diff --git a/.gitignore b/.gitignore
index 8d22b28bd84a1f75af031867b14a77210f5123c1..f819e4bc74fffc0f2e6dc67fb03958a9452e745f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,4 +16,5 @@ build
 _autosave*
 .DS_Store
 a.out
+bin
 
diff --git a/reform2-lpc-fw/.cproject b/reform2-lpc-fw/.cproject
new file mode 100644
index 0000000000000000000000000000000000000000..dfcf13cbd03dce7c10efefdc73be706156782ef2
--- /dev/null
+++ b/reform2-lpc-fw/.cproject
@@ -0,0 +1,992 @@
+<?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="com.crt.advproject.config.exe.debug.31686071.1683240460">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.crt.advproject.config.exe.debug.31686071.1683240460" moduleId="org.eclipse.cdt.core.settings" name="RF1GHZNODE">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" 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.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactExtension="axf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="LPC11U37/401" errorParsers="org.eclipse.cdt.core.MakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GASErrorParser" id="com.crt.advproject.config.exe.debug.31686071.1683240460" name="RF1GHZNODE" parent="com.crt.advproject.config.exe.debug" postannouncebuildStep="Performing post-build steps" postbuildStep="arm-none-eabi-size &quot;${BuildArtifactFileName}&quot;; #arm-none-eabi-objcopy -O binary &quot;${BuildArtifactFileName}&quot; &quot;${BuildArtifactFileBaseName}.bin&quot; ; checksum -p ${TargetChip} -d &quot;${BuildArtifactFileBaseName}.bin&quot;;  ">
+					<folderInfo id="com.crt.advproject.config.exe.debug.31686071.1683240460." name="/" resourcePath="">
+						<toolChain id="com.crt.advproject.toolchain.exe.debug.1364124233" name="Code Red MCU Tools" superClass="com.crt.advproject.toolchain.exe.debug">
+							<targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF" id="com.crt.advproject.platform.exe.debug.179539220" name="ARM-based MCU (Debug)" superClass="com.crt.advproject.platform.exe.debug"/>
+							<builder buildPath="${workspace_loc:/LPC11U_LPC13U_Codebase/Debug}" id="com.crt.advproject.builder.exe.debug.1291331417" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="com.crt.advproject.builder.exe.debug"/>
+							<tool id="com.crt.advproject.cpp.exe.debug.52510877" name="MCU C++ Compiler" superClass="com.crt.advproject.cpp.exe.debug"/>
+							<tool id="com.crt.advproject.gcc.exe.debug.844765466" name="MCU C Compiler" superClass="com.crt.advproject.gcc.exe.debug">
+								<option id="com.crt.advproject.gcc.arch.1316843127" name="Architecture" superClass="com.crt.advproject.gcc.arch" value="com.crt.advproject.gcc.target.cm3" valueType="enumerated"/>
+								<option id="com.crt.advproject.gcc.thumb.1359528183" name="Thumb mode" superClass="com.crt.advproject.gcc.thumb" value="true" valueType="boolean"/>
+								<option id="gnu.c.compiler.option.preprocessor.def.symbols.818295962" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="__REDLIB__"/>
+									<listOptionValue builtIn="false" value="ARM_MATH_CM0"/>
+									<listOptionValue builtIn="false" value="CFG_BRD_RF1GHZNODE"/>
+									<listOptionValue builtIn="false" value="DEBUG"/>
+									<listOptionValue builtIn="false" value="__CODE_RED"/>
+									<listOptionValue builtIn="false" value="__USE_CMSIS=CMSISv2p00_LPC11Uxx"/>
+								</option>
+								<option id="gnu.c.compiler.option.misc.other.220640580" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections" valueType="string"/>
+								<option id="com.crt.advproject.gcc.hdrlib.701733772" name="Use headers for C library" superClass="com.crt.advproject.gcc.hdrlib" value="com.crt.advproject.gcc.hdrlib.codered" valueType="enumerated"/>
+								<option id="gnu.c.compiler.option.include.paths.1158021021" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/cmsis}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/cli}&quot;"/>
+								</option>
+								<option id="com.crt.advproject.c.misc.dialect.607931325" name="C Dialect" superClass="com.crt.advproject.c.misc.dialect" value="com.crt.advproject.misc.dialect.gnu99" valueType="enumerated"/>
+								<option id="gnu.c.compiler.option.warnings.pedantic.1694593321" name="Pedantic (-pedantic)" superClass="gnu.c.compiler.option.warnings.pedantic" value="false" valueType="boolean"/>
+								<inputType id="com.crt.advproject.compiler.input.1531632236" superClass="com.crt.advproject.compiler.input"/>
+							</tool>
+							<tool id="com.crt.advproject.gas.exe.debug.1374717928" name="MCU Assembler" superClass="com.crt.advproject.gas.exe.debug">
+								<option id="com.crt.advproject.gas.arch.1482050908" name="Architecture" superClass="com.crt.advproject.gas.arch" value="com.crt.advproject.gas.target.cm3" valueType="enumerated"/>
+								<option id="com.crt.advproject.gas.thumb.1985823242" name="Thumb mode" superClass="com.crt.advproject.gas.thumb" value="true" valueType="boolean"/>
+								<option id="gnu.both.asm.option.flags.crt.907328865" name="Assembler flags" superClass="gnu.both.asm.option.flags.crt" value="-c -x assembler-with-cpp -D__REDLIB__ -DDEBUG -D__CODE_RED" valueType="string"/>
+								<option id="com.crt.advproject.gas.hdrlib.1232253139" name="Use headers for C library" superClass="com.crt.advproject.gas.hdrlib" value="com.crt.advproject.gas.hdrlib.codered" valueType="enumerated"/>
+								<inputType id="com.crt.advproject.assembler.input.492793352" name="Additional Assembly Source Files" superClass="com.crt.advproject.assembler.input"/>
+								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1506086469" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+							</tool>
+							<tool id="com.crt.advproject.link.cpp.exe.debug.1548250628" name="MCU C++ Linker" superClass="com.crt.advproject.link.cpp.exe.debug"/>
+							<tool id="com.crt.advproject.link.exe.debug.1302209906" name="MCU Linker" superClass="com.crt.advproject.link.exe.debug">
+								<option id="com.crt.advproject.link.arch.1272124390" name="Architecture" superClass="com.crt.advproject.link.arch" value="com.crt.advproject.link.target.cm3" valueType="enumerated"/>
+								<option id="com.crt.advproject.link.thumb.1054411598" name="Thumb mode" superClass="com.crt.advproject.link.thumb" value="true" valueType="boolean"/>
+								<option id="com.crt.advproject.link.script.1417406066" name="Linker script" superClass="com.crt.advproject.link.script" value="&quot;LPC11U_LPC13U_CodeBase_RF1GHZNODE.ld&quot;" valueType="string"/>
+								<option id="com.crt.advproject.link.manage.186448314" name="Manage linker script" superClass="com.crt.advproject.link.manage" value="true" valueType="boolean"/>
+								<option id="gnu.c.link.option.nostdlibs.2044725838" name="No startup or default libs (-nostdlib)" superClass="gnu.c.link.option.nostdlibs" value="true" valueType="boolean"/>
+								<option id="gnu.c.link.option.other.1470988433" name="Other options (-Xlinker [option])" superClass="gnu.c.link.option.other" valueType="stringList">
+									<listOptionValue builtIn="false" value="-Map=&quot;${BuildArtifactFileBaseName}.map&quot;"/>
+									<listOptionValue builtIn="false" value="--allow-multiple-definition"/>
+									<listOptionValue builtIn="false" value="--gc-sections"/>
+								</option>
+								<option id="com.crt.advproject.link.gcc.hdrlib.874162722" name="Use C library" superClass="com.crt.advproject.link.gcc.hdrlib" value="com.crt.advproject.gcc.link.hdrlib.codered.semihost" valueType="enumerated"/>
+								<option id="gnu.c.link.option.libs.918751438" name="Libraries (-l)" superClass="gnu.c.link.option.libs" valueType="libs">
+									<listOptionValue builtIn="false" value="arm_cortexM0l_math"/>
+									<listOptionValue builtIn="false" value="RTX_CM0"/>
+								</option>
+								<option id="gnu.c.link.option.paths.1326749668" name="Library search path (-L)" superClass="gnu.c.link.option.paths" valueType="libPaths">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/cmsis/libs}&quot;"/>
+								</option>
+								<option id="com.crt.advproject.link.gcc.multicore.slave.611061657" name="Multicore slave" superClass="com.crt.advproject.link.gcc.multicore.slave"/>
+								<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.2105041727" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+						</toolChain>
+					</folderInfo>
+					<fileInfo id="com.crt.advproject.config.exe.debug.31686071.1683240460.src/cr_startup_lpc13u.cpp" name="cr_startup_lpc13u.cpp" rcbsApplicability="disable" resourcePath="src/cr_startup_lpc13u.cpp" toolsToInvoke=""/>
+					<sourceEntries>
+						<entry excluding="startup_LPC13Uxx_keil.s|startup_lpc13u_gnumake.c|startup_lpc11u_gnumake.c|startup_LPC11Uxx_keil.s|system_LPC13Uxx.c|startup_LPC13Uxx_arm.s|startup_lpc13u.c|startup_LPC11Uxx_arm.s|startup_lpc11u.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="cmsis"/>
+						<entry excluding="drivers/rf/bluetooth|drivers/displays/graphic/hw/hx8347g.h|drivers/displays/graphic/hw/hx8347g.c|core/usb/usb_cdc_old.c|core/usb/hid_desc.c|core/usb_cdc.c|drivers/displays/graphic/aafonts/aa2/source|drivers/displays/graphic/aafonts/aa4/source|drivers/storage/fatfs/ccsbcs.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+			<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
+			<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+		</cconfiguration>
+		<cconfiguration id="com.crt.advproject.config.exe.debug.31686071.2088192637">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.crt.advproject.config.exe.debug.31686071.2088192637" moduleId="org.eclipse.cdt.core.settings" name="RF1GHZUSB">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" 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.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactExtension="axf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="LPC1347" errorParsers="org.eclipse.cdt.core.MakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GASErrorParser" id="com.crt.advproject.config.exe.debug.31686071.2088192637" name="RF1GHZUSB" parent="com.crt.advproject.config.exe.debug" postannouncebuildStep="Performing post-build steps" postbuildStep="arm-none-eabi-size &quot;${BuildArtifactFileName}&quot;; #arm-none-eabi-objcopy -O binary &quot;${BuildArtifactFileName}&quot; &quot;${BuildArtifactFileBaseName}.bin&quot; ; checksum -p ${TargetChip} -d &quot;${BuildArtifactFileBaseName}.bin&quot;;  ">
+					<folderInfo id="com.crt.advproject.config.exe.debug.31686071.2088192637." name="/" resourcePath="">
+						<toolChain id="com.crt.advproject.toolchain.exe.debug.634369899" name="Code Red MCU Tools" superClass="com.crt.advproject.toolchain.exe.debug">
+							<targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF" id="com.crt.advproject.platform.exe.debug.2122482194" name="ARM-based MCU (Debug)" superClass="com.crt.advproject.platform.exe.debug"/>
+							<builder buildPath="${workspace_loc:/LPC11U_LPC13U_Codebase/Debug}" id="com.crt.advproject.builder.exe.debug.2110732932" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="com.crt.advproject.builder.exe.debug"/>
+							<tool id="com.crt.advproject.cpp.exe.debug.105505002" name="MCU C++ Compiler" superClass="com.crt.advproject.cpp.exe.debug"/>
+							<tool id="com.crt.advproject.gcc.exe.debug.1302164407" name="MCU C Compiler" superClass="com.crt.advproject.gcc.exe.debug">
+								<option id="com.crt.advproject.gcc.arch.1346480943" name="Architecture" superClass="com.crt.advproject.gcc.arch" value="com.crt.advproject.gcc.target.cm3" valueType="enumerated"/>
+								<option id="com.crt.advproject.gcc.thumb.1220273852" name="Thumb mode" superClass="com.crt.advproject.gcc.thumb" value="true" valueType="boolean"/>
+								<option id="gnu.c.compiler.option.preprocessor.def.symbols.386713938" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="__REDLIB__"/>
+									<listOptionValue builtIn="false" value="ARM_MATH_CM3"/>
+									<listOptionValue builtIn="false" value="CFG_BRD_RF1GHZUSB"/>
+									<listOptionValue builtIn="false" value="DEBUG"/>
+									<listOptionValue builtIn="false" value="__CODE_RED"/>
+									<listOptionValue builtIn="false" value="__USE_CMSIS=CMSISv2p10_LPC13Uxx"/>
+								</option>
+								<option id="gnu.c.compiler.option.misc.other.1929918352" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections" valueType="string"/>
+								<option id="com.crt.advproject.gcc.hdrlib.1563562537" name="Use headers for C library" superClass="com.crt.advproject.gcc.hdrlib" value="com.crt.advproject.gcc.hdrlib.codered" valueType="enumerated"/>
+								<option id="gnu.c.compiler.option.include.paths.923082958" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/cmsis}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/cli}&quot;"/>
+								</option>
+								<option id="com.crt.advproject.c.misc.dialect.1058054445" name="C Dialect" superClass="com.crt.advproject.c.misc.dialect" value="com.crt.advproject.misc.dialect.gnu99" valueType="enumerated"/>
+								<option id="gnu.c.compiler.option.warnings.pedantic.746780479" name="Pedantic (-pedantic)" superClass="gnu.c.compiler.option.warnings.pedantic" value="false" valueType="boolean"/>
+								<inputType id="com.crt.advproject.compiler.input.692695703" superClass="com.crt.advproject.compiler.input"/>
+							</tool>
+							<tool id="com.crt.advproject.gas.exe.debug.94778119" name="MCU Assembler" superClass="com.crt.advproject.gas.exe.debug">
+								<option id="com.crt.advproject.gas.arch.218501735" name="Architecture" superClass="com.crt.advproject.gas.arch" value="com.crt.advproject.gas.target.cm3" valueType="enumerated"/>
+								<option id="com.crt.advproject.gas.thumb.1784611683" name="Thumb mode" superClass="com.crt.advproject.gas.thumb" value="true" valueType="boolean"/>
+								<option id="gnu.both.asm.option.flags.crt.2029696743" name="Assembler flags" superClass="gnu.both.asm.option.flags.crt" value="-c -x assembler-with-cpp -D__REDLIB__ -DDEBUG -D__CODE_RED" valueType="string"/>
+								<option id="com.crt.advproject.gas.hdrlib.97812233" name="Use headers for C library" superClass="com.crt.advproject.gas.hdrlib" value="com.crt.advproject.gas.hdrlib.codered" valueType="enumerated"/>
+								<inputType id="com.crt.advproject.assembler.input.1772704232" name="Additional Assembly Source Files" superClass="com.crt.advproject.assembler.input"/>
+								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1113863701" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+							</tool>
+							<tool id="com.crt.advproject.link.cpp.exe.debug.1694735683" name="MCU C++ Linker" superClass="com.crt.advproject.link.cpp.exe.debug"/>
+							<tool id="com.crt.advproject.link.exe.debug.317357732" name="MCU Linker" superClass="com.crt.advproject.link.exe.debug">
+								<option id="com.crt.advproject.link.arch.1701703795" name="Architecture" superClass="com.crt.advproject.link.arch" value="com.crt.advproject.link.target.cm3" valueType="enumerated"/>
+								<option id="com.crt.advproject.link.thumb.1262333094" name="Thumb mode" superClass="com.crt.advproject.link.thumb" value="true" valueType="boolean"/>
+								<option id="com.crt.advproject.link.script.1180633184" name="Linker script" superClass="com.crt.advproject.link.script" value="&quot;LPC11U_LPC13U_CodeBase_RF1GHZUSB.ld&quot;" valueType="string"/>
+								<option id="com.crt.advproject.link.manage.2042373910" name="Manage linker script" superClass="com.crt.advproject.link.manage" value="true" valueType="boolean"/>
+								<option id="gnu.c.link.option.nostdlibs.1445136205" name="No startup or default libs (-nostdlib)" superClass="gnu.c.link.option.nostdlibs" value="true" valueType="boolean"/>
+								<option id="gnu.c.link.option.other.756967378" name="Other options (-Xlinker [option])" superClass="gnu.c.link.option.other" valueType="stringList">
+									<listOptionValue builtIn="false" value="-Map=&quot;${BuildArtifactFileBaseName}.map&quot;"/>
+									<listOptionValue builtIn="false" value="--allow-multiple-definition"/>
+									<listOptionValue builtIn="false" value="--gc-sections"/>
+								</option>
+								<option id="com.crt.advproject.link.gcc.hdrlib.1660270697" name="Use C library" superClass="com.crt.advproject.link.gcc.hdrlib" value="com.crt.advproject.gcc.link.hdrlib.codered.semihost" valueType="enumerated"/>
+								<option id="gnu.c.link.option.libs.1263477426" name="Libraries (-l)" superClass="gnu.c.link.option.libs" valueType="libs">
+									<listOptionValue builtIn="false" value="arm_cortexM3l_math"/>
+									<listOptionValue builtIn="false" value="RTX_CM3"/>
+								</option>
+								<option id="gnu.c.link.option.paths.1276160123" name="Library search path (-L)" superClass="gnu.c.link.option.paths" valueType="libPaths">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/cmsis/libs}&quot;"/>
+								</option>
+								<option id="com.crt.advproject.link.gcc.multicore.slave.892745171" name="Multicore slave" superClass="com.crt.advproject.link.gcc.multicore.slave"/>
+								<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.181391152" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+						</toolChain>
+					</folderInfo>
+					<fileInfo id="com.crt.advproject.config.exe.debug.31686071.2088192637.src/cr_startup_lpc13u.cpp" name="cr_startup_lpc13u.cpp" rcbsApplicability="disable" resourcePath="src/cr_startup_lpc13u.cpp" toolsToInvoke=""/>
+					<sourceEntries>
+						<entry excluding="startup_LPC13Uxx_keil.s|startup_lpc13u_gnumake.c|startup_lpc11u_gnumake.c|startup_LPC11Uxx_keil.s|system_LPC11Uxx.c|startup_LPC13Uxx_arm.s|startup_lpc13u.c|startup_LPC11Uxx_arm.s|startup_lpc11u.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="cmsis"/>
+						<entry excluding="drivers/rf/bluetooth|drivers/displays/graphic/hw/hx8347g.h|drivers/displays/graphic/hw/hx8347g.c|core/usb/usb_cdc_old.c|core/usb/hid_desc.c|core/usb_cdc.c|drivers/displays/graphic/aafonts/aa2/source|drivers/displays/graphic/aafonts/aa4/source|drivers/storage/fatfs/ccsbcs.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+			<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
+			<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+		</cconfiguration>
+		<cconfiguration id="com.crt.advproject.config.exe.debug.31686071.2088192637.845617240">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.crt.advproject.config.exe.debug.31686071.2088192637.845617240" moduleId="org.eclipse.cdt.core.settings" name="LPCNFC">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" 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.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactExtension="axf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="LPC1347" errorParsers="org.eclipse.cdt.core.MakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GASErrorParser" id="com.crt.advproject.config.exe.debug.31686071.2088192637.845617240" name="LPCNFC" parent="com.crt.advproject.config.exe.debug" postannouncebuildStep="Performing post-build steps" postbuildStep="arm-none-eabi-size &quot;${BuildArtifactFileName}&quot;; #arm-none-eabi-objcopy -O binary &quot;${BuildArtifactFileName}&quot; &quot;${BuildArtifactFileBaseName}.bin&quot; ; checksum -p ${TargetChip} -d &quot;${BuildArtifactFileBaseName}.bin&quot;;  ">
+					<folderInfo id="com.crt.advproject.config.exe.debug.31686071.2088192637.845617240." name="/" resourcePath="">
+						<toolChain id="com.crt.advproject.toolchain.exe.debug.1818742214" name="Code Red MCU Tools" superClass="com.crt.advproject.toolchain.exe.debug">
+							<targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF" id="com.crt.advproject.platform.exe.debug.75049207" name="ARM-based MCU (Debug)" superClass="com.crt.advproject.platform.exe.debug"/>
+							<builder buildPath="${workspace_loc:/LPC11U_LPC13U_Codebase/Debug}" id="com.crt.advproject.builder.exe.debug.1115889589" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="com.crt.advproject.builder.exe.debug"/>
+							<tool id="com.crt.advproject.cpp.exe.debug.1828594266" name="MCU C++ Compiler" superClass="com.crt.advproject.cpp.exe.debug"/>
+							<tool id="com.crt.advproject.gcc.exe.debug.1664140350" name="MCU C Compiler" superClass="com.crt.advproject.gcc.exe.debug">
+								<option id="com.crt.advproject.gcc.arch.1425469769" name="Architecture" superClass="com.crt.advproject.gcc.arch" value="com.crt.advproject.gcc.target.cm3" valueType="enumerated"/>
+								<option id="com.crt.advproject.gcc.thumb.215892761" name="Thumb mode" superClass="com.crt.advproject.gcc.thumb" value="true" valueType="boolean"/>
+								<option id="gnu.c.compiler.option.preprocessor.def.symbols.326788874" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="ARM_MATH_CM3"/>
+									<listOptionValue builtIn="false" value="__REDLIB__"/>
+									<listOptionValue builtIn="false" value="CFG_BRD_LPCNFC"/>
+									<listOptionValue builtIn="false" value="DEBUG"/>
+									<listOptionValue builtIn="false" value="__CODE_RED"/>
+									<listOptionValue builtIn="false" value="__USE_CMSIS=CMSISv2p10_LPC13Uxx"/>
+								</option>
+								<option id="gnu.c.compiler.option.misc.other.1282586810" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections" valueType="string"/>
+								<option id="com.crt.advproject.gcc.hdrlib.1408953164" name="Use headers for C library" superClass="com.crt.advproject.gcc.hdrlib" value="com.crt.advproject.gcc.hdrlib.codered" valueType="enumerated"/>
+								<option id="gnu.c.compiler.option.include.paths.402508251" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/cmsis}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/cli}&quot;"/>
+								</option>
+								<option id="com.crt.advproject.c.misc.dialect.290746254" name="C Dialect" superClass="com.crt.advproject.c.misc.dialect" value="com.crt.advproject.misc.dialect.gnu99" valueType="enumerated"/>
+								<option id="gnu.c.compiler.option.warnings.pedantic.2132838304" name="Pedantic (-pedantic)" superClass="gnu.c.compiler.option.warnings.pedantic" value="false" valueType="boolean"/>
+								<inputType id="com.crt.advproject.compiler.input.1773770746" superClass="com.crt.advproject.compiler.input"/>
+							</tool>
+							<tool id="com.crt.advproject.gas.exe.debug.708873596" name="MCU Assembler" superClass="com.crt.advproject.gas.exe.debug">
+								<option id="com.crt.advproject.gas.arch.225247010" name="Architecture" superClass="com.crt.advproject.gas.arch" value="com.crt.advproject.gas.target.cm3" valueType="enumerated"/>
+								<option id="com.crt.advproject.gas.thumb.1230846548" name="Thumb mode" superClass="com.crt.advproject.gas.thumb" value="true" valueType="boolean"/>
+								<option id="gnu.both.asm.option.flags.crt.891976528" name="Assembler flags" superClass="gnu.both.asm.option.flags.crt" value="-c -x assembler-with-cpp -D__REDLIB__ -DDEBUG -D__CODE_RED" valueType="string"/>
+								<option id="com.crt.advproject.gas.hdrlib.1432831573" name="Use headers for C library" superClass="com.crt.advproject.gas.hdrlib" value="com.crt.advproject.gas.hdrlib.codered" valueType="enumerated"/>
+								<inputType id="com.crt.advproject.assembler.input.955588643" name="Additional Assembly Source Files" superClass="com.crt.advproject.assembler.input"/>
+								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.723398240" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+							</tool>
+							<tool id="com.crt.advproject.link.cpp.exe.debug.702015378" name="MCU C++ Linker" superClass="com.crt.advproject.link.cpp.exe.debug"/>
+							<tool id="com.crt.advproject.link.exe.debug.2134350270" name="MCU Linker" superClass="com.crt.advproject.link.exe.debug">
+								<option id="com.crt.advproject.link.arch.1763764748" name="Architecture" superClass="com.crt.advproject.link.arch" value="com.crt.advproject.link.target.cm3" valueType="enumerated"/>
+								<option id="com.crt.advproject.link.thumb.1168822572" name="Thumb mode" superClass="com.crt.advproject.link.thumb" value="true" valueType="boolean"/>
+								<option id="com.crt.advproject.link.script.611100937" name="Linker script" superClass="com.crt.advproject.link.script" value="&quot;LPC11U_LPC13U_CodeBase_board_rf1ghzusb.ld&quot;" valueType="string"/>
+								<option id="com.crt.advproject.link.manage.804744011" name="Manage linker script" superClass="com.crt.advproject.link.manage" value="true" valueType="boolean"/>
+								<option id="gnu.c.link.option.nostdlibs.1892955685" name="No startup or default libs (-nostdlib)" superClass="gnu.c.link.option.nostdlibs" value="true" valueType="boolean"/>
+								<option id="gnu.c.link.option.other.1197887103" name="Other options (-Xlinker [option])" superClass="gnu.c.link.option.other" valueType="stringList">
+									<listOptionValue builtIn="false" value="-Map=&quot;${BuildArtifactFileBaseName}.map&quot;"/>
+									<listOptionValue builtIn="false" value="--allow-multiple-definition"/>
+									<listOptionValue builtIn="false" value="--gc-sections"/>
+								</option>
+								<option id="com.crt.advproject.link.gcc.hdrlib.1875188381" name="Use C library" superClass="com.crt.advproject.link.gcc.hdrlib" value="com.crt.advproject.gcc.link.hdrlib.codered.semihost" valueType="enumerated"/>
+								<option id="gnu.c.link.option.libs.465270395" name="Libraries (-l)" superClass="gnu.c.link.option.libs" valueType="libs">
+									<listOptionValue builtIn="false" value="arm_cortexM3l_math"/>
+									<listOptionValue builtIn="false" value="RTX_CM3"/>
+								</option>
+								<option id="gnu.c.link.option.paths.1747535721" name="Library search path (-L)" superClass="gnu.c.link.option.paths" valueType="libPaths">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/cmsis/libs}&quot;"/>
+								</option>
+								<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1707214524" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+						</toolChain>
+					</folderInfo>
+					<fileInfo id="com.crt.advproject.config.exe.debug.31686071.2088192637.845617240.src/cr_startup_lpc13u.cpp" name="cr_startup_lpc13u.cpp" rcbsApplicability="disable" resourcePath="src/cr_startup_lpc13u.cpp" toolsToInvoke=""/>
+					<sourceEntries>
+						<entry excluding="startup_LPC13Uxx_keil.s|startup_lpc13u_gnumake.c|startup_lpc11u_gnumake.c|startup_LPC11Uxx_keil.s|system_LPC11Uxx.c|startup_LPC13Uxx_arm.s|startup_lpc13u.c|startup_LPC11Uxx_arm.s|startup_lpc11u.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="cmsis"/>
+						<entry excluding="drivers/rf/bluetooth|drivers/displays/graphic/hw/hx8347g.h|drivers/displays/graphic/hw/hx8347g.c|core/usb/usb_cdc_old.c|core/usb/hid_desc.c|core/usb_cdc.c|drivers/displays/graphic/aafonts/aa2/source|drivers/displays/graphic/aafonts/aa4/source|drivers/storage/fatfs/ccsbcs.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+			<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
+			<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+		</cconfiguration>
+		<cconfiguration id="com.crt.advproject.config.exe.debug.31686071.2088192637.925022945">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.crt.advproject.config.exe.debug.31686071.2088192637.925022945" moduleId="org.eclipse.cdt.core.settings" name="LPCXpresso LPC1347">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" 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.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactExtension="axf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="LPC1347" errorParsers="org.eclipse.cdt.core.MakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GmakeErrorParser" id="com.crt.advproject.config.exe.debug.31686071.2088192637.925022945" name="LPCXpresso LPC1347" parent="com.crt.advproject.config.exe.debug" postannouncebuildStep="Performing post-build steps" postbuildStep="arm-none-eabi-size &quot;${BuildArtifactFileName}&quot;; #arm-none-eabi-objcopy -O binary &quot;${BuildArtifactFileName}&quot; &quot;${BuildArtifactFileBaseName}.bin&quot; ; checksum -p ${TargetChip} -d &quot;${BuildArtifactFileBaseName}.bin&quot;;  " preannouncebuildStep="" prebuildStep="">
+					<folderInfo id="com.crt.advproject.config.exe.debug.31686071.2088192637.925022945." name="/" resourcePath="">
+						<toolChain errorParsers="" id="com.crt.advproject.toolchain.exe.debug.989001085" name="Code Red MCU Tools" superClass="com.crt.advproject.toolchain.exe.debug">
+							<targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF" id="com.crt.advproject.platform.exe.debug.1528108941" name="ARM-based MCU (Debug)" superClass="com.crt.advproject.platform.exe.debug"/>
+							<builder buildPath="${workspace_loc:/LPC11U_LPC13U_Codebase/Debug}" errorParsers="org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.CWDLocator" id="com.crt.advproject.builder.exe.debug.1323571416" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="com.crt.advproject.builder.exe.debug"/>
+							<tool id="com.crt.advproject.cpp.exe.debug.24520083" name="MCU C++ Compiler" superClass="com.crt.advproject.cpp.exe.debug"/>
+							<tool command="arm-none-eabi-gcc" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG}${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" errorParsers="org.eclipse.cdt.core.GCCErrorParser" id="com.crt.advproject.gcc.exe.debug.858718438" name="MCU C Compiler" superClass="com.crt.advproject.gcc.exe.debug">
+								<option id="com.crt.advproject.gcc.arch.817872319" name="Architecture" superClass="com.crt.advproject.gcc.arch" value="com.crt.advproject.gcc.target.cm3" valueType="enumerated"/>
+								<option id="com.crt.advproject.gcc.thumb.348923478" name="Thumb mode" superClass="com.crt.advproject.gcc.thumb" value="true" valueType="boolean"/>
+								<option id="gnu.c.compiler.option.preprocessor.def.symbols.1784005350" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="__REDLIB__"/>
+									<listOptionValue builtIn="false" value="ARM_MATH_CM3"/>
+									<listOptionValue builtIn="false" value="CFG_BRD_LPCXPRESSO_LPC1347"/>
+									<listOptionValue builtIn="false" value="DEBUG"/>
+									<listOptionValue builtIn="false" value="__CODE_RED"/>
+									<listOptionValue builtIn="false" value="__USE_CMSIS=CMSISv2p10_LPC13Uxx"/>
+								</option>
+								<option id="gnu.c.compiler.option.misc.other.244627948" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections" valueType="string"/>
+								<option id="com.crt.advproject.gcc.hdrlib.1843567114" name="Use headers for C library" superClass="com.crt.advproject.gcc.hdrlib" value="com.crt.advproject.gcc.hdrlib.codered" valueType="enumerated"/>
+								<option id="gnu.c.compiler.option.include.paths.1896358864" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/cmsis}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/cli}&quot;"/>
+								</option>
+								<option id="com.crt.advproject.c.misc.dialect.59094747" name="C Dialect" superClass="com.crt.advproject.c.misc.dialect" value="com.crt.advproject.misc.dialect.gnu99" valueType="enumerated"/>
+								<option id="gnu.c.compiler.option.warnings.pedantic.390923332" name="Pedantic (-pedantic)" superClass="gnu.c.compiler.option.warnings.pedantic" value="false" valueType="boolean"/>
+								<inputType id="com.crt.advproject.compiler.input.908086299" superClass="com.crt.advproject.compiler.input"/>
+							</tool>
+							<tool command="arm-none-eabi-gcc" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG}${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" errorParsers="org.eclipse.cdt.core.GASErrorParser" id="com.crt.advproject.gas.exe.debug.999735181" name="MCU Assembler" superClass="com.crt.advproject.gas.exe.debug">
+								<option id="com.crt.advproject.gas.arch.456291473" name="Architecture" superClass="com.crt.advproject.gas.arch" value="com.crt.advproject.gas.target.cm3" valueType="enumerated"/>
+								<option id="com.crt.advproject.gas.thumb.528382375" name="Thumb mode" superClass="com.crt.advproject.gas.thumb" value="true" valueType="boolean"/>
+								<option id="gnu.both.asm.option.flags.crt.2135136227" name="Assembler flags" superClass="gnu.both.asm.option.flags.crt" value="-c -x assembler-with-cpp -D__REDLIB__ -DDEBUG -D__CODE_RED" valueType="string"/>
+								<option id="com.crt.advproject.gas.hdrlib.1307819853" name="Use headers for C library" superClass="com.crt.advproject.gas.hdrlib" value="com.crt.advproject.gas.hdrlib.codered" valueType="enumerated"/>
+								<inputType id="com.crt.advproject.assembler.input.161749592" name="Additional Assembly Source Files" superClass="com.crt.advproject.assembler.input"/>
+								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.411573238" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+							</tool>
+							<tool id="com.crt.advproject.link.cpp.exe.debug.1115067052" name="MCU C++ Linker" superClass="com.crt.advproject.link.cpp.exe.debug"/>
+							<tool command="arm-none-eabi-gcc" commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG}${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" errorParsers="org.eclipse.cdt.core.GLDErrorParser" id="com.crt.advproject.link.exe.debug.1218922656" name="MCU Linker" superClass="com.crt.advproject.link.exe.debug">
+								<option id="com.crt.advproject.link.arch.403194258" name="Architecture" superClass="com.crt.advproject.link.arch" value="com.crt.advproject.link.target.cm3" valueType="enumerated"/>
+								<option id="com.crt.advproject.link.thumb.1077052836" name="Thumb mode" superClass="com.crt.advproject.link.thumb" value="true" valueType="boolean"/>
+								<option id="com.crt.advproject.link.script.1098515890" name="Linker script" superClass="com.crt.advproject.link.script" value="&quot;LPC11U_LPC13U_CodeBase_LPCXpresso_LPC1347.ld&quot;" valueType="string"/>
+								<option id="com.crt.advproject.link.manage.2111218160" name="Manage linker script" superClass="com.crt.advproject.link.manage" value="true" valueType="boolean"/>
+								<option id="gnu.c.link.option.nostdlibs.460492021" name="No startup or default libs (-nostdlib)" superClass="gnu.c.link.option.nostdlibs" value="true" valueType="boolean"/>
+								<option id="gnu.c.link.option.other.790182996" name="Other options (-Xlinker [option])" superClass="gnu.c.link.option.other" valueType="stringList">
+									<listOptionValue builtIn="false" value="-Map=&quot;${BuildArtifactFileBaseName}.map&quot;"/>
+									<listOptionValue builtIn="false" value="--allow-multiple-definition"/>
+									<listOptionValue builtIn="false" value="--gc-sections"/>
+								</option>
+								<option id="com.crt.advproject.link.gcc.hdrlib.2128421580" name="Use C library" superClass="com.crt.advproject.link.gcc.hdrlib" value="com.crt.advproject.gcc.link.hdrlib.codered.semihost" valueType="enumerated"/>
+								<option id="gnu.c.link.option.libs.1160871876" name="Libraries (-l)" superClass="gnu.c.link.option.libs" valueType="libs">
+									<listOptionValue builtIn="false" value="arm_cortexM3l_math"/>
+									<listOptionValue builtIn="false" value="RTX_CM3"/>
+								</option>
+								<option id="gnu.c.link.option.paths.1129666474" name="Library search path (-L)" superClass="gnu.c.link.option.paths" valueType="libPaths">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/cmsis/libs}&quot;"/>
+								</option>
+								<option id="com.crt.advproject.link.gcc.multicore.slave.1388193091" name="Multicore slave" superClass="com.crt.advproject.link.gcc.multicore.slave"/>
+								<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1401162176" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+						</toolChain>
+					</folderInfo>
+					<fileInfo id="com.crt.advproject.config.exe.debug.31686071.2088192637.925022945.src/cr_startup_lpc13u.cpp" name="cr_startup_lpc13u.cpp" rcbsApplicability="disable" resourcePath="src/cr_startup_lpc13u.cpp" toolsToInvoke=""/>
+					<sourceEntries>
+						<entry excluding="drivers/rf/bluetooth|drivers/displays/graphic/hw/hx8347g.h|drivers/displays/graphic/hw/hx8347g.c|core/usb/usb_cdc_old.c|core/usb/hid_desc.c|core/usb_cdc.c|drivers/displays/graphic/aafonts/aa2/source|drivers/displays/graphic/aafonts/aa4/source|drivers/storage/fatfs/ccsbcs.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+						<entry excluding="startup_LPC13Uxx_keil.s|startup_lpc13u_gnumake.c|startup_lpc11u_gnumake.c|startup_LPC11Uxx_keil.s|system_LPC11Uxx.c|startup_LPC13Uxx_arm.s|startup_lpc13u.c|startup_LPC11Uxx_arm.s|startup_lpc11u.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="cmsis"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+			<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
+			<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+		</cconfiguration>
+		<cconfiguration id="com.crt.advproject.config.exe.debug.31686071.2088192637.845617240.860621000">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.crt.advproject.config.exe.debug.31686071.2088192637.845617240.860621000" moduleId="org.eclipse.cdt.core.settings" name="LPCSTEPPER">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" 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.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactExtension="axf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="LPC1347" errorParsers="org.eclipse.cdt.core.MakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GASErrorParser" id="com.crt.advproject.config.exe.debug.31686071.2088192637.845617240.860621000" name="LPCSTEPPER" parent="com.crt.advproject.config.exe.debug" postannouncebuildStep="Performing post-build steps" postbuildStep="arm-none-eabi-size &quot;${BuildArtifactFileName}&quot;; #arm-none-eabi-objcopy -O binary &quot;${BuildArtifactFileName}&quot; &quot;${BuildArtifactFileBaseName}.bin&quot; ; checksum -p ${TargetChip} -d &quot;${BuildArtifactFileBaseName}.bin&quot;;  ">
+					<folderInfo id="com.crt.advproject.config.exe.debug.31686071.2088192637.845617240.860621000." name="/" resourcePath="">
+						<toolChain id="com.crt.advproject.toolchain.exe.debug.31841940" name="Code Red MCU Tools" superClass="com.crt.advproject.toolchain.exe.debug">
+							<targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF" id="com.crt.advproject.platform.exe.debug.651536745" name="ARM-based MCU (Debug)" superClass="com.crt.advproject.platform.exe.debug"/>
+							<builder buildPath="${workspace_loc:/LPC11U_LPC13U_Codebase/Debug}" id="com.crt.advproject.builder.exe.debug.451544333" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="com.crt.advproject.builder.exe.debug"/>
+							<tool id="com.crt.advproject.cpp.exe.debug.1161685546" name="MCU C++ Compiler" superClass="com.crt.advproject.cpp.exe.debug"/>
+							<tool id="com.crt.advproject.gcc.exe.debug.115506131" name="MCU C Compiler" superClass="com.crt.advproject.gcc.exe.debug">
+								<option id="com.crt.advproject.gcc.arch.349251133" name="Architecture" superClass="com.crt.advproject.gcc.arch" value="com.crt.advproject.gcc.target.cm3" valueType="enumerated"/>
+								<option id="com.crt.advproject.gcc.thumb.1921463726" name="Thumb mode" superClass="com.crt.advproject.gcc.thumb" value="true" valueType="boolean"/>
+								<option id="gnu.c.compiler.option.preprocessor.def.symbols.1438815367" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="__REDLIB__"/>
+									<listOptionValue builtIn="false" value="ARM_MATH_CM3"/>
+									<listOptionValue builtIn="false" value="CFG_BRD_LPCSTEPPER"/>
+									<listOptionValue builtIn="false" value="DEBUG"/>
+									<listOptionValue builtIn="false" value="__CODE_RED"/>
+									<listOptionValue builtIn="false" value="__USE_CMSIS=CMSISv2p10_LPC13Uxx"/>
+								</option>
+								<option id="gnu.c.compiler.option.misc.other.1450857191" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections" valueType="string"/>
+								<option id="com.crt.advproject.gcc.hdrlib.1773190745" name="Use headers for C library" superClass="com.crt.advproject.gcc.hdrlib" value="com.crt.advproject.gcc.hdrlib.codered" valueType="enumerated"/>
+								<option id="gnu.c.compiler.option.include.paths.71330727" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/cmsis}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/cli}&quot;"/>
+								</option>
+								<option id="com.crt.advproject.c.misc.dialect.980558680" name="C Dialect" superClass="com.crt.advproject.c.misc.dialect" value="com.crt.advproject.misc.dialect.gnu99" valueType="enumerated"/>
+								<option id="gnu.c.compiler.option.warnings.pedantic.1514335985" name="Pedantic (-pedantic)" superClass="gnu.c.compiler.option.warnings.pedantic" value="false" valueType="boolean"/>
+								<inputType id="com.crt.advproject.compiler.input.430469609" superClass="com.crt.advproject.compiler.input"/>
+							</tool>
+							<tool id="com.crt.advproject.gas.exe.debug.1801607223" name="MCU Assembler" superClass="com.crt.advproject.gas.exe.debug">
+								<option id="com.crt.advproject.gas.arch.878530752" name="Architecture" superClass="com.crt.advproject.gas.arch" value="com.crt.advproject.gas.target.cm3" valueType="enumerated"/>
+								<option id="com.crt.advproject.gas.thumb.723777905" name="Thumb mode" superClass="com.crt.advproject.gas.thumb" value="true" valueType="boolean"/>
+								<option id="gnu.both.asm.option.flags.crt.524055960" name="Assembler flags" superClass="gnu.both.asm.option.flags.crt" value="-c -x assembler-with-cpp -D__REDLIB__ -DDEBUG -D__CODE_RED" valueType="string"/>
+								<option id="com.crt.advproject.gas.hdrlib.337915348" name="Use headers for C library" superClass="com.crt.advproject.gas.hdrlib" value="com.crt.advproject.gas.hdrlib.codered" valueType="enumerated"/>
+								<inputType id="com.crt.advproject.assembler.input.534983802" name="Additional Assembly Source Files" superClass="com.crt.advproject.assembler.input"/>
+								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1938134658" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+							</tool>
+							<tool id="com.crt.advproject.link.cpp.exe.debug.2075800947" name="MCU C++ Linker" superClass="com.crt.advproject.link.cpp.exe.debug"/>
+							<tool id="com.crt.advproject.link.exe.debug.1170909073" name="MCU Linker" superClass="com.crt.advproject.link.exe.debug">
+								<option id="com.crt.advproject.link.arch.1432298724" name="Architecture" superClass="com.crt.advproject.link.arch" value="com.crt.advproject.link.target.cm3" valueType="enumerated"/>
+								<option id="com.crt.advproject.link.thumb.2071701659" name="Thumb mode" superClass="com.crt.advproject.link.thumb" value="true" valueType="boolean"/>
+								<option id="com.crt.advproject.link.script.499798183" name="Linker script" superClass="com.crt.advproject.link.script" value="&quot;LPC11U_LPC13U_CodeBase_board_rf1ghzusb.ld&quot;" valueType="string"/>
+								<option id="com.crt.advproject.link.manage.1653486529" name="Manage linker script" superClass="com.crt.advproject.link.manage" value="true" valueType="boolean"/>
+								<option id="gnu.c.link.option.nostdlibs.544476149" name="No startup or default libs (-nostdlib)" superClass="gnu.c.link.option.nostdlibs" value="true" valueType="boolean"/>
+								<option id="gnu.c.link.option.other.880029791" name="Other options (-Xlinker [option])" superClass="gnu.c.link.option.other" valueType="stringList">
+									<listOptionValue builtIn="false" value="-Map=&quot;${BuildArtifactFileBaseName}.map&quot;"/>
+									<listOptionValue builtIn="false" value="--allow-multiple-definition"/>
+									<listOptionValue builtIn="false" value="--gc-sections"/>
+								</option>
+								<option id="com.crt.advproject.link.gcc.hdrlib.802565012" name="Use C library" superClass="com.crt.advproject.link.gcc.hdrlib" value="com.crt.advproject.gcc.link.hdrlib.codered.semihost" valueType="enumerated"/>
+								<option id="gnu.c.link.option.libs.189488570" name="Libraries (-l)" superClass="gnu.c.link.option.libs" valueType="libs">
+									<listOptionValue builtIn="false" value="arm_cortexM3l_math"/>
+									<listOptionValue builtIn="false" value="RTX_CM3"/>
+								</option>
+								<option id="gnu.c.link.option.paths.1304582147" name="Library search path (-L)" superClass="gnu.c.link.option.paths" valueType="libPaths">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/cmsis/libs}&quot;"/>
+								</option>
+								<option id="com.crt.advproject.link.gcc.multicore.slave.1853652725" name="Multicore slave" superClass="com.crt.advproject.link.gcc.multicore.slave"/>
+								<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1900511407" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+						</toolChain>
+					</folderInfo>
+					<fileInfo id="com.crt.advproject.config.exe.debug.31686071.2088192637.845617240.860621000.src/cr_startup_lpc13u.cpp" name="cr_startup_lpc13u.cpp" rcbsApplicability="disable" resourcePath="src/cr_startup_lpc13u.cpp" toolsToInvoke=""/>
+					<sourceEntries>
+						<entry excluding="startup_LPC13Uxx_keil.s|startup_lpc13u_gnumake.c|startup_lpc11u_gnumake.c|startup_LPC11Uxx_keil.s|system_LPC11Uxx.c|startup_LPC13Uxx_arm.s|startup_lpc13u.c|startup_LPC11Uxx_arm.s|startup_lpc11u.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="cmsis"/>
+						<entry excluding="drivers/rf/bluetooth|drivers/displays/graphic/hw/hx8347g.h|drivers/displays/graphic/hw/hx8347g.c|core/usb/usb_cdc_old.c|core/usb/hid_desc.c|core/usb_cdc.c|drivers/displays/graphic/aafonts/aa2/source|drivers/displays/graphic/aafonts/aa4/source|drivers/storage/fatfs/ccsbcs.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+			<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
+			<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+		</cconfiguration>
+		<cconfiguration id="com.crt.advproject.config.exe.debug.31686071.813738243.189727752">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.crt.advproject.config.exe.debug.31686071.813738243.189727752" moduleId="org.eclipse.cdt.core.settings" name="Unit Tests">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" 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.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactExtension="axf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="Unit Testing on Host" errorParsers="org.eclipse.cdt.core.MakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GASErrorParser" id="com.crt.advproject.config.exe.debug.31686071.813738243.189727752" name="Unit Tests" parent="com.crt.advproject.config.exe.debug" postannouncebuildStep="Performing post-build steps" postbuildStep="arm-none-eabi-size &quot;${BuildArtifactFileName}&quot;; #arm-none-eabi-objcopy -O binary &quot;${BuildArtifactFileName}&quot; &quot;${BuildArtifactFileBaseName}.bin&quot; ; checksum -p ${TargetChip} -d &quot;${BuildArtifactFileBaseName}.bin&quot;;  ">
+					<folderInfo id="com.crt.advproject.config.exe.debug.31686071.813738243.189727752." name="/" resourcePath="">
+						<toolChain id="cdt.managedbuild.toolchain.gnu.mingw.base.1013237103" name="MinGW GCC" superClass="cdt.managedbuild.toolchain.gnu.mingw.base">
+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.PE" id="cdt.managedbuild.target.gnu.platform.mingw.base.549536196" name="Debug Platform" osList="win32" superClass="cdt.managedbuild.target.gnu.platform.mingw.base"/>
+							<builder buildPath="${workspace_loc:/LPC11U_LPC13U_CodeBase/Test Host}" id="cdt.managedbuild.target.gnu.builder.base.32757778" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
+							<tool id="cdt.managedbuild.tool.gnu.assembler.mingw.base.1552435561" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.mingw.base">
+								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1750460629" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.archiver.mingw.base.2138995537" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.mingw.base"/>
+							<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base.408533627" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base"/>
+							<tool id="cdt.managedbuild.tool.gnu.c.compiler.mingw.base.1392617983" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.mingw.base">
+								<option id="gnu.c.compiler.option.include.paths.2090133852" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/cmsis}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/cli}&quot;"/>
+								</option>
+								<option id="gnu.c.compiler.option.preprocessor.def.symbols.487822153" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="__REDLIB__"/>
+									<listOptionValue builtIn="false" value="ARM_MATH_CM3"/>
+									<listOptionValue builtIn="false" value="_TEST_"/>
+									<listOptionValue builtIn="false" value="DEBUG"/>
+									<listOptionValue builtIn="false" value="__CODE_RED"/>
+									<listOptionValue builtIn="false" value="__USE_CMSIS=CMSISv2p10_LPC13Uxx"/>
+									<listOptionValue builtIn="false" value="CFG_BRD_RF1GHZNODE=1"/>
+								</option>
+								<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1234878819" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.c.linker.mingw.base.1325287067" name="MinGW C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.mingw.base">
+								<option id="gnu.c.link.option.libs.1029207244" name="Libraries (-l)" superClass="gnu.c.link.option.libs" valueType="libs">
+									<listOptionValue builtIn="false" value="arm_cortexM3l_math"/>
+									<listOptionValue builtIn="false" value="RTX_CM3"/>
+								</option>
+								<option id="gnu.c.link.option.paths.1662049946" name="Library search path (-L)" superClass="gnu.c.link.option.paths" valueType="libPaths">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/cmsis/libs}&quot;"/>
+								</option>
+								<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.2091001581" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+							<tool id="cdt.managedbuild.tool.gnu.cpp.linker.mingw.base.2097382306" name="MinGW C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.mingw.base"/>
+						</toolChain>
+					</folderInfo>
+					<fileInfo id="com.crt.advproject.config.exe.debug.31686071.813738243.189727752.src/cr_startup_lpc13u.cpp" name="cr_startup_lpc13u.cpp" rcbsApplicability="disable" resourcePath="src/cr_startup_lpc13u.cpp" toolsToInvoke=""/>
+					<sourceEntries>
+						<entry excluding="startup_LPC13Uxx_keil.s|startup_lpc13u_gnumake.c|startup_lpc11u_gnumake.c|startup_LPC11Uxx_keil.s|startup_LPC13Uxx_arm.s|startup_lpc13u.c|startup_LPC11Uxx_arm.s|startup_lpc11u.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="cmsis"/>
+						<entry excluding="main.c|drivers/rf/bluetooth|drivers/displays/graphic/hw/hx8347g.h|drivers/displays/graphic/hw/hx8347g.c|core/usb/usb_cdc_old.c|core/usb/hid_desc.c|core/usb_cdc.c|drivers/displays/graphic/aafonts/aa2/source|drivers/displays/graphic/aafonts/aa4/source|drivers/storage/fatfs/ccsbcs.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+			<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
+			<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="LPC11U_LPC13U_Codebase.com.crt.advproject.projecttype.exe.1731523490" name="Executable" projectType="com.crt.advproject.projecttype.exe"/>
+	</storageModule>
+	<storageModule moduleId="com.crt.config">
+		<projectStorage>&lt;?xml version="1.0" encoding="UTF-8"?&gt;&#13;
+&lt;TargetConfig&gt;&#13;
+&lt;Properties property_0="" property_2="LPC11_12_13_64K_8K.cfx" property_3="NXP" property_4="LPC1347" property_count="5" version="1"/&gt;&#13;
+&lt;infoList vendor="NXP"&gt;&lt;info chip="LPC1347" flash_driver="LPC11_12_13_64K_8K.cfx" match_id="0x08020543" name="LPC1347" stub="crt_emu_lpc11_13_nxp"&gt;&lt;chip&gt;&lt;name&gt;LPC1347&lt;/name&gt;&#13;
+&lt;family&gt;LPC13xx (12bit ADC)&lt;/family&gt;&#13;
+&lt;vendor&gt;NXP (formerly Philips)&lt;/vendor&gt;&#13;
+&lt;reset board="None" core="Real" sys="Real"/&gt;&#13;
+&lt;clock changeable="TRUE" freq="12MHz" is_accurate="TRUE"/&gt;&#13;
+&lt;memory can_program="true" id="Flash" is_ro="true" type="Flash"/&gt;&#13;
+&lt;memory id="RAM" type="RAM"/&gt;&#13;
+&lt;memory id="Periph" is_volatile="true" type="Peripheral"/&gt;&#13;
+&lt;memoryInstance derived_from="Flash" id="MFlash64" location="0x0" size="0x10000"/&gt;&#13;
+&lt;memoryInstance derived_from="RAM" id="RamLoc8" location="0x10000000" size="0x2000"/&gt;&#13;
+&lt;memoryInstance derived_from="RAM" id="RamUsb2" location="0x20004000" size="0x800"/&gt;&#13;
+&lt;memoryInstance derived_from="RAM" id="RamPeriph2" location="0x20000000" size="0x800"/&gt;&#13;
+&lt;prog_flash blocksz="0x1000" location="0x0" maxprgbuff="0x1000" progwithcode="TRUE" size="0x10000"/&gt;&#13;
+&lt;peripheralInstance derived_from="V7M_MPU" id="MPU" location="0xe000ed90"/&gt;&#13;
+&lt;peripheralInstance derived_from="V7M_NVIC" id="NVIC" location="0xe000e000"/&gt;&#13;
+&lt;peripheralInstance derived_from="V7M_DCR" id="DCR" location="0xe000edf0"/&gt;&#13;
+&lt;peripheralInstance derived_from="V7M_ITM" id="ITM" location="0xe0000000"/&gt;&#13;
+&lt;peripheralInstance derived_from="I2C" id="I2C" location="0x40000000"/&gt;&#13;
+&lt;peripheralInstance derived_from="WWDT" id="WWDT" location="0x40004000"/&gt;&#13;
+&lt;peripheralInstance derived_from="USART" id="USART" location="0x40008000"/&gt;&#13;
+&lt;peripheralInstance derived_from="CT16B0" id="CT16B0" location="0x4000c000"/&gt;&#13;
+&lt;peripheralInstance derived_from="CT16B1" id="CT16B1" location="0x40010000"/&gt;&#13;
+&lt;peripheralInstance derived_from="CT32B0" id="CT32B0" location="0x40014000"/&gt;&#13;
+&lt;peripheralInstance derived_from="CT32B1" id="CT32B1" location="0x40018000"/&gt;&#13;
+&lt;peripheralInstance derived_from="ADC" id="ADC" location="0x4001c000"/&gt;&#13;
+&lt;peripheralInstance derived_from="PMU" id="PMU" location="0x40038000"/&gt;&#13;
+&lt;peripheralInstance derived_from="FLASHCTRL" id="FLASHCTRL" location="0x4003c000"/&gt;&#13;
+&lt;peripheralInstance derived_from="SSP0" id="SSP0" location="0x40040000"/&gt;&#13;
+&lt;peripheralInstance derived_from="IOCON" id="IOCON" location="0x40044000"/&gt;&#13;
+&lt;peripheralInstance derived_from="SYSCON" id="SYSCON" location="0x40048000"/&gt;&#13;
+&lt;peripheralInstance derived_from="GPIO-PIN-INT" id="GPIO-PIN-INT" location="0x4004c000"/&gt;&#13;
+&lt;peripheralInstance derived_from="SSP1" id="SSP1" location="0x40058000"/&gt;&#13;
+&lt;peripheralInstance derived_from="GPIO-GROUP-INT0" id="GPIO-GROUP-INT0" location="0x4005c000"/&gt;&#13;
+&lt;peripheralInstance derived_from="GPIO-GROUP-INT1" id="GPIO-GROUP-INT1" location="0x40060000"/&gt;&#13;
+&lt;peripheralInstance derived_from="RITIMER" id="RITIMER" location="0x40064000"/&gt;&#13;
+&lt;peripheralInstance derived_from="USB" id="USB" location="0x40080000"/&gt;&#13;
+&lt;peripheralInstance derived_from="GPIO-PORT" id="GPIO-PORT" location="0x50000000"/&gt;&#13;
+&lt;/chip&gt;&#13;
+&lt;processor&gt;&lt;name gcc_name="cortex-m3"&gt;Cortex-M3&lt;/name&gt;&#13;
+&lt;family&gt;Cortex-M&lt;/family&gt;&#13;
+&lt;/processor&gt;&#13;
+&lt;link href="nxp_lpc13Uxx_peripheral.xme" show="embed" type="simple"/&gt;&#13;
+&lt;/info&gt;&#13;
+&lt;/infoList&gt;&#13;
+&lt;/TargetConfig&gt;</projectStorage>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+	<storageModule moduleId="refreshScope" versionNumber="2">
+		<configuration configurationName="Release">
+			<resource resourceType="PROJECT" workspacePath="/LPC11U_LPC13U_Codebase"/>
+		</configuration>
+		<configuration configurationName="Test"/>
+		<configuration configurationName="lpc13uxx"/>
+		<configuration configurationName="Debug">
+			<resource resourceType="PROJECT" workspacePath="/LPC11U_LPC13U_Codebase"/>
+		</configuration>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+			<buildOutputProvider>
+				<openAction enabled="true" filePath=""/>
+				<parser enabled="true"/>
+			</buildOutputProvider>
+			<scannerInfoProvider id="specsFile">
+				<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+				<parser enabled="true"/>
+			</scannerInfoProvider>
+		</profile>
+		<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+			<buildOutputProvider>
+				<openAction enabled="true" filePath=""/>
+				<parser enabled="true"/>
+			</buildOutputProvider>
+			<scannerInfoProvider id="specsFile">
+				<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+				<parser enabled="true"/>
+			</scannerInfoProvider>
+		</profile>
+		<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+			<buildOutputProvider>
+				<openAction enabled="true" filePath=""/>
+				<parser enabled="true"/>
+			</buildOutputProvider>
+			<scannerInfoProvider id="specsFile">
+				<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+				<parser enabled="true"/>
+			</scannerInfoProvider>
+		</profile>
+		<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+			<buildOutputProvider>
+				<openAction enabled="true" filePath=""/>
+				<parser enabled="true"/>
+			</buildOutputProvider>
+			<scannerInfoProvider id="specsFile">
+				<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+				<parser enabled="true"/>
+			</scannerInfoProvider>
+		</profile>
+		<scannerConfigBuildInfo instanceId="com.crt.advproject.config.exe.debug.31686071.813738243;com.crt.advproject.config.exe.debug.31686071.813738243.;com.crt.advproject.gas.exe.debug.1975416117;com.crt.advproject.assembler.input.1699188568">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.crt.advproject.GCCManagedMakePerProjectProfile"/>
+			<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.crt.advproject.config.exe.debug.31686071;com.crt.advproject.config.exe.debug.31686071.src/cr_startup_lpc13u.c;com.crt.advproject.gcc.exe.debug.193771616.224057781;com.crt.advproject.compiler.input.1139040405">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.crt.advproject.GCCManagedMakePerProjectProfile"/>
+			<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.crt.advproject.config.exe.debug.31686071;com.crt.advproject.config.exe.debug.31686071.;com.crt.advproject.gas.exe.debug.901247457;com.crt.advproject.assembler.input.1899264729">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.crt.advproject.GCCManagedMakePerProjectProfile"/>
+			<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.crt.advproject.config.exe.debug.31686071;com.crt.advproject.config.exe.debug.31686071.;com.crt.advproject.gcc.exe.debug.193771616;com.crt.advproject.compiler.input.1854981945">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.crt.advproject.GCCManagedMakePerProjectProfile"/>
+			<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.crt.advproject.config.exe.release.1359038632;com.crt.advproject.config.exe.release.1359038632.;com.crt.advproject.gas.exe.release.1510879370;com.crt.advproject.assembler.input.131494635">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.crt.advproject.GCCManagedMakePerProjectProfile"/>
+			<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.crt.advproject.config.exe.debug.31686071.813738243;com.crt.advproject.config.exe.debug.31686071.813738243.;com.crt.advproject.gcc.exe.debug.2075339861;com.crt.advproject.compiler.input.746444375">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.crt.advproject.GCCManagedMakePerProjectProfile"/>
+			<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.crt.advproject.config.exe.release.1359038632;com.crt.advproject.config.exe.release.1359038632.;com.crt.advproject.gcc.exe.release.924652254;com.crt.advproject.compiler.input.1528512002">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.crt.advproject.GCCManagedMakePerProjectProfile"/>
+			<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+			<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
+				<buildOutputProvider>
+					<openAction enabled="true" filePath=""/>
+					<parser enabled="true"/>
+				</buildOutputProvider>
+				<scannerInfoProvider id="specsFile">
+					<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
+					<parser enabled="true"/>
+				</scannerInfoProvider>
+			</profile>
+		</scannerConfigBuildInfo>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
+		<buildTargets>
+			<target name="clean" path="tests_host" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
+				<buildCommand>rake.bat</buildCommand>
+				<buildArguments/>
+				<buildTarget>clean</buildTarget>
+				<stopOnError>true</stopOnError>
+				<useDefaultCommand>false</useDefaultCommand>
+				<runAllBuilders>true</runAllBuilders>
+			</target>
+			<target name="clobber" path="tests_host" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
+				<buildCommand>rake.bat</buildCommand>
+				<buildArguments/>
+				<buildTarget>clobber</buildTarget>
+				<stopOnError>true</stopOnError>
+				<useDefaultCommand>false</useDefaultCommand>
+				<runAllBuilders>true</runAllBuilders>
+			</target>
+			<target name="release" path="tests_host" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
+				<buildCommand>rake.bat</buildCommand>
+				<buildArguments/>
+				<buildTarget>release</buildTarget>
+				<stopOnError>true</stopOnError>
+				<useDefaultCommand>false</useDefaultCommand>
+				<runAllBuilders>true</runAllBuilders>
+			</target>
+			<target name="test" path="tests_host" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
+				<buildCommand>rake.bat</buildCommand>
+				<buildArguments/>
+				<buildTarget>test:all</buildTarget>
+				<stopOnError>true</stopOnError>
+				<useDefaultCommand>false</useDefaultCommand>
+				<runAllBuilders>true</runAllBuilders>
+			</target>
+			<target name="test delta" path="tests_host" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
+				<buildCommand>rake.bat</buildCommand>
+				<buildArguments/>
+				<buildTarget>test:delta</buildTarget>
+				<stopOnError>true</stopOnError>
+				<useDefaultCommand>false</useDefaultCommand>
+				<runAllBuilders>true</runAllBuilders>
+			</target>
+			<target name="test verbose" path="tests_host" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
+				<buildCommand>rake.bat</buildCommand>
+				<buildArguments/>
+				<buildTarget>verbosity[4] test:all</buildTarget>
+				<stopOnError>true</stopOnError>
+				<useDefaultCommand>false</useDefaultCommand>
+				<runAllBuilders>true</runAllBuilders>
+			</target>
+			<target name="test verbose delta" path="tests_host" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
+				<buildCommand>rake.bat</buildCommand>
+				<buildArguments/>
+				<buildTarget>verbosity[4] test:delta</buildTarget>
+				<stopOnError>true</stopOnError>
+				<useDefaultCommand>false</useDefaultCommand>
+				<runAllBuilders>true</runAllBuilders>
+			</target>
+		</buildTargets>
+	</storageModule>
+</cproject>
diff --git a/reform2-lpc-fw/.gitignore b/reform2-lpc-fw/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..3dd74388ab61018e613353d85e6220ffac7d477d
--- /dev/null
+++ b/reform2-lpc-fw/.gitignore
@@ -0,0 +1,3 @@
+bin
+*.o
+tests_host
diff --git a/reform2-lpc-fw/.project b/reform2-lpc-fw/.project
new file mode 100644
index 0000000000000000000000000000000000000000..79cfa94842aecbd6ea22d88bc49ff00e34bba439
--- /dev/null
+++ b/reform2-lpc-fw/.project
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>LPC11U_LPC13U_Codebase</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+			<triggers>clean,full,incremental,</triggers>
+			<arguments>
+				<dictionary>
+					<key>?name?</key>
+					<value></value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.append_environment</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
+					<value>all</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildArguments</key>
+					<value></value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildCommand</key>
+					<value>make</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildLocation</key>
+					<value>${workspace_loc:/LPC11U_LPC13U_Codebase/Debug}</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
+					<value>clean</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.contents</key>
+					<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
+					<value>false</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableFullBuild</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
+					<value>all</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.stopOnError</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
+					<value>true</value>
+				</dictionary>
+			</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>
+	<filteredResources>
+		<filter>
+			<id>1352877696259</id>
+			<name>src/drivers/rf/bluetooth/nrf8001</name>
+			<type>6</type>
+			<matcher>
+				<id>org.eclipse.ui.ide.multiFilter</id>
+				<arguments>1.0-name-matches-false-false-data_queue.*</arguments>
+			</matcher>
+		</filter>
+		<filter>
+			<id>1352877696283</id>
+			<name>src/drivers/rf/bluetooth/nrf8001</name>
+			<type>6</type>
+			<matcher>
+				<id>org.eclipse.ui.ide.multiFilter</id>
+				<arguments>1.0-name-matches-false-false-hid_application.*</arguments>
+			</matcher>
+		</filter>
+	</filteredResources>
+</projectDescription>
diff --git a/reform2-lpc-fw/.travis.yml b/reform2-lpc-fw/.travis.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3e4d31db01eb7e788bb2672e97596e201c03d0cf
--- /dev/null
+++ b/reform2-lpc-fw/.travis.yml
@@ -0,0 +1,4 @@
+language: c
+compiler:
+  - gcc
+script: cd tests_host/ && rake test:all
\ No newline at end of file
diff --git a/reform2-lpc-fw/License.txt b/reform2-lpc-fw/License.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9b04d94a324ca0b21e5366dee23fdfc529133938
--- /dev/null
+++ b/reform2-lpc-fw/License.txt
@@ -0,0 +1,26 @@
+Software License Agreement (BSD License)
+
+Unless otherwise noted, Copyright (c) 2013 Kevin Townsend (microBuilder.eu)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. Neither the name of the copyright holders nor the
+names of its contributors may be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/reform2-lpc-fw/Makefile b/reform2-lpc-fw/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..0cee652de48ee4307f0793bab6d7ba18788ed20b
--- /dev/null
+++ b/reform2-lpc-fw/Makefile
@@ -0,0 +1,438 @@
+##########################################################################
+# User configuration and firmware specific object files	
+##########################################################################
+
+FILENAME=firmware
+
+# See projectconfig.h for a list of valid BOARD options!
+BOARD=CFG_BRD_REFORM2
+
+# Set TARGET to 'lpc11u' or 'lpc13u' depending on the target MCU
+TARGET = lpc11u
+ifeq (lpc11u,$(TARGET))
+  CORE = cortex-m0
+  LDSCRIPT = cmsis/lpc11u24.ld
+  # LDSCRIPT = cmsis/lpc11u37.ld
+else
+  CORE = cortex-m3
+  LDSCRIPT = cmsis/lpc1347.ld
+endif
+
+# Set OPTIMIZATION to '0', '1', '2', '3' or 's'
+OPTIMIZATION = s
+
+##########################################################################
+# Output directories
+##########################################################################
+
+BIN_PATH = bin
+OBJ_PATH = bin/obj
+
+##########################################################################
+# Source Files
+##########################################################################
+
+VPATH = cmsis
+ifeq (lpc11u,$(TARGET))
+  OBJS   = $(OBJ_PATH)/startup_lpc11u_gnumake.o 
+  OBJS  += $(OBJ_PATH)/system_LPC11Uxx.o
+else
+  OBJS   = $(OBJ_PATH)/startup_lpc13u_gnumake.o 
+  OBJS  += $(OBJ_PATH)/system_LPC13Uxx.o
+endif
+OBJS  += $(OBJ_PATH)/math_helper.o
+OBJS  += $(OBJ_PATH)/RTX_hook.o
+
+VPATH += src
+OBJS  += $(OBJ_PATH)/printf-retarget.o
+
+VPATH += src/boards/lpcnfc
+OBJS  += $(OBJ_PATH)/board_lpcnfc.o
+
+VPATH += src/boards/reform2
+OBJS  += $(OBJ_PATH)/board_reform2.o
+
+VPATH += src/boards/rf1ghzusb
+OBJS  += $(OBJ_PATH)/board_rf1ghzusb.o
+
+VPATH += src/boards/rf1ghznode
+OBJS  += $(OBJ_PATH)/board_rf1ghznode.o
+
+VPATH += src/cli
+OBJS  += $(OBJ_PATH)/cli.o 
+OBJS  += $(OBJ_PATH)/commands.o
+
+VPATH += src/cli/commands
+OBJS  += $(OBJ_PATH)/cmd_chibi_addr.o 
+OBJS  += $(OBJ_PATH)/cmd_chibi_tx.o 
+OBJS  += $(OBJ_PATH)/cmd_dbg_memrd.o
+OBJS  += $(OBJ_PATH)/cmd_eeprom_read.o 
+OBJS  += $(OBJ_PATH)/cmd_eeprom_write.o 
+OBJS  += $(OBJ_PATH)/cmd_i2c_read.o
+OBJS  += $(OBJ_PATH)/cmd_i2c_scan.o 
+OBJS  += $(OBJ_PATH)/cmd_i2c_write.o 
+OBJS  += $(OBJ_PATH)/cmd_nfc_mfc_ndef.o
+OBJS  += $(OBJ_PATH)/cmd_nfc_mifareclassic_memdump.o
+OBJS  += $(OBJ_PATH)/cmd_nfc_mifareclassic_valueblock.o 
+OBJS  += $(OBJ_PATH)/cmd_nfc_mifareultralight_memdump.o 
+OBJS  += $(OBJ_PATH)/cmd_rtc_read.o
+OBJS  += $(OBJ_PATH)/cmd_rtc_write.o
+OBJS  += $(OBJ_PATH)/cmd_sd_dir.o
+OBJS  += $(OBJ_PATH)/cmd_sysinfo.o
+OBJS  += $(OBJ_PATH)/cmd_wifi.o
+
+VPATH += src/core/adc
+OBJS  += $(OBJ_PATH)/adc.o
+
+VPATH += src/core/delay
+OBJS  += $(OBJ_PATH)/delay.o
+
+VPATH += src/core/debug
+OBJS  += $(OBJ_PATH)/debug.o
+
+VPATH += src/core/eeprom
+OBJS  += $(OBJ_PATH)/eeprom.o
+
+VPATH += src/core/fifo
+OBJS  += $(OBJ_PATH)/fifo.o
+
+VPATH += src/core/gpio
+OBJS  += $(OBJ_PATH)/gpio.o
+
+VPATH += src/core/i2c
+OBJS  += $(OBJ_PATH)/i2c.o
+
+VPATH += src/core/iap
+OBJS  += $(OBJ_PATH)/iap.o
+
+VPATH += src/core/libc
+OBJS  += $(OBJ_PATH)/stdio.o 
+OBJS  += $(OBJ_PATH)/string.o
+
+VPATH += src/core/pmu
+OBJS  += $(OBJ_PATH)/pmu.o
+
+VPATH += src/core/ssp0
+OBJS  += $(OBJ_PATH)/ssp0.o
+
+VPATH += src/core/ssp1
+OBJS  += $(OBJ_PATH)/ssp1.o
+
+VPATH += src/core/timer16
+OBJS  += $(OBJ_PATH)/timer16.o
+
+VPATH += src/core/timer32
+OBJS  += $(OBJ_PATH)/timer32.o
+
+VPATH += src/core/uart
+OBJS  += $(OBJ_PATH)/uart.o 
+OBJS  += $(OBJ_PATH)/uart_buf.o
+
+VPATH += src/core/usb
+OBJS  += $(OBJ_PATH)/descriptors.o 
+OBJS  += $(OBJ_PATH)/usb_cdc.o 
+OBJS  += $(OBJ_PATH)/usb_custom_class.o
+OBJS  += $(OBJ_PATH)/usb_hid.o 
+OBJS  += $(OBJ_PATH)/usb_msc.o 
+OBJS  += $(OBJ_PATH)/usbd.o
+
+VPATH += src/drivers
+OBJS  += $(OBJ_PATH)/timespan.o
+
+VPATH += src/drivers/displays
+OBJS  += $(OBJ_PATH)/smallfonts.o
+
+VPATH += src/drivers/displays/bitmap/ssd1306
+OBJS  += $(OBJ_PATH)/ssd1306_i2c.o
+
+VPATH += src/drivers/displays/graphic 
+OBJS  += $(OBJ_PATH)/aafonts.o 
+OBJS  += $(OBJ_PATH)/colors.o 
+OBJS  += $(OBJ_PATH)/drawing.o 
+OBJS  += $(OBJ_PATH)/fonts.o 
+OBJS  += $(OBJ_PATH)/theme.o
+
+VPATH += src/drivers/displays/graphic/aafonts/aa2 
+OBJS  += $(OBJ_PATH)/DejaVuSansCondensed14_AA2.o 
+OBJS  += $(OBJ_PATH)/DejaVuSansCondensedBold14_AA2.o 
+OBJS  += $(OBJ_PATH)/DejaVuSansMono10_AA2.o 
+OBJS  += $(OBJ_PATH)/DejaVuSansMono13_AA2.o 
+OBJS  += $(OBJ_PATH)/DejaVuSansMono14_AA2.o 
+OBJS  += $(OBJ_PATH)/FontCalibri18_AA2.o 
+OBJS  += $(OBJ_PATH)/FontCalibriBold18_AA2.o 
+OBJS  += $(OBJ_PATH)/FontCalibriItalic18_AA2.o 
+OBJS  += $(OBJ_PATH)/FontFranklinGothicBold99_Numbers_AA2.o
+
+VPATH += src/drivers/displays/graphic/aafonts/aa4 
+OBJS  += $(OBJ_PATH)/FontCalibri18_AA4.o
+
+VPATH += src/drivers/displays/graphic/fonts 
+OBJS  += $(OBJ_PATH)/dejavusans9.o 
+OBJS  += $(OBJ_PATH)/dejavusansbold9.o 
+OBJS  += $(OBJ_PATH)/dejavusanscondensed9.o 
+OBJS  += $(OBJ_PATH)/dejavusansmono8.o 
+OBJS  += $(OBJ_PATH)/dejavusansmonobold8.o 
+OBJS  += $(OBJ_PATH)/veramono9.o 
+OBJS  += $(OBJ_PATH)/veramono11.o 
+OBJS  += $(OBJ_PATH)/veramonobold9.o 
+OBJS  += $(OBJ_PATH)/veramonobold11.o 
+OBJS  += $(OBJ_PATH)/verdana9.o 
+OBJS  += $(OBJ_PATH)/verdana14.o 
+OBJS  += $(OBJ_PATH)/verdanabold14.o
+
+VPATH += src/drivers/displays/graphic/hw
+OBJS  += $(OBJ_PATH)/hx8340b.o 
+# OBJS  += $(OBJ_PATH)/hx8347g.o
+
+VPATH += src/drivers/displays/segment/ht16k33
+OBJS  += $(OBJ_PATH)/ht16k33.o
+
+VPATH += src/drivers/filters/iir
+OBJS  += $(OBJ_PATH)/iir_f.o
+OBJS  += $(OBJ_PATH)/iir_i.o
+OBJS  += $(OBJ_PATH)/iir_u16.o
+
+VPATH += src/drivers/filters/ma
+OBJS  += $(OBJ_PATH)/sma_f.o 
+OBJS  += $(OBJ_PATH)/sma_i.o 
+OBJS  += $(OBJ_PATH)/sma_u16.o
+OBJS  += $(OBJ_PATH)/wma_f.o 
+OBJS  += $(OBJ_PATH)/wma_i.o 
+OBJS  += $(OBJ_PATH)/wma_u16.o
+
+VPATH += src/drivers/motor/stepper
+OBJS  += $(OBJ_PATH)/stepper.o
+
+VPATH += src/drivers/pwm/pca9685
+OBJS  += $(OBJ_PATH)/pca9685.o
+
+VPATH += src/drivers/rf/802.15.4/chibi
+OBJS  += $(OBJ_PATH)/chb.o 
+OBJS  += $(OBJ_PATH)/chb_buf.o 
+OBJS  += $(OBJ_PATH)/chb_drvr.o 
+OBJS  += $(OBJ_PATH)/chb_eeprom.o 
+OBJS  += $(OBJ_PATH)/chb_spi.o
+OBJS  += $(OBJ_PATH)/messages.o
+
+VPATH += src/drivers/rf/nfc/pn532
+OBJS  += $(OBJ_PATH)/pn532.o 
+OBJS  += $(OBJ_PATH)/pn532_bus_i2c.o 
+OBJS  += $(OBJ_PATH)/pn532_bus_uart.o
+
+VPATH += src/drivers/rf/nfc/pn532/helpers
+OBJS  += $(OBJ_PATH)/pn532_config.o 
+OBJS  += $(OBJ_PATH)/pn532_gpio.o 
+OBJS  += $(OBJ_PATH)/pn532_mifare_classic.o 
+OBJS  += $(OBJ_PATH)/pn532_mifare_ultralight.o 
+OBJS  += $(OBJ_PATH)/pn532_ndef.o 
+OBJS  += $(OBJ_PATH)/pn532_ndef_cards.o 
+
+VPATH += src/drivers/rf/wifi/cc3000
+OBJS  += $(OBJ_PATH)/spi.o 
+OBJS  += $(OBJ_PATH)/wifi.o 
+
+VPATH += src/drivers/rf/wifi/cc3000/hostdriver
+OBJS  += $(OBJ_PATH)/cc3000_common.o 
+OBJS  += $(OBJ_PATH)/evnt_handler.o 
+OBJS  += $(OBJ_PATH)/hci.o 
+OBJS  += $(OBJ_PATH)/netapp.o 
+OBJS  += $(OBJ_PATH)/nvmem.o 
+OBJS  += $(OBJ_PATH)/security.o 
+OBJS  += $(OBJ_PATH)/socket.o 
+OBJS  += $(OBJ_PATH)/wlan.o 
+
+VPATH += src/drivers/rf/nfc/pn532/mem_allocator
+OBJS  += $(OBJ_PATH)/bget.o 
+OBJS  += $(OBJ_PATH)/pn532_mem.o 
+
+VPATH += src/drivers/rtc
+OBJS  += $(OBJ_PATH)/rtc.o
+
+VPATH += src/drivers/rtc/pcf2129
+OBJS  += $(OBJ_PATH)/pcf2129.o
+
+VPATH += src/drivers/sensors
+OBJS  += $(OBJ_PATH)/sensors.o
+OBJS  += $(OBJ_PATH)/sensorpoll.o
+
+VPATH += src/drivers/sensors/accelerometers
+OBJS  += $(OBJ_PATH)/accelerometers.o
+OBJS  += $(OBJ_PATH)/adxl345.o
+OBJS  += $(OBJ_PATH)/lis3dh.o
+OBJS  += $(OBJ_PATH)/lsm303accel.o
+
+VPATH += src/drivers/sensors/gyroscopes
+OBJS  += $(OBJ_PATH)/l3gd20.o
+
+VPATH += src/drivers/sensors/light
+OBJS  += $(OBJ_PATH)/tsl2561.o
+
+VPATH += src/drivers/sensors/magnetometers
+OBJS  += $(OBJ_PATH)/magnetometers.o
+OBJS  += $(OBJ_PATH)/lsm303mag.o
+
+VPATH += src/drivers/sensors/pressure
+OBJS  += $(OBJ_PATH)/pressure.o
+OBJS  += $(OBJ_PATH)/bmp085.o
+OBJS  += $(OBJ_PATH)/mpl115a2.o
+
+VPATH += src/drivers/sensors/temperature
+OBJS  += $(OBJ_PATH)/lm75b.o
+
+VPATH += src/drivers/storage
+OBJS  += $(OBJ_PATH)/logger.o 
+
+VPATH += src/drivers/storage/fatfs
+OBJS  += $(OBJ_PATH)/ff.o 
+OBJS  += $(OBJ_PATH)/mmc.o
+
+VPATH += src/localisation
+OBJS  += $(OBJ_PATH)/localisation.o
+
+VPATH += src/protocol
+OBJS  += $(OBJ_PATH)/protocol.o
+
+VPATH += src/protocol/commands
+OBJS  += $(OBJ_PATH)/protocol_cmd_led.o
+OBJS  += $(OBJ_PATH)/protocol_cmd_sysinfo.o
+
+##########################################################################
+# Include paths
+##########################################################################
+
+ROOT_PATH = src
+INCLUDE_PATHS = -I$(ROOT_PATH) -Icmsis
+
+##########################################################################
+# GNU GCC compiler prefix
+##########################################################################
+
+# Use the default toolchain (based on the PATH variable, etc.)
+CROSS_COMPILE ?= arm-none-eabi-
+
+# OR ... use a toolchain at a specific location
+# CROSS_COMPILE = C:/code_red/RedSuiteNXP_5.0.12_1048/redsuite/tools/bin/arm-none-eabi-
+# CROSS_COMPILE = C:/arm/gnu4.7.2012.q4/bin/arm-none-eabi-
+
+AS           = $(CROSS_COMPILE)gcc
+CC           = $(CROSS_COMPILE)gcc
+LD           = $(CROSS_COMPILE)gcc
+SIZE         = $(CROSS_COMPILE)size
+OBJCOPY      = $(CROSS_COMPILE)objcopy
+OBJDUMP      = $(CROSS_COMPILE)objdump
+OUTFILE      = $(BIN_PATH)/$(FILENAME)
+LPCRC       ?= tools/lpcrc/lpcrc
+REMOVE       = rm -f
+MOUNT_POINT ?= /media/CRP DISABLD
+
+##########################################################################
+# Compiler settings, parameters and flags
+##########################################################################
+
+# Compiler Options
+GCFLAGS  = -c 
+GCFLAGS += -std=gnu99 
+GCFLAGS += -g 
+GCFLAGS += -O$(OPTIMIZATION) 
+GCFLAGS += $(INCLUDE_PATHS) 
+GCFLAGS += -Wall 
+GCFLAGS += -mthumb 
+GCFLAGS += -ffunction-sections 
+GCFLAGS += -fdata-sections 
+GCFLAGS += -fmessage-length=0 
+GCFLAGS += -fno-builtin 
+GCFLAGS += -mcpu=$(CORE) 
+GCFLAGS += -DTARGET=$(TARGET)
+GCFLAGS += -D$(BOARD)
+# CMSIS DSP Flags
+ifeq (lpc11u,$(TARGET))
+  GCFLAGS += -DARM_MATH_CM0
+else
+  GCFLAGS += -DARM_MATH_CM3
+endif
+# For use with the GCC ARM Embedded toolchain
+# GCFLAGS += --specs=nano.specs
+# For use with the LPCXpresso toolchain
+# GCFLAGS += -D__REDLIB__ -D__CODE_RED
+
+# Assembler Options
+ASFLAGS  = -c 
+ASFLAGS += -g 
+ASFLAGS += -O$(OPTIMIZATION) 
+ASFLAGS += $(INCLUDE_PATHS) 
+ASFLAGS += -Wall 
+ASFLAGS += -mthumb 
+ASFLAGS += -ffunction-sections 
+ASFLAGS += -fdata-sections 
+ASFLAGS += -fmessage-length=0 
+ASFLAGS += -mcpu=$(CORE) 
+ASFLAGS += -D__ASSEMBLY__ 
+ASFLAGS += -x assembler-with-cpp
+
+# Linker Options
+LDFLAGS  = -nostartfiles 
+LDFLAGS += -mcpu=$(CORE) 
+LDFLAGS += -mthumb 
+LDFLAGS += -O$(OPTIMIZATION) 
+LDFLAGS += -Wl,--gc-sections 
+LDFLAGS += -T $(LDSCRIPT)
+LDFLAGS += -Xlinker -Map=bin/firmware.map
+# CMSIS Libraries
+LDFLAGS += -L./cmsis/libs
+ifeq (lpc11u,$(TARGET))
+  LDLIBS   = -larm_cortexM0l_math -lRTX_CM0
+else
+  LDLIBS   = -larm_cortexM3l_math -lRTX_CM3
+endif
+# External Libraries
+LDLIBS   += -lm
+# The following libraries are required with the LPCXpresso toolchain
+# LDLIBS  += -lcr_c -lcr_eabihelpers
+
+OCFLAGS = --strip-unneeded
+
+##########################################################################
+# Rules
+##########################################################################
+
+all: firmware
+
+$(OBJ_PATH)/%.o : %.c
+	@mkdir -p $(dir $@)
+	-@echo "COMPILING $(@F)"
+	@$(CC) $(GCFLAGS) -o $@ $<
+
+$(OBJ_PATH)/%.o : %.s
+	@mkdir -p $(dir $@)
+	-@echo "ASSEMBLING $(@F)"
+	@$(AS) $(ASFLAGS) -o $@ $<
+
+firmware: $(OBJS) $(SYS_OBJS)
+	@mkdir -p $(BIN_PATH)
+	-@echo ""
+	-@echo "LINKING $(OUTFILE).elf ($(CORE) -O$(OPTIMIZATION) $(BOARD))"
+	@$(LD) $(LDFLAGS) -o $(OUTFILE).elf $(LDLIBS) $(OBJS) $(LDLIBS)
+	-@echo ""
+	@$(SIZE) $(OUTFILE).elf
+	-@echo ""
+	-@echo "Generating $(OUTFILE).hex"
+	@$(OBJCOPY) $(OCFLAGS) -O ihex $(OUTFILE).elf $(OUTFILE).hex
+	-@echo "Generating $(OUTFILE).bin"
+	@$(OBJCOPY) $(OCFLAGS) -O binary $(OUTFILE).elf $(OUTFILE).bin
+	-@echo ""
+	@$(LPCRC) $(OUTFILE).bin
+
+flash: firmware
+	-@echo ""
+	-@echo "Flashing device ..."
+	-@[ -e "$(MOUNT_POINT)/firmware.bin" ] && dd if=bin/firmware.bin of="$(MOUNT_POINT)/firmware.bin" conv=nocreat,notrunc && umount "$(MOUNT_POINT)" || echo "Error, no device?!"
+
+lpcrc:
+	-@echo ""
+	-@echo "Building lpcrc (checksum tool) ..."
+	@make -C tools/lpcrc
+  
+clean:
+	@$(REMOVE) $(OBJS) $(OUTFILE).elf $(OUTFILE).bin $(OUTFILE).hex
+
+#########################################################################
diff --git a/reform2-lpc-fw/README.md b/reform2-lpc-fw/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..76b8118b96adc384cf2f2ebc46fa6a5244f1f3ce
--- /dev/null
+++ b/reform2-lpc-fw/README.md
@@ -0,0 +1,68 @@
+# LPC11U/LPC13U Code Base #
+
+This code base is an attempt at providing a reasonably well-organized, open-source starting point for projects based on the LPC11Uxx and LPC13Uxx family of MCUs.
+
+## Key Features ##
+
+It includes the following key features, which can be easily enabled or disabled via a single board-specific config file:
+
+- [USB CDC, HID and MSC support](https://github.com/microbuilder/LPC11U_LPC13U_Codebase/tree/master/src/core/usb), including HID Keyboard and HID Mouse emulation, with any combination of devices possible up to the number of end points available on the MCU
+- Easy to extend [command-line interface](https://github.com/microbuilder/LPC11U_LPC13U_Codebase/tree/master/src/cli) (CLI) with USB CDC and UART support
+- [Sensor abstraction layer](https://github.com/microbuilder/LPC11U_LPC13U_Codebase/tree/master/src/drivers/sensors) where all sensors return a common descriptor and data type using standardized SI units
+- Basic [localisation support](https://github.com/microbuilder/LPC11U_LPC13U_Codebase/tree/master/src/localisation), allowing multiple languages to be used in the same application
+- Graphics sub-system including support for multiple font types (bitmap or anti-aliased), basic drawing functions, and a simple HW abstraction mechanism
+- FAT16/32 file system support for SD cards including the option to use long names (via FatFS)
+- Numerous wireless stacks, including NFC (based on the PN532) and 802.15.4 (based on the AT86RF212).
+- A basic [unit testing framework](https://github.com/microbuilder/LPC11U_LPC13U_Codebase/tree/master/tests_host) suitable for embedded systems (Unity)
+
+## Supported MCUs ##
+  
+This code base is designed to work transparently with the following MCUs, allowing you to select the MCU with the right price/performance/size ratio for your project without having to rewrite any underlying code:
+
+- **LPC1347** - ARM Cortex M3, 72MHz, 64KB Flash, 8+2+2KB SRAM, 4KB EEPROM
+- **LPC11U37** - ARM Cortex M0, 50MHz, 128KB Flash, 8+2KB SRAM, 4KB EEPROM
+- **LPC11U24** - ARM Cortex M0, 50MHa, 32KB Flash, 8+2KB SRAM, 4KB EEPROM
+
+## Multiple Board Support ##
+
+In an attempt to make the code base relevant in a variety of situations, there is a basic [board abstraction layer](https://github.com/microbuilder/LPC11U_LPC13U_Codebase/tree/master/src/boards), and all config settings are board-specific.
+
+The target board in indicated in the shared **projectconfig.h** file, which in turn  references the board-specific config and initialization code in the **'boards/'** subfolder.
+
+## Supported IDEs/Toolchains ##
+
+The code base contains a few dependencies on GCC extensions (notably in the localisation system), and has not been tested with any non-GCC toolchain.
+
+At the moment the following IDEs are supported by the code base, and this list may be extended in the future:
+
+**GCC/Makefile ('Makefile')**
+
+The codebase includes startup code, linker scripts and a makefile to build this codebase with the cross-platform, open-source GNU/GCC toolset.  This gives you the most control over how your project is built, and allows you to build your project on any platform with support for GCC and make (*NIX, Mac OSX, Windows, etc.). [(more)](doc/toolchain_make.md)
+
+**LPCXpresso / Code Red IDE (.cproject/.project)**
+
+LPCXpresso is a free of charge Eclipse-based IDE based around GCC.  It's based on Code Red's commercial Red Suite IDE, but is provided free of charge by NXP Semiconductors with a debug limit up to 128Kb (you can, however, compile projects larger than this), which is within the limits of all of the chips supported by this code base.  
+
+Inexpensive LPCXpresso development boards are available with integrated SWD debuggers that can be seperated from the MCU part of the board and used to debug any supported MCU or device. [(more)](doc/toolchain_lpcxpresso.md)
+
+**Crossworks for ARM (CW\_*.hzp)**
+
+Project files are also provided for Rowley Associate's popular Crossworks for ARM IDE, which is GCC based, includes an optimised standard C library, and supports a large variety of HW debuggers (including the popular J-Link from Segger). [(more)](doc/toolchain_crossworks.md)
+
+## Current Development Status ##
+
+This code base is still in active development, and there are almost certainly a number of improvements that can be made to it, bugs that will need to be worked out, and pieces of code that could be better organized or rewritten entirely.
+
+The current localisation system is quite unsatisfactory, for example, but the decision was made to keep in in the code base in the hopes that other people will propose improvements to it, as well as to other parts of this code base.
+
+Until an initial public release is made (version 1.0), the code base should be considered unstable and some reorganisation will almost certainly continue to take place in different parts of the code.  
+
+The current code has a good overall structure, but there are still many parts that can be streamlined or reorganized (for example, reworking the UART buffer to use src/core/fifo.c instead of the older buffer from a previous code base).
+
+## How Can I Help? ##
+
+Quite a bit of time, effort and money has gone into producing this open source code base in the sole hope that it will make things easier for other people to get started with this well-rounded MCU family.  If you find the code base useful as is, the best thanks you can give is to contribute something useful back to it, and improve the current code base so that other people can learn from your efforts as well.
+
+## License ##
+
+Where possible, all code is provided under a BSD style license, but each file is individually licensed and you should ensure that you fully understand the license terms and limitations of any files you use in your project.
diff --git a/reform2-lpc-fw/changelog.md b/reform2-lpc-fw/changelog.md
new file mode 100644
index 0000000000000000000000000000000000000000..7b4a92a55c10e18ddc53498c87764a0061b3e6f5
--- /dev/null
+++ b/reform2-lpc-fw/changelog.md
@@ -0,0 +1,87 @@
+# LPC11U/LPC13U Code Base - Revision History #
+
+Major changes in the LPC11U/LPC13U code base by code base version number.
+
+## 0.9.1 [12 July 2013] ##
+
+- Fixed .bss placement in USB SRAM in linker scripts! (oops!)
+
+## 0.9.0 [12 July 2013] ##
+
+- delay.c interrupt priority changed to be one higher than the lowest level so that other interrupts can potentially be configured to use delay by setting them to the lowest level
+- sensorpoll.c added to poll sensor data at fixed intervals using 16-bit timer 1 (though care needs to be taken using this!)
+- Disabled both generic interrupt handlers in timer16.c since they are both potentially used elsewhere
+- magnetometer.c, accelerometer.c and pressure.c generic helper functions added in the sensor abstraction layer
+- Added debug.c to help with debugging in the field
+- Merged CMSIS-RTOS (RTX) updates from RTX branch ... basic test works on M3 and M0, but further testing needed
+- Added basic USB custom class support (fast bulk transfers)
+- USB HID now shares the same API as USB custom class calls to make it easier to switch
+- Various improvements to the simple binary protocol
+- Removed unity tests (/tests) to make room for ceedling native tests (/tests_host)
+- Removed Keil project files since it's too much of a headache to maintain
+- Reorganised errors.h (certains numeric values were changed)
+- Updated board config files for USB/Protocol additions
+- Added CFG\_ENABLE\_TIMER32 to disable TIMER32 (interrupt handlers use a lot of flash/SRAM)
+- CC3000 support added (experimental, see note below!)
+- Added sysinfo command to the simple binary protocol
+- Fixed a bug in iap.c (truncated serial numbers)
+- **BREAKING CHANGE**: Moved all /src/drivers/rf code to technology-specific folders ('nfc', 'wifi', etc.)
+- **KNOWN ISSUE**: There's a truckload of issues with the CC3000 API from TI!  It can't currently be built using the makefile, and is CW only at the moment. Be sure to disable CFG_CC3000 in our board config file until these issues can all be resolved!
+- **KNOWN ISSUE**: CFG\_USB\_CUSTOM\_CLASS can not be combined with any HID classes, and you must use one or the other.  This seems to be an issue with the ROM drivers and memory managed, and placing the USB memory buffer in the main 8KB block (instead of the 2KB USB SRAM block) avoids this issue, but since the buffer needs to be aligned on a 2048 byte boundary this leads to a huge waste of memory.  Investigation ongoing, but for now avoid combining CFG\_USB\_CUSTOM\_CLASS and any HID class(es).
+
+## 0.8.6 [14 June 2013] ##
+
+- Added core/timer16
+- Added core/delay (abstraction layer to use systick or timer16[0] for 1ms delays)
+- Removed core/systick and changed all systick* calls to delay* (for RTOS compatability)
+- Added flow control to uart.c
+- Added faster simple moving average filter (drivers/filters/ma/sma\_*), removed old versions
+- Added weighted moving average filter (/drivers/filters/ma/wma\_*)
+- Renamed CMSIS startup_* files to be clearer
+- Added drivers/storage/logger.c to log data to an SD card or a local file (local file is Crossworks only)
+- Updated adc.c for differences between LPC11U and LPC1347
+- Moved low power and 10-bit ADC mode settings to board config file
+- Added custom M3 RTX library (canned M3 RTX lib from ARM generated hardfault)
+- Added %f (float), %e (scientific notation) and %E (engineering notation) printf support in stdio.c (Pito)
+- **KNOWN ISSUE**: CDC still sometimes fails with heavy traffic ... active debugging in progress
+- **KNOWN ISSUE**: RTX tested under LPCXpresso, but not working under CW since startup code needs to be modified so license issues need to be resolved with Rowley
+
+## 0.8.5 [21 May 2013] ##
+
+- Updated CMSIS to v3.20
+- Renamed Crossworks project files to CW_*
+- Renamed Keil project files to Keil_*
+- Added stepper support to board config files
+- Changed the clock setup in core/adc
+- Added basic TCS34725 driver
+- First attempt at a simple binary protocol (CFG_PROTOCOL, /src/protocol)
+- Added CFG\_BRD\_SIMULATOR as a board option (mostly for unit tests)
+- Fixed negative value bug in timespanCreate
+- Renamed /src/drivers/statistics to /src/drivers/filters
+- Added some basic Python scripts to test the IIR filter
+- Updated LPCXpresso project files to use /cmsis (no more external dependencies)
+- Added int32_t iir filter and matching python scripts
+- Changed usb HID generic callbacks to be more general
+  - Replaced 'USB\_HID\_GenericReportOut\_t' and 'USB\_HID\_GenericReportIn\_t' signatures with '(uint8\_t report[] and uint32\_t length)'
+  - Affected functions are 'usb\_hid\_generic\_recv\_isr', 'usb\_hid\_generic\_report\_request\_isr', and 'usb\_hid\_generic\_send'
+- Added CMSIS DSP library to the makefile, LPCXpresso and Crossworks project files
+- Added RTX library for CMSIS-RTOS (currently untested)
+- Removed all use of GPIOSetBitValue and GPIOSetDir (wasteful fluff)
+- Added simple moving average filter and python tester
+- Improved fifo_t to support any object size (previously uint8_t only)
+- Added ceedling support (experimental)
+
+## 0.8.1 [23 April 2013] ##
+
+- 'main' entry point moved to board-specific files ('src/boards/*')
+- Removed main.c from src root
+- LPCXpresso/Red Suite project files now default to the LPC1347
+- Moved messages.c to drivers/rf/chibi
+- Removed some unnecessary files
+- Added binary.h to simplify binary access across toolchains (removed '0b' references)
+- Added 'get_fattime' to board files (get timestamp for FAT32 and SD cards)
+- Moved board selection from projectconfig.h to the make file and IDE project properties
+
+## 0.8.0 [2 April 2013] ##
+
+- First public release
diff --git a/reform2-lpc-fw/cmsis/LPC11Uxx.h b/reform2-lpc-fw/cmsis/LPC11Uxx.h
new file mode 100644
index 0000000000000000000000000000000000000000..3cb49fb06330ade46f3daa0184219ac0d2432514
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/LPC11Uxx.h
@@ -0,0 +1,668 @@
+
+/****************************************************************************************************//**
+ * @file     LPC11Uxx.h
+ *
+ *
+ * @brief    CMSIS Cortex-M0 Core Peripheral Access Layer Header File for
+ *           default LPC11Uxx Device Series
+ *
+ * @version  V0.1
+ * @date     21. March 2011
+ *
+ * @note     Generated with SFDGen V2.6 Build 3j (beta) on Thursday, 17.03.2011 13:19:45
+ *
+ *           from CMSIS SVD File 'LPC11U1x_svd.xml' Version 0.1,
+ *           created on Wednesday, 16.03.2011 20:30:42, last modified on Thursday, 17.03.2011 20:19:40
+ *
+ *******************************************************************************************************/
+
+
+
+/** @addtogroup NXP
+  * @{
+  */
+
+/** @addtogroup LPC11Uxx
+  * @{
+  */
+
+#ifndef __LPC11UXX_H__
+#define __LPC11UXX_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif 
+
+
+#if defined ( __CC_ARM   )
+  #pragma anon_unions
+#endif
+
+ /* Interrupt Number Definition */
+
+typedef enum {
+// -------------------------  Cortex-M0 Processor Exceptions Numbers  -----------------------------
+  Reset_IRQn                        = -15,  /*!<   1  Reset Vector, invoked on Power up and warm reset */
+  NonMaskableInt_IRQn               = -14,  /*!<   2  Non maskable Interrupt, cannot be stopped or preempted */
+  HardFault_IRQn                    = -13,  /*!<   3  Hard Fault, all classes of Fault */
+  SVCall_IRQn                       = -5,   /*!<  11  System Service Call via SVC instruction */
+  DebugMonitor_IRQn                 = -4,   /*!<  12  Debug Monitor                    */
+  PendSV_IRQn                       = -2,   /*!<  14  Pendable request for system service */
+  SysTick_IRQn                      = -1,   /*!<  15  System Tick Timer                */
+// ---------------------------  LPC11Uxx Specific Interrupt Numbers  ------------------------------
+FLEX_INT0_IRQn                = 0,        /*!< All I/O pins can be routed to below 8 interrupts. */
+  FLEX_INT1_IRQn                = 1,
+  FLEX_INT2_IRQn                = 2,
+  FLEX_INT3_IRQn                = 3,
+  FLEX_INT4_IRQn                = 4,   
+  FLEX_INT5_IRQn                = 5,        
+  FLEX_INT6_IRQn                = 6,        
+  FLEX_INT7_IRQn                = 7,        
+  GINT0_IRQn                    = 8,        /*!< Grouped Interrupt 0                              */
+  GINT1_IRQn                    = 9,        /*!< Grouped Interrupt 1                              */
+  Reserved0_IRQn                = 10,       /*!< Reserved Interrupt                               */
+  Reserved1_IRQn                = 11,       
+  Reserved2_IRQn                = 12,       
+  Reserved3_IRQn                = 13,       
+  SSP1_IRQn                     = 14,       /*!< SSP1 Interrupt                                   */
+  I2C_IRQn                      = 15,       /*!< I2C Interrupt                                    */
+  TIMER_16_0_IRQn               = 16,       /*!< 16-bit Timer0 Interrupt                          */
+  TIMER_16_1_IRQn               = 17,       /*!< 16-bit Timer1 Interrupt                          */
+  TIMER_32_0_IRQn               = 18,       /*!< 32-bit Timer0 Interrupt                          */
+  TIMER_32_1_IRQn               = 19,       /*!< 32-bit Timer1 Interrupt                          */
+  SSP0_IRQn                     = 20,       /*!< SSP0 Interrupt                                   */
+  UART_IRQn                     = 21,       /*!< UART Interrupt                                   */
+  USB_IRQn                      = 22,       /*!< USB IRQ Interrupt                                */
+  USB_FIQn                      = 23,       /*!< USB FIQ Interrupt                                */
+  ADC_IRQn                      = 24,       /*!< A/D Converter Interrupt                          */
+  WDT_IRQn                      = 25,       /*!< Watchdog timer Interrupt                         */  
+  BOD_IRQn                      = 26,       /*!< Brown Out Detect(BOD) Interrupt                  */
+  FMC_IRQn                      = 27,       /*!< Flash Memory Controller Interrupt                */
+  Reserved4_IRQn                = 28,       /*!< Reserved Interrupt                               */
+  Reserved5_IRQn                = 29,       /*!< Reserved Interrupt                               */
+  USBWakeup_IRQn                = 30,       /*!< USB wakeup Interrupt                             */
+  Reserved6_IRQn                = 31,       /*!< Reserved Interrupt                               */
+} IRQn_Type;
+
+
+/** @addtogroup Configuration_of_CMSIS
+  * @{
+  */
+
+/* Processor and Core Peripheral Section */ /* Configuration of the Cortex-M0 Processor and Core Peripherals */
+
+#define __MPU_PRESENT             0         /*!< MPU present or not                    */
+#define __NVIC_PRIO_BITS          2         /*!< Number of Bits used for Priority Levels */
+#define __Vendor_SysTickConfig    0         /*!< Set to 1 if different SysTick Config is used */
+/** @} */ /* End of group Configuration_of_CMSIS */
+
+#include "core_cm0.h"                       /*!< Cortex-M0 processor and core peripherals */
+#include "system_LPC11Uxx.h"                /*!< LPC11Uxx System                       */
+
+/** @addtogroup Device_Peripheral_Registers
+  * @{
+  */
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                          I2C                                         -----
+// ------------------------------------------------------------------------------------------------
+
+
+/**
+  * @brief Product name title=UM10462 Chapter title=LPC11U1x I2C-bus controller Modification date=3/16/2011 Major revision=0 Minor revision=3  (I2C)
+  */
+
+typedef struct {                            /*!< (@ 0x40000000) I2C Structure          */
+  __IO uint32_t CONSET;                     /*!< (@ 0x40000000) I2C Control Set Register */
+  __I  uint32_t STAT;                       /*!< (@ 0x40000004) I2C Status Register */
+  __IO uint32_t DAT;                        /*!< (@ 0x40000008) I2C Data Register.  */
+  __IO uint32_t ADR0;                       /*!< (@ 0x4000000C) I2C Slave Address Register 0 */
+  __IO uint32_t SCLH;                       /*!< (@ 0x40000010) SCH Duty Cycle Register High Half Word */
+  __IO uint32_t SCLL;                       /*!< (@ 0x40000014) SCL Duty Cycle Register Low Half Word */
+  __IO uint32_t CONCLR;                     /*!< (@ 0x40000018) I2C Control Clear Register*/
+  __IO uint32_t MMCTRL;                     /*!< (@ 0x4000001C) Monitor mode control register*/
+  __IO uint32_t ADR1;                       /*!< (@ 0x40000020) I2C Slave Address Register 1*/
+  __IO uint32_t ADR2;                       /*!< (@ 0x40000024) I2C Slave Address Register 2*/
+  __IO uint32_t ADR3;                       /*!< (@ 0x40000028) I2C Slave Address Register 3*/
+  __I  uint32_t DATA_BUFFER;                /*!< (@ 0x4000002C) Data buffer register */
+union{
+  __IO uint32_t MASK[4];                    /*!< (@ 0x40000030) I2C Slave address mask register */
+  struct{
+  __IO uint32_t MASK0;
+  __IO uint32_t MASK1;
+  __IO uint32_t MASK2;
+  __IO uint32_t MASK3;
+  };
+  };
+} LPC_I2C_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                         WWDT                                         -----
+// ------------------------------------------------------------------------------------------------
+
+
+/**
+  * @brief Product name title=UM10462 Chapter title=LPC11U1x Windowed Watchdog Timer (WWDT) Modification date=3/16/2011 Major revision=0 Minor revision=3  (WWDT)
+  */
+
+typedef struct {                            /*!< (@ 0x40004000) WWDT Structure         */
+  __IO uint32_t MOD;                        /*!< (@ 0x40004000) Watchdog mode register*/
+  __IO uint32_t TC;                         /*!< (@ 0x40004004) Watchdog timer constant register */
+  __IO uint32_t FEED;                       /*!< (@ 0x40004008) Watchdog feed sequence register */
+  __I  uint32_t TV;                         /*!< (@ 0x4000400C) Watchdog timer value register */
+  __IO uint32_t CLKSEL;                     /*!< (@ 0x40004010) Watchdog clock select register. */
+  __IO uint32_t WARNINT;                    /*!< (@ 0x40004014) Watchdog Warning Interrupt compare value. */
+  __IO uint32_t WINDOW;                     /*!< (@ 0x40004018) Watchdog Window compare value. */
+} LPC_WWDT_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                         USART                                        -----
+// ------------------------------------------------------------------------------------------------
+
+
+/**
+  * @brief Product name title=UM10462 Chapter title=LPC11U1x USART Modification date=3/16/2011 Major revision=0 Minor revision=3  (USART)
+  */
+
+typedef struct {                            /*!< (@ 0x40008000) USART Structure        */
+  
+  union {
+    __IO uint32_t DLL;                      /*!< (@ 0x40008000) Divisor Latch LSB. Least significant byte of the baud rate divisor value. The full divisor is used to generate a baud rate from the fractional rate divider. (DLAB=1) */
+    __O  uint32_t THR;                      /*!< (@ 0x40008000) Transmit Holding Register. The next character to be transmitted is written here. (DLAB=0) */
+    __I  uint32_t RBR;                      /*!< (@ 0x40008000) Receiver Buffer Register. Contains the next received character to be read. (DLAB=0) */
+  };
+  
+  union {
+    __IO uint32_t IER;                      /*!< (@ 0x40008004) Interrupt Enable Register. Contains individual interrupt enable bits for the 7 potential USART interrupts. (DLAB=0) */
+    __IO uint32_t DLM;                      /*!< (@ 0x40008004) Divisor Latch MSB. Most significant byte of the baud rate divisor value. The full divisor is used to generate a baud rate from the fractional rate divider. (DLAB=1) */
+  };
+  
+  union {
+    __O  uint32_t FCR;                      /*!< (@ 0x40008008) FIFO Control Register. Controls USART FIFO usage and modes. */
+    __I  uint32_t IIR;                      /*!< (@ 0x40008008) Interrupt ID Register. Identifies which interrupt(s) are pending. */
+  };
+  __IO uint32_t LCR;                        /*!< (@ 0x4000800C) Line Control Register. Contains controls for frame formatting and break generation. */
+  __IO uint32_t MCR;                        /*!< (@ 0x40008010) Modem Control Register. */
+  __I  uint32_t LSR;                        /*!< (@ 0x40008014) Line Status Register. Contains flags for transmit and receive status, including line errors. */
+  __I  uint32_t MSR;                        /*!< (@ 0x40008018) Modem Status Register. */
+  __IO uint32_t SCR;                        /*!< (@ 0x4000801C) Scratch Pad Register. Eight-bit temporary storage for software. */
+  __IO uint32_t ACR;                        /*!< (@ 0x40008020) Auto-baud Control Register. Contains controls for the auto-baud feature. */
+  __IO uint32_t ICR;                        /*!< (@ 0x40008024) IrDA Control Register. Enables and configures the IrDA (remote control) mode. */
+  __IO uint32_t FDR;                        /*!< (@ 0x40008028) Fractional Divider Register. Generates a clock input for the baud rate divider. */
+  __IO uint32_t OSR;                        /*!< (@ 0x4000802C) Oversampling Register. Controls the degree of oversampling during each bit time. */
+  __IO uint32_t TER;                        /*!< (@ 0x40008030) Transmit Enable Register. Turns off USART transmitter for use with software flow control. */
+  __I  uint32_t RESERVED0[3];
+  __IO uint32_t HDEN;                       /*!< (@ 0x40008040) Half duplex enable register. */
+  __I  uint32_t RESERVED1;
+  __IO uint32_t SCICTRL;                    /*!< (@ 0x40008048) Smart Card Interface Control register. Enables and configures the Smart Card Interface feature. */
+  __IO uint32_t RS485CTRL;                  /*!< (@ 0x4000804C) RS-485/EIA-485 Control. Contains controls to configure various aspects of RS-485/EIA-485 modes. */
+  __IO uint32_t RS485ADRMATCH;              /*!< (@ 0x40008050) RS-485/EIA-485 address match. Contains the address match value for RS-485/EIA-485 mode. */
+  __IO uint32_t RS485DLY;                   /*!< (@ 0x40008054) RS-485/EIA-485 direction control delay. */
+  __IO uint32_t SYNCCTRL; 
+} LPC_USART_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                        Timer                                       -----
+// ------------------------------------------------------------------------------------------------
+
+
+/**
+  * @brief Product name title=UM10462 Chapter title=LPC11U1x 32-bitcounter/timers CT32B0/1 Modification date=3/16/2011 Major revision=0 Minor revision=3  
+  */
+
+typedef struct {                            /*!< (@ 0x40014000) CT32B0 Structure        */
+  __IO uint32_t IR;                         /*!< (@ 0x40014000) Interrupt Register      */
+  __IO uint32_t TCR;                        /*!< (@ 0x40014004) Timer Control Register  */
+  __IO uint32_t TC;                         /*!< (@ 0x40014008) Timer Counter 		*/
+  __IO uint32_t PR;                         /*!< (@ 0x4001400C) Prescale Register  	*/
+  __IO uint32_t PC;                         /*!< (@ 0x40014010) Prescale Counter	 */
+  __IO uint32_t MCR;                        /*!< (@ 0x40014014) Match Control Register */
+  union {
+  __IO uint32_t MR[4];                      /*!< (@ 0x40014018) Match Register */
+  struct{
+  __IO uint32_t MR0;                        /*!< (@ 0x40018018) Match Register. MR0 */
+  __IO uint32_t MR1;                        /*!< (@ 0x4001801C) Match Register. MR1 */
+  __IO uint32_t MR2;                        /*!< (@ 0x40018020) Match Register. MR2 */
+  __IO uint32_t MR3;                        /*!< (@ 0x40018024) Match Register. MR3 */
+  };
+  };
+  __IO uint32_t CCR;                        /*!< (@ 0x40014028) Capture Control Register */
+  union{
+  __I  uint32_t CR[4];                      /*!< (@ 0x4001402C) Capture Register  */
+    struct{
+  __I  uint32_t CR0;			    /*!< (@ 0x4001802C) Capture Register. CR 0 */
+  __I  uint32_t CR1;			    /*!< (@ 0x40018030) Capture Register. CR 1 */
+  __I  uint32_t CR2;			    /*!< (@ 0x40018034) Capture Register. CR 2 */
+  __I  uint32_t CR3;			    /*!< (@ 0x40018038) Capture Register. CR 3 */
+  };
+  };
+__IO uint32_t EMR;                        /*!< (@ 0x4001403C) External Match Register */
+  __I  uint32_t RESERVED0[12];
+  __IO uint32_t CTCR;                       /*!< (@ 0x40014070) Count Control Register */
+  __IO uint32_t PWMC;                       /*!< (@ 0x40014074) PWM Control Register */
+} LPC_CTxxBx_Type;
+
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                          ADC                                         -----
+// ------------------------------------------------------------------------------------------------
+
+
+/**
+  * @brief Product name title=UM10462 Chapter title=LPC11U1x ADC Modification date=3/16/2011 Major revision=0 Minor revision=3  (ADC)
+  */
+
+typedef struct {                            /*!< (@ 0x4001C000) ADC Structure          */
+  __IO uint32_t CR;                         /*!< (@ 0x4001C000) A/D Control Register */
+  __IO uint32_t GDR;                        /*!< (@ 0x4001C004) A/D Global Data Register */
+  __I  uint32_t RESERVED0[1];
+  __IO uint32_t INTEN;                      /*!< (@ 0x4001C00C) A/D Interrupt Enable Register */
+  union{
+  __I  uint32_t DR[8];                      /*!< (@ 0x4001C010) A/D Channel Data Register*/
+    struct{
+  __IO uint32_t DR0;                      	/*!< (@ 0x40020010) A/D Channel Data Register 0*/
+  __IO uint32_t DR1;                      	/*!< (@ 0x40020014) A/D Channel Data Register 1*/
+  __IO uint32_t DR2;                      	/*!< (@ 0x40020018) A/D Channel Data Register 2*/
+  __IO uint32_t DR3;                      	/*!< (@ 0x4002001C) A/D Channel Data Register 3*/
+  __IO uint32_t DR4;                      	/*!< (@ 0x40020020) A/D Channel Data Register 4*/
+  __IO uint32_t DR5;                      	/*!< (@ 0x40020024) A/D Channel Data Register 5*/
+  __IO uint32_t DR6;                      	/*!< (@ 0x40020028) A/D Channel Data Register 6*/
+  __IO uint32_t DR7;                      	/*!< (@ 0x4002002C) A/D Channel Data Register 7*/
+  };
+  };
+  __I  uint32_t STAT;                       /*!< (@ 0x4001C030) A/D Status Register.  */
+} LPC_ADC_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                          PMU                                         -----
+// ------------------------------------------------------------------------------------------------
+
+
+/**
+  * @brief Product name title=UM10462 Chapter title=LPC11U1x Power Management Unit (PMU) Modification date=3/16/2011 Major revision=0 Minor revision=3  (PMU)
+  */
+
+typedef struct {                            /*!< (@ 0x40038000) PMU Structure          */
+  __IO uint32_t PCON;                       /*!< (@ 0x40038000) Power control register */
+  union{
+  __IO uint32_t GPREG[4];                   /*!< (@ 0x40038004) General purpose register 0 */
+  struct{
+  __IO uint32_t GPREG0;                   	/*!< (@ 0x40038004) General purpose register 0 */
+  __IO uint32_t GPREG1;                   	/*!< (@ 0x40038008) General purpose register 1 */
+  __IO uint32_t GPREG2;                   	/*!< (@ 0x4003800C) General purpose register 2 */
+  __IO uint32_t GPREG3;                   	/*!< (@ 0x40038010) General purpose register 3 */
+  };
+  };
+} LPC_PMU_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                       FLASHCTRL                                      -----
+// ------------------------------------------------------------------------------------------------
+
+
+/**
+  * @brief Product name title=UM10462 Chapter title=LPC11U1x Flash programming firmware Modification date=3/17/2011 Major revision=0 Minor revision=3  (FLASHCTRL)
+  */
+
+typedef struct {                            /*!< (@ 0x4003C000) FLASHCTRL Structure    */
+  __I  uint32_t RESERVED0[4];
+  __IO uint32_t FLASHCFG;                   /*!< (@ 0x4003C010) Flash memory access time configuration register */
+  __I  uint32_t RESERVED1[3];
+  __IO uint32_t FMSSTART;                   /*!< (@ 0x4003C020) Signature start address register */
+  __IO uint32_t FMSSTOP;                    /*!< (@ 0x4003C024) Signature stop-address register */
+  __I  uint32_t RESERVED2[1];
+  __I  uint32_t FMSW0;                      /*!< (@ 0x4003C02C) Word 0 [31:0]          */
+  __I  uint32_t FMSW1;                      /*!< (@ 0x4003C030) Word 1 [63:32]         */
+  __I  uint32_t FMSW2;                      /*!< (@ 0x4003C034) Word 2 [95:64]         */
+  __I  uint32_t FMSW3;                      /*!< (@ 0x4003C038) Word 3 [127:96]        */
+  __I  uint32_t RESERVED3[1001];
+  __I  uint32_t FMSTAT;                     /*!< (@ 0x4003CFE0) Signature generation status register */
+  __I  uint32_t RESERVED4[1];
+  __IO uint32_t FMSTATCLR;                  /*!< (@ 0x4003CFE8) Signature generation status clear register */
+} LPC_FLASHCTRL_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                         SSP0/1                                         -----
+// ------------------------------------------------------------------------------------------------
+
+
+/**
+  * @brief Product name title=UM10462 Chapter title=LPC11U1x SSP/SPI Modification date=3/16/2011 Major revision=0 Minor revision=3  (SSP0)
+  */
+
+typedef struct {                            /*!< (@ 0x40040000) SSP0 Structure         */
+  __IO uint32_t CR0;                        /*!< (@ 0x40040000) Control Register 0. Selects the serial clock rate, bus type, and data size. */
+  __IO uint32_t CR1;                        /*!< (@ 0x40040004) Control Register 1. Selects master/slave and other modes. */
+  __IO uint32_t DR;                         /*!< (@ 0x40040008) Data Register. Writes fill the transmit FIFO, and reads empty the receive FIFO. */
+  __I  uint32_t SR;                         /*!< (@ 0x4004000C) Status Register        */
+  __IO uint32_t CPSR;                       /*!< (@ 0x40040010) Clock Prescale Register */
+  __IO uint32_t IMSC;                       /*!< (@ 0x40040014) Interrupt Mask Set and Clear Register */
+  __I  uint32_t RIS;                        /*!< (@ 0x40040018) Raw Interrupt Status Register */
+  __I  uint32_t MIS;                        /*!< (@ 0x4004001C) Masked Interrupt Status Register */
+  __IO uint32_t ICR;                        /*!< (@ 0x40040020) SSPICR Interrupt Clear Register */
+} LPC_SSPx_Type;
+
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                       IOCONFIG                                       -----
+// ------------------------------------------------------------------------------------------------
+
+
+/**
+  * @brief Product name title=UM10462 Chapter title=LPC11U1x I/O configuration Modification date=3/16/2011 Major revision=0 Minor revision=3  (IOCONFIG)
+  */
+
+typedef struct {                            /*!< (@ 0x40044000) IOCONFIG Structure     */
+  __IO uint32_t RESET_PIO0_0;               /*!< (@ 0x40044000) I/O configuration for pin RESET/PIO0_0 */
+  __IO uint32_t PIO0_1;                     /*!< (@ 0x40044004) I/O configuration for pin PIO0_1/CLKOUT/CT32B0_MAT2/USB_FTOGGLE */
+  __IO uint32_t PIO0_2;                     /*!< (@ 0x40044008) I/O configuration for pin PIO0_2/SSEL0/CT16B0_CAP0 */
+  __IO uint32_t PIO0_3;                     /*!< (@ 0x4004400C) I/O configuration for pin PIO0_3/USB_VBUS */
+  __IO uint32_t PIO0_4;                     /*!< (@ 0x40044010) I/O configuration for pin PIO0_4/SCL */
+  __IO uint32_t PIO0_5;                     /*!< (@ 0x40044014) I/O configuration for pin PIO0_5/SDA */
+  __IO uint32_t PIO0_6;                     /*!< (@ 0x40044018) I/O configuration for pin PIO0_6/USB_CONNECT/SCK0 */
+  __IO uint32_t PIO0_7;                     /*!< (@ 0x4004401C) I/O configuration for pin PIO0_7/CTS */
+  __IO uint32_t PIO0_8;                     /*!< (@ 0x40044020) I/O configuration for pin PIO0_8/MISO0/CT16B0_MAT0 */
+  __IO uint32_t PIO0_9;                     /*!< (@ 0x40044024) I/O configuration for pin PIO0_9/MOSI0/CT16B0_MAT1 */
+  __IO uint32_t SWCLK_PIO0_10;              /*!< (@ 0x40044028) I/O configuration for pin SWCLK/PIO0_10/ SCK0/CT16B0_MAT2 */
+  __IO uint32_t TDI_PIO0_11;                /*!< (@ 0x4004402C) I/O configuration for pin TDI/PIO0_11/AD0/CT32B0_MAT3 */
+  __IO uint32_t TMS_PIO0_12;                /*!< (@ 0x40044030) I/O configuration for pin TMS/PIO0_12/AD1/CT32B1_CAP0 */
+  __IO uint32_t TDO_PIO0_13;                /*!< (@ 0x40044034) I/O configuration for pin TDO/PIO0_13/AD2/CT32B1_MAT0 */
+  __IO uint32_t TRST_PIO0_14;               /*!< (@ 0x40044038) I/O configuration for pin TRST/PIO0_14/AD3/CT32B1_MAT1 */
+  __IO uint32_t SWDIO_PIO0_15;              /*!< (@ 0x4004403C) I/O configuration for pin SWDIO/PIO0_15/AD4/CT32B1_MAT2 */
+  __IO uint32_t PIO0_16;                    /*!< (@ 0x40044040) I/O configuration for pin PIO0_16/AD5/CT32B1_MAT3/ WAKEUP */
+  __IO uint32_t PIO0_17;                    /*!< (@ 0x40044044) I/O configuration for pin PIO0_17/RTS/CT32B0_CAP0/SCLK */
+  __IO uint32_t PIO0_18;                    /*!< (@ 0x40044048) I/O configuration for pin PIO0_18/RXD/CT32B0_MAT0 */
+  __IO uint32_t PIO0_19;                    /*!< (@ 0x4004404C) I/O configuration for pin PIO0_19/TXD/CT32B0_MAT1 */
+  __IO uint32_t PIO0_20;                    /*!< (@ 0x40044050) I/O configuration for pin PIO0_20/CT16B1_CAP0 */
+  __IO uint32_t PIO0_21;                    /*!< (@ 0x40044054) I/O configuration for pin PIO0_21/CT16B1_MAT0/MOSI1 */
+  __IO uint32_t PIO0_22;                    /*!< (@ 0x40044058) I/O configuration for pin PIO0_22/AD6/CT16B1_MAT1/MISO1 */
+  __IO uint32_t PIO0_23;                    /*!< (@ 0x4004405C) I/O configuration for pin PIO0_23/AD7 */
+  __IO uint32_t PIO1_0;                 /*!< Offset: 0x060 */
+  __IO uint32_t PIO1_1;         
+  __IO uint32_t PIO1_2;       
+  __IO uint32_t PIO1_3;      
+  __IO uint32_t PIO1_4;                 /*!< Offset: 0x070 */
+  __IO uint32_t PIO1_5;                     /*!< (@ 0x40044074) I/O configuration for pin PIO1_5/CT32B1_CAP1 */
+  __IO uint32_t PIO1_6;     
+  __IO uint32_t PIO1_7;       
+  __IO uint32_t PIO1_8;                 /*!< Offset: 0x080 */
+  __IO uint32_t PIO1_9;        
+  __IO uint32_t PIO1_10;        
+  __IO uint32_t PIO1_11;       
+  __IO uint32_t PIO1_12;                /*!< Offset: 0x090 */
+  __IO uint32_t PIO1_13;                    /*!< (@ 0x40044094) I/O configuration for pin PIO1_13/DTR/CT16B0_MAT0/TXD */
+  __IO uint32_t PIO1_14;                    /*!< (@ 0x40044098) I/O configuration for pin PIO1_14/DSR/CT16B0_MAT1/RXD */
+  __IO uint32_t PIO1_15;                    /*!< (@ 0x4004409C) I/O configuration for pin PIO1_15/DCD/ CT16B0_MAT2/SCK1 */
+  __IO uint32_t PIO1_16;                    /*!< (@ 0x400440A0) I/O configuration for pin PIO1_16/RI/CT16B0_CAP0 */
+  __IO uint32_t PIO1_17;
+  __IO uint32_t PIO1_18;
+  __IO uint32_t PIO1_19;                    /*!< (@ 0x400440AC) I/O configuration for pin PIO1_19/DTR/SSEL1 */
+  __IO uint32_t PIO1_20;                    /*!< (@ 0x400440B0) I/O configuration for pin PIO1_20/DSR/SCK1 */
+  __IO uint32_t PIO1_21;                    /*!< (@ 0x400440B4) I/O configuration for pin PIO1_21/DCD/MISO1 */
+  __IO uint32_t PIO1_22;                    /*!< (@ 0x400440B8) I/O configuration for pin PIO1_22/RI/MOSI1 */
+  __IO uint32_t PIO1_23;                    /*!< (@ 0x400440BC) I/O configuration for pin PIO1_23/CT16B1_MAT1/SSEL1 */
+  __IO uint32_t PIO1_24;                    /*!< (@ 0x400440C0) I/O configuration for pin PIO1_24/ CT32B0_MAT0 */
+  __IO uint32_t PIO1_25;                    /*!< (@ 0x400440C4) I/O configuration for pin PIO1_25/CT32B0_MAT1 */
+  __IO uint32_t PIO1_26;                    /*!< (@ 0x400440C8) I/O configuration for pin PIO1_26/CT32B0_MAT2/ RXD */
+  __IO uint32_t PIO1_27;                    /*!< (@ 0x400440CC) I/O configuration for pin PIO1_27/CT32B0_MAT3/ TXD */
+  __IO uint32_t PIO1_28;                    /*!< (@ 0x400440D0) I/O configuration for pin PIO1_28/CT32B0_CAP0/ SCLK */
+  __IO uint32_t PIO1_29;                    /*!< (@ 0x400440D4) I/O configuration for pin PIO1_29/SCK0/ CT32B0_CAP1 */
+  __IO uint32_t PIO1_30;
+  __IO uint32_t PIO1_31;                    /*!< (@ 0x400440DC) I/O configuration for pin PIO1_31 */
+} LPC_IOCON_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                        SYSCON                                        -----
+// ------------------------------------------------------------------------------------------------
+
+
+/**
+  * @brief Product name title=UM10462 Chapter title=LPC11U1x System control block Modification date=3/16/2011 Major revision=0 Minor revision=3  (SYSCON)
+  */
+
+typedef struct {                            /*!< (@ 0x40048000) SYSCON Structure       */
+  __IO uint32_t SYSMEMREMAP;                /*!< (@ 0x40048000) System memory remap    */
+  __IO uint32_t PRESETCTRL;                 /*!< (@ 0x40048004) Peripheral reset control */
+  __IO uint32_t SYSPLLCTRL;                 /*!< (@ 0x40048008) System PLL control     */
+  __I  uint32_t SYSPLLSTAT;                 /*!< (@ 0x4004800C) System PLL status      */
+  __IO uint32_t USBPLLCTRL;                 /*!< (@ 0x40048010) USB PLL control        */
+  __I  uint32_t USBPLLSTAT;                 /*!< (@ 0x40048014) USB PLL status         */
+  __I  uint32_t RESERVED0[2];
+  __IO uint32_t SYSOSCCTRL;                 /*!< (@ 0x40048020) System oscillator control */
+  __IO uint32_t WDTOSCCTRL;                 /*!< (@ 0x40048024) Watchdog oscillator control */
+  __I  uint32_t RESERVED1[2];
+  __IO uint32_t SYSRSTSTAT;                 /*!< (@ 0x40048030) System reset status register */
+  __I  uint32_t RESERVED2[3];
+  __IO uint32_t SYSPLLCLKSEL;               /*!< (@ 0x40048040) System PLL clock source select */
+  __IO uint32_t SYSPLLCLKUEN;               /*!< (@ 0x40048044) System PLL clock source update enable */
+  __IO uint32_t USBPLLCLKSEL;               /*!< (@ 0x40048048) USB PLL clock source select */
+  __IO uint32_t USBPLLCLKUEN;               /*!< (@ 0x4004804C) USB PLL clock source update enable */
+  __I  uint32_t RESERVED3[8];
+  __IO uint32_t MAINCLKSEL;                 /*!< (@ 0x40048070) Main clock source select */
+  __IO uint32_t MAINCLKUEN;                 /*!< (@ 0x40048074) Main clock source update enable */
+  __IO uint32_t SYSAHBCLKDIV;               /*!< (@ 0x40048078) System clock divider   */
+  __I  uint32_t RESERVED4[1];
+  __IO uint32_t SYSAHBCLKCTRL;              /*!< (@ 0x40048080) System clock control   */
+  __I  uint32_t RESERVED5[4];
+  __IO uint32_t SSP0CLKDIV;                 /*!< (@ 0x40048094) SSP0 clock divider     */
+  __IO uint32_t UARTCLKDIV;                 /*!< (@ 0x40048098) UART clock divider     */
+  __IO uint32_t SSP1CLKDIV;                 /*!< (@ 0x4004809C) SSP1 clock divider     */
+  __I  uint32_t RESERVED6[8];
+  __IO uint32_t USBCLKSEL;                  /*!< (@ 0x400480C0) USB clock source select */
+  __IO uint32_t USBCLKUEN;                  /*!< (@ 0x400480C4) USB clock source update enable */
+  __IO uint32_t USBCLKDIV;                  /*!< (@ 0x400480C8) USB clock source divider */
+  __I  uint32_t RESERVED7[5];
+  __IO uint32_t CLKOUTSEL;                  /*!< (@ 0x400480E0) CLKOUT clock source select */
+  __IO uint32_t CLKOUTUEN;                  /*!< (@ 0x400480E4) CLKOUT clock source update enable */
+  __IO uint32_t CLKOUTDIV;                  /*!< (@ 0x400480E8) CLKOUT clock divider   */
+  __I  uint32_t RESERVED8[5];
+  __I  uint32_t PIOPORCAP0;                 /*!< (@ 0x40048100) POR captured PIO status 0 */
+  __I  uint32_t PIOPORCAP1;                 /*!< (@ 0x40048104) POR captured PIO status 1 */
+  __I  uint32_t RESERVED9[18];
+  __IO uint32_t BODCTRL;                    /*!< (@ 0x40048150) Brown-Out Detect       */
+  __IO uint32_t SYSTCKCAL;                  /*!< (@ 0x40048154) System tick counter calibration */
+  __I  uint32_t RESERVED10[6];
+  __IO uint32_t IRQLATENCY;                 /*!< (@ 0x40048170) IQR delay */
+  __IO uint32_t NMISRC;                     /*!< (@ 0x40048174) NMI Source Control     */
+  __IO uint32_t PINTSEL[8];                 /*!< (@ 0x40048178) GPIO Pin Interrupt Select register 0 */
+  __IO uint32_t USBCLKCTRL;                 /*!< (@ 0x40048198) USB clock control      */
+  __I  uint32_t USBCLKST;                   /*!< (@ 0x4004819C) USB clock status       */
+  __I  uint32_t RESERVED11[25];
+  __IO uint32_t STARTERP0;                  /*!< (@ 0x40048204) Start logic 0 interrupt wake-up enable register 0 */
+  __I  uint32_t RESERVED12[3];
+  __IO uint32_t STARTERP1;                  /*!< (@ 0x40048214) Start logic 1 interrupt wake-up enable register 1 */
+  __I  uint32_t RESERVED13[6];
+  __IO uint32_t PDSLEEPCFG;                 /*!< (@ 0x40048230) Power-down states in deep-sleep mode */
+  __IO uint32_t PDAWAKECFG;                 /*!< (@ 0x40048234) Power-down states for wake-up from deep-sleep */
+  __IO uint32_t PDRUNCFG;                   /*!< (@ 0x40048238) Power configuration register */
+  __I  uint32_t RESERVED14[110];
+  __I  uint32_t DEVICE_ID;                  /*!< (@ 0x400483F4) Device ID              */
+} LPC_SYSCON_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                     GPIO_PIN_INT                                     -----
+// ------------------------------------------------------------------------------------------------
+
+
+/**
+  * @brief Product name title=UM10462 Chapter title=LPC11U1x GPIO Modification date=3/17/2011 Major revision=0 Minor revision=3  (GPIO_PIN_INT)
+  */
+
+typedef struct {                            /*!< (@ 0x4004C000) GPIO_PIN_INT Structure */
+  __IO uint32_t ISEL;                       /*!< (@ 0x4004C000) Pin Interrupt Mode register */
+  __IO uint32_t IENR;                       /*!< (@ 0x4004C004) Pin Interrupt Enable (Rising) register */
+  __IO uint32_t SIENR;                      /*!< (@ 0x4004C008) Set Pin Interrupt Enable (Rising) register */
+  __IO uint32_t CIENR;                      /*!< (@ 0x4004C00C) Clear Pin Interrupt Enable (Rising) register */
+  __IO uint32_t IENF;                       /*!< (@ 0x4004C010) Pin Interrupt Enable Falling Edge / Active Level register */
+  __IO uint32_t SIENF;                      /*!< (@ 0x4004C014) Set Pin Interrupt Enable Falling Edge / Active Level register */
+  __IO uint32_t CIENF;                      /*!< (@ 0x4004C018) Clear Pin Interrupt Enable Falling Edge / Active Level address */
+  __IO uint32_t RISE;                       /*!< (@ 0x4004C01C) Pin Interrupt Rising Edge register */
+  __IO uint32_t FALL;                       /*!< (@ 0x4004C020) Pin Interrupt Falling Edge register */
+  __IO uint32_t IST;                        /*!< (@ 0x4004C024) Pin Interrupt Status register */
+} LPC_GPIO_PIN_INT_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                    GPIO_GROUP_INT0/1                                   -----
+// ------------------------------------------------------------------------------------------------
+
+
+/**
+  * @brief Product name title=UM10462 Chapter title=LPC11U1x GPIO Modification date=3/17/2011 Major revision=0 Minor revision=3  (GPIO_GROUP_INT0)
+  */
+
+typedef struct {                            /*!< (@ 0x4005C000) GPIO_GROUP_INT0 Structure */
+  __IO uint32_t CTRL;                       /*!< (@ 0x4005C000) GPIO grouped interrupt control register */
+  __I  uint32_t RESERVED0[7];
+  __IO uint32_t PORT_POL[2];                /*!< (@ 0x4005C020) GPIO grouped interrupt port 0 polarity register */
+  __I  uint32_t RESERVED1[6];
+  __IO uint32_t PORT_ENA[2];                /*!< (@ 0x4005C040) GPIO grouped interrupt port 0/1 enable register */
+} LPC_GPIO_GROUP_INTx_Type;
+
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                          USB                                         -----
+// ------------------------------------------------------------------------------------------------
+
+
+/**
+  * @brief Product name title=UM10462 Chapter title=LPC11U1x USB2.0device controller Modification date=3/16/2011 Major revision=0 Minor revision=3  (USB)
+  */
+
+typedef struct {                            /*!< (@ 0x40080000) USB Structure          */
+  __IO uint32_t DEVCMDSTAT;                 /*!< (@ 0x40080000) USB Device Command/Status register */
+  __IO uint32_t INFO;                       /*!< (@ 0x40080004) USB Info register      */
+  __IO uint32_t EPLISTSTART;                /*!< (@ 0x40080008) USB EP Command/Status List start address */
+  __IO uint32_t DATABUFSTART;               /*!< (@ 0x4008000C) USB Data buffer start address */
+  __IO uint32_t LPM;                        /*!< (@ 0x40080010) Link Power Management register */
+  __IO uint32_t EPSKIP;                     /*!< (@ 0x40080014) USB Endpoint skip      */
+  __IO uint32_t EPINUSE;                    /*!< (@ 0x40080018) USB Endpoint Buffer in use */
+  __IO uint32_t EPBUFCFG;                   /*!< (@ 0x4008001C) USB Endpoint Buffer Configuration register */
+  __IO uint32_t INTSTAT;                    /*!< (@ 0x40080020) USB interrupt status register */
+  __IO uint32_t INTEN;                      /*!< (@ 0x40080024) USB interrupt enable register */
+  __IO uint32_t INTSETSTAT;                 /*!< (@ 0x40080028) USB set interrupt status register */
+  __IO uint32_t INTROUTING;                 /*!< (@ 0x4008002C) USB interrupt routing register */
+  __I  uint32_t RESERVED0[1];
+  __I  uint32_t EPTOGGLE;                   /*!< (@ 0x40080034) USB Endpoint toggle register */
+} LPC_USB_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                       GPIO_PORT                                      -----
+// ------------------------------------------------------------------------------------------------
+
+
+/**
+  * @brief Product name title=UM10462 Chapter title=LPC11U1x GPIO Modification date=3/17/2011 Major revision=0 Minor revision=3  (GPIO_PORT)
+  */
+
+typedef struct {                            
+  union {
+    struct {
+      __IO uint8_t B0[32];                       /*!< (@ 0x50000000) Byte pin registers port 0; pins PIO0_0 to PIO0_31 */
+      __IO uint8_t B1[32];                       /*!< (@ 0x50000020) Byte pin registers port 1 */
+    };
+    __IO uint8_t B[64];                       /*!< (@ 0x50000000) Byte pin registers port 0/1 */
+  };
+  __I  uint32_t RESERVED0[1008];
+  union {
+    struct {
+      __IO uint32_t W0[32];                      /*!< (@ 0x50001000) Word pin registers port 0 */
+      __IO uint32_t W1[32];                      /*!< (@ 0x50001080) Word pin registers port 1 */
+    };
+    __IO uint32_t W[64];                       /*!< (@ 0x50001000) Word pin registers port 0/1 */
+  };
+       uint32_t RESERVED1[960];
+  __IO uint32_t DIR[2];			/* 0x2000 */
+       uint32_t RESERVED2[30];
+  __IO uint32_t MASK[2];		/* 0x2080 */
+       uint32_t RESERVED3[30];
+  __IO uint32_t PIN[2];			/* 0x2100 */
+       uint32_t RESERVED4[30];
+  __IO uint32_t MPIN[2];		/* 0x2180 */
+       uint32_t RESERVED5[30];
+  __IO uint32_t SET[2];			/* 0x2200 */
+       uint32_t RESERVED6[30];
+  __O  uint32_t CLR[2];			/* 0x2280 */
+       uint32_t RESERVED7[30];
+  __O  uint32_t NOT[2];			/* 0x2300 */
+} LPC_GPIO_Type;
+
+
+#if defined ( __CC_ARM   )
+  #pragma no_anon_unions
+#endif
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                 Peripheral memory map                                -----
+// ------------------------------------------------------------------------------------------------
+
+#define LPC_I2C_BASE              (0x40000000)
+#define LPC_WWDT_BASE             (0x40004000)
+#define LPC_USART_BASE            (0x40008000)
+#define LPC_CT16B0_BASE           (0x4000C000)
+#define LPC_CT16B1_BASE           (0x40010000)
+#define LPC_CT32B0_BASE           (0x40014000)
+#define LPC_CT32B1_BASE           (0x40018000)
+#define LPC_ADC_BASE              (0x4001C000)
+#define LPC_PMU_BASE              (0x40038000)
+#define LPC_FLASHCTRL_BASE        (0x4003C000)
+#define LPC_SSP0_BASE             (0x40040000)
+#define LPC_SSP1_BASE             (0x40058000)
+#define LPC_IOCON_BASE            (0x40044000)
+#define LPC_SYSCON_BASE           (0x40048000)
+#define LPC_GPIO_PIN_INT_BASE     (0x4004C000)
+#define LPC_GPIO_GROUP_INT0_BASE  (0x4005C000)
+#define LPC_GPIO_GROUP_INT1_BASE  (0x40060000)
+#define LPC_USB_BASE              (0x40080000)
+#define LPC_GPIO_BASE             (0x50000000)
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                Peripheral declaration                                -----
+// ------------------------------------------------------------------------------------------------
+
+#define LPC_I2C                   ((LPC_I2C_Type            *) LPC_I2C_BASE)
+#define LPC_WWDT                  ((LPC_WWDT_Type           *) LPC_WWDT_BASE)
+#define LPC_USART                 ((LPC_USART_Type          *) LPC_USART_BASE)
+#define LPC_CT16B0                ((LPC_CTxxBx_Type         *) LPC_CT16B0_BASE)
+#define LPC_CT16B1                ((LPC_CTxxBx_Type         *) LPC_CT16B1_BASE)
+#define LPC_CT32B0                ((LPC_CTxxBx_Type         *) LPC_CT32B0_BASE)
+#define LPC_CT32B1                ((LPC_CTxxBx_Type         *) LPC_CT32B1_BASE)
+#define LPC_ADC                   ((LPC_ADC_Type            *) LPC_ADC_BASE)
+#define LPC_PMU                   ((LPC_PMU_Type            *) LPC_PMU_BASE)
+#define LPC_FLASHCTRL             ((LPC_FLASHCTRL_Type      *) LPC_FLASHCTRL_BASE)
+#define LPC_SSP0                  ((LPC_SSPx_Type           *) LPC_SSP0_BASE)
+#define LPC_SSP1                  ((LPC_SSPx_Type           *) LPC_SSP1_BASE)
+#define LPC_IOCON                 ((LPC_IOCON_Type          *) LPC_IOCON_BASE)
+#define LPC_SYSCON                ((LPC_SYSCON_Type         *) LPC_SYSCON_BASE)
+#define LPC_GPIO_PIN_INT          ((LPC_GPIO_PIN_INT_Type   *) LPC_GPIO_PIN_INT_BASE)
+#define LPC_GPIO_GROUP_INT0       ((LPC_GPIO_GROUP_INTx_Type*) LPC_GPIO_GROUP_INT0_BASE)
+#define LPC_GPIO_GROUP_INT1       ((LPC_GPIO_GROUP_INTx_Type*) LPC_GPIO_GROUP_INT1_BASE)
+#define LPC_USB                   ((LPC_USB_Type            *) LPC_USB_BASE)
+#define LPC_GPIO                  ((LPC_GPIO_Type           *) LPC_GPIO_BASE)
+
+
+/** @} */ /* End of group Device_Peripheral_Registers */
+/** @} */ /* End of group (null) */
+/** @} */ /* End of group LPC11Uxx */
+
+#ifdef __cplusplus
+}
+#endif 
+
+
+#endif  // __LPC11UXX_H__
diff --git a/reform2-lpc-fw/cmsis/LPC13Uxx.h b/reform2-lpc-fw/cmsis/LPC13Uxx.h
new file mode 100644
index 0000000000000000000000000000000000000000..220c0f88966c8c514d7320348d585e9b63ffde86
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/LPC13Uxx.h
@@ -0,0 +1,760 @@
+
+/****************************************************************************************************//**
+ * @file     LPC13Uxx.h
+ *
+ * 
+ *
+ * @brief    CMSIS Cortex-M3 Core Peripheral Access Layer Header File for
+ *           default LPC13Uxx Device Series
+ *
+ * @version  V0.1
+ * @date     18. Jan 2012
+ *
+ * @note     Generated with SFDGen V2.6 Build 4f  on Tuesday, 17.01.2012 13:39:52
+ *
+ *           from CMSIS SVD File 'LPC13uxx_svd_v0.1.xml' Version 0.1,
+ *           created on Thurs, 01.19.2012 15:13:15, last modified on Thurs, 01.19.2012 15:53:09
+ *
+ *******************************************************************************************************/
+
+/** @addtogroup NXP
+  * @{
+  */
+
+/** @addtogroup LPC13Uxx
+  * @{
+  */
+
+#ifndef __LPC13UXX_H__
+#define __LPC13UXX_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif 
+
+
+#if defined ( __CC_ARM   )
+  #pragma anon_unions
+#endif
+
+ /* Interrupt Number Definition */
+
+typedef enum {
+// -------------------------  Cortex-M3 Processor Exceptions Numbers  -----------------------------
+  Reset_IRQn                        = -15,  /*!<   1  Reset Vector, invoked on Power up and warm reset */
+  NonMaskableInt_IRQn               = -14,  /*!<   2  Non maskable Interrupt, cannot be stopped or preempted */
+  HardFault_IRQn                    = -13,  /*!<   3  Hard Fault, all classes of Fault */
+  MemoryManagement_IRQn             = -12,  /*!<   4  Memory Management, MPU mismatch, including Access Violation and No Match */
+  BusFault_IRQn                     = -11,  /*!<   5  Bus Fault, Pre-Fetch-, Memory Access Fault, other address/memory related Fault */
+  UsageFault_IRQn                   = -10,  /*!<   6  Usage Fault, i.e. Undef Instruction, Illegal State Transition */
+  SVCall_IRQn                       = -5,   /*!<  11  System Service Call via SVC instruction */
+  DebugMonitor_IRQn                 = -4,   /*!<  12  Debug Monitor                    */
+  PendSV_IRQn                       = -2,   /*!<  14  Pendable request for system service */
+  SysTick_IRQn                      = -1,   /*!<  15  System Tick Timer                */
+// ----------------------------  LPC13Uxx Specific Interrupt Numbers  --------------------------------
+  PIN_INT0_IRQn                     = 0,    /*!<   0  PIN_INT0                         */
+  PIN_INT1_IRQn                     = 1,    /*!<   1  PIN_INT1                         */
+  PIN_INT2_IRQn                     = 2,    /*!<   2  PIN_INT2                         */
+  PIN_INT3_IRQn                     = 3,    /*!<   3  PIN_INT3                         */
+  PIN_INT4_IRQn                     = 4,    /*!<   4  PIN_INT4                         */
+  PIN_INT5_IRQn                     = 5,    /*!<   5  PIN_INT5                         */
+  PIN_INT6_IRQn                     = 6,    /*!<   6  PIN_INT6                         */
+  PIN_INT7_IRQn                     = 7,    /*!<   7  PIN_INT7                         */
+  GINT0_IRQn                        = 8,    /*!<   8  GINT0                            */
+  GINT1_IRQn                        = 9,    /*!<   9  GINT1                            */
+  Reserved0_IRQn                    = 10,   /*!<  10  Reserved Interrupt               */
+  Reserved1_IRQn                    = 11,   /*!<  11  Reserved Interrupt               */
+  RIT_IRQn                          = 12,   /*!<  12  Repetitive Interrupt Timer       */
+  Reserved2_IRQn                    = 13,   /*!<  13  Reserved Interrupt               */
+  SSP1_IRQn                         = 14,   /*!<  14  SSP1                             */
+  I2C_IRQn                          = 15,   /*!<  15  I2C                              */
+  CT16B0_IRQn                       = 16,   /*!<  16  CT16B0                           */
+  CT16B1_IRQn                       = 17,   /*!<  17  CT16B1                           */
+  CT32B0_IRQn                       = 18,   /*!<  18  CT32B0                           */
+  CT32B1_IRQn                       = 19,   /*!<  19  CT32B1                           */
+  SSP0_IRQn                         = 20,   /*!<  20  SSP0                             */
+  USART_IRQn                        = 21,   /*!<  21  USART                            */
+  USB_IRQ_IRQn                      = 22,   /*!<  22  USB_IRQ                          */
+  USB_FIQ_IRQn                      = 23,   /*!<  23  USB_FIQ                          */
+  ADC_IRQn                          = 24,   /*!<  24  ADC                              */
+  WDT_IRQn                          = 25,   /*!<  25  WDT                              */
+  BOD_IRQn                          = 26,   /*!<  26  BOD                              */
+  FMC_IRQn                          = 27,   /*!<  27  FMC                              */
+  Reserved3_IRQn                    = 28,   /*!<  28  Reserved Interrupt               */
+  Reserved4_IRQn                    = 29,   /*!<  29  Reserved Interrupt               */
+  USBWAKEUP_IRQn                    = 30,   /*!<  30  USBWAKEUP                        */
+  Reserved5_IRQn                    = 31,   /*!<  31  Reserved Interrupt               */
+} IRQn_Type;
+
+
+/** @addtogroup Configuration_of_CMSIS
+  * @{
+  */
+
+/* Processor and Core Peripheral Section */ /* Configuration of the Cortex-M3 Processor and Core Peripherals */
+
+#define __CM3_REV              0x0000       /*!< Cortex-M3 Core Revision               */
+#define __MPU_PRESENT             0         /*!< MPU present or not                    */
+#define __NVIC_PRIO_BITS          3         /*!< Number of Bits used for Priority Levels */
+#define __Vendor_SysTickConfig    0         /*!< Set to 1 if different SysTick Config is used */
+/** @} */ /* End of group Configuration_of_CMSIS */
+
+#include <core_cm3.h>                       /*!< Cortex-M3 processor and core peripherals */
+#include "system_LPC13Uxx.h"                /*!< LPC13Uxx System                          */
+
+/** @addtogroup Device_Peripheral_Registers
+  * @{
+  */
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                          I2C                                         -----
+// ------------------------------------------------------------------------------------------------
+
+
+
+typedef struct {                            /*!< (@ 0x40000000) I2C Structure          */
+  __IO uint32_t CONSET;                     /*!< (@ 0x40000000) I2C Control Set Register. When a one is written to a bit of this register, the corresponding bit in the I2C control register is set. Writing a zero has no effect on the corresponding bit in the I2C control register. */
+  __I  uint32_t STAT;                       /*!< (@ 0x40000004) I2C Status Register. During I2C operation, this register provides detailed status codes that allow software to determine the next action needed. */
+  __IO uint32_t DAT;                        /*!< (@ 0x40000008) I2C Data Register. During master or slave transmit mode, data to be transmitted is written to this register. During master or slave receive mode, data that has been received may be read from this register. */
+  __IO uint32_t ADR0;                       /*!< (@ 0x4000000C) I2C Slave Address Register 0. Contains the 7-bit slave address for operation of the I2C interface in slave mode, and is not used in master mode. The least significant bit determines whether a slave responds to the General Call address. */
+  __IO uint32_t SCLH;                       /*!< (@ 0x40000010) SCH Duty Cycle Register High Half Word. Determines the high time of the I2C clock. */
+  __IO uint32_t SCLL;                       /*!< (@ 0x40000014) SCL Duty Cycle Register Low Half Word. Determines the low time of the I2C clock. I2nSCLL and I2nSCLH together determine the clock frequency generated by an I2C master and certain times used in slave mode. */
+  __O  uint32_t CONCLR;                     /*!< (@ 0x40000018) I2C Control Clear Register. When a one is written to a bit of this register, the corresponding bit in the I2C control register is cleared. Writing a zero has no effect on the corresponding bit in the I2C control register. */
+  __IO uint32_t MMCTRL;                     /*!< (@ 0x4000001C) Monitor mode control register. */
+  union{
+  __IO uint32_t ADR[3];                     /*!< (@ 0x40000020) I2C Slave Address Register. Contains the 7-bit slave address for operation of the I2C interface in slave mode, and is not used in master mode. The least significant bit determines whether a slave responds to the General Call address. */
+  struct{
+  __IO uint32_t ADR1;
+  __IO uint32_t ADR2;
+  __IO uint32_t ADR3;
+  };
+  };
+  __I  uint32_t DATA_BUFFER;                /*!< (@ 0x4000002C) Data buffer register. The contents of the 8 MSBs of the I2DAT shift register will be transferred to the DATA_BUFFER automatically after every nine bits (8 bits of data plus ACK or NACK) has been received on the bus. */
+  union{
+  __IO uint32_t MASK[4];                    /*!< (@ 0x40000030) I2C Slave address mask register. This mask register is associated with I2ADR0 to determine an address match. The mask register has no effect when comparing to the General Call address (0000000). */
+  struct{
+  __IO uint32_t MASK0;
+  __IO uint32_t MASK1;
+  __IO uint32_t MASK2;
+  __IO uint32_t MASK3;
+  };
+  };
+} LPC_I2C_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                         WWDT                                         -----
+// ------------------------------------------------------------------------------------------------
+
+
+typedef struct {                            /*!< (@ 0x40004000) WWDT Structure         */
+  __IO uint32_t MOD;                        /*!< (@ 0x40004000) Watchdog mode register. This register contains the basic mode and status of the Watchdog Timer. */
+  __IO uint32_t TC;                         /*!< (@ 0x40004004) Watchdog timer constant register. This 24-bit register determines the time-out value. */
+  __O  uint32_t FEED;                       /*!< (@ 0x40004008) Watchdog feed sequence register. Writing 0xAA followed by 0x55 to this register reloads the Watchdog timer with the value contained in WDTC. */
+  __I  uint32_t TV;                         /*!< (@ 0x4000400C) Watchdog timer value register. This 24-bit register reads out the current value of the Watchdog timer. */
+  __IO uint32_t CLKSEL;                     /*!< (@ 0x40004010) Watchdog clock select register. */
+  __IO uint32_t WARNINT;                    /*!< (@ 0x40004014) Watchdog Warning Interrupt compare value. */
+  __IO uint32_t WINDOW;                     /*!< (@ 0x40004018) Watchdog Window compare value. */
+} LPC_WWDT_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                         USART                                        -----
+// ------------------------------------------------------------------------------------------------
+
+
+typedef struct {                            /*!< (@ 0x40008000) USART Structure        */
+  
+  union {
+    __IO uint32_t DLL;                      /*!< (@ 0x40008000) Divisor Latch LSB. Least significant byte of the baud rate divisor value. The full divisor is used to generate a baud rate from the fractional rate divider. (DLAB=1) */
+    __O  uint32_t THR;                      /*!< (@ 0x40008000) Transmit Holding Register. The next character to be transmitted is written here. (DLAB=0) */
+    __I  uint32_t RBR;                      /*!< (@ 0x40008000) Receiver Buffer Register. Contains the next received character to be read. (DLAB=0) */
+  };
+  
+  union {
+    __IO uint32_t IER;                      /*!< (@ 0x40008004) Interrupt Enable Register. Contains individual interrupt enable bits for the 7 potential USART interrupts. (DLAB=0) */
+    __IO uint32_t DLM;                      /*!< (@ 0x40008004) Divisor Latch MSB. Most significant byte of the baud rate divisor value. The full divisor is used to generate a baud rate from the fractional rate divider. (DLAB=1) */
+  };
+  
+  union {
+    __O  uint32_t FCR;                      /*!< (@ 0x40008008) FIFO Control Register. Controls USART FIFO usage and modes. */
+    __I  uint32_t IIR;                      /*!< (@ 0x40008008) Interrupt ID Register. Identifies which interrupt(s) are pending. */
+  };
+  __IO uint32_t LCR;                        /*!< (@ 0x4000800C) Line Control Register. Contains controls for frame formatting and break generation. */
+  __IO uint32_t MCR;                        /*!< (@ 0x40008010) Modem Control Register. */
+  __I  uint32_t LSR;                        /*!< (@ 0x40008014) Line Status Register. Contains flags for transmit and receive status, including line errors. */
+  __I  uint32_t MSR;                        /*!< (@ 0x40008018) Modem Status Register. */
+  __IO uint32_t SCR;                        /*!< (@ 0x4000801C) Scratch Pad Register. Eight-bit temporary storage for software. */
+  __IO uint32_t ACR;                        /*!< (@ 0x40008020) Auto-baud Control Register. Contains controls for the auto-baud feature. */
+  __IO uint32_t ICR;                        /*!< (@ 0x40008024) IrDA Control Register. Enables and configures the IrDA (remote control) mode. */
+  __IO uint32_t FDR;                        /*!< (@ 0x40008028) Fractional Divider Register. Generates a clock input for the baud rate divider. */
+  __IO uint32_t OSR;                        /*!< (@ 0x4000802C) Oversampling Register. Controls the degree of oversampling during each bit time. */
+  __IO uint32_t TER;                        /*!< (@ 0x40008030) Transmit Enable Register. Turns off USART transmitter for use with software flow control. */
+  __I  uint32_t RESERVED0[3];
+  __IO uint32_t HDEN;                       /*!< (@ 0x40008040) Half duplex enable register. */
+  __I  uint32_t RESERVED1;
+  __IO uint32_t SCICTRL;                    /*!< (@ 0x40008048) Smart Card Interface Control register. Enables and configures the Smart Card Interface feature. */
+  __IO uint32_t RS485CTRL;                  /*!< (@ 0x4000804C) RS-485/EIA-485 Control. Contains controls to configure various aspects of RS-485/EIA-485 modes. */
+  __IO uint32_t RS485ADRMATCH;              /*!< (@ 0x40008050) RS-485/EIA-485 address match. Contains the address match value for RS-485/EIA-485 mode. */
+  __IO uint32_t RS485DLY;                   /*!< (@ 0x40008054) RS-485/EIA-485 direction control delay. */
+  __IO uint32_t SYNCCTRL;                   /*!< (@ 0x40008058) Synchronous mode control register. */
+} LPC_USART_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                        CT16B0                                        -----
+// ------------------------------------------------------------------------------------------------
+
+typedef struct {                            /*!< (@ 0x4000C000) CT16B0 Structure       */
+  __IO uint32_t IR;                         /*!< (@ 0x4000C000) Interrupt Register. The IR can be written to clear interrupts. The IR can be read to identify which of eight possible interrupt sources are pending. */
+  __IO uint32_t TCR;                        /*!< (@ 0x4000C004) Timer Control Register. The TCR is used to control the Timer Counter functions. The Timer Counter can be disabled or reset through the TCR. */
+  __IO uint32_t TC;                         /*!< (@ 0x4000C008) Timer Counter. The 16-bit TC is incremented every PR+1 cycles of PCLK. The TC is controlled through the TCR. */
+  __IO uint32_t PR;                         /*!< (@ 0x4000C00C) Prescale Register. When the Prescale Counter (below) is equal to this value, the next clock increments the TC and clears the PC. */
+  __IO uint32_t PC;                         /*!< (@ 0x4000C010) Prescale Counter. The 16-bit PC is a counter which is incremented to the value stored in PR. When the value in PR is reached, the TC is incremented and the PC is cleared. The PC is observable and controllable through the bus interface. */
+  __IO uint32_t MCR;                        /*!< (@ 0x4000C014) Match Control Register. The MCR is used to control if an interrupt is generated and if the TC is reset when a Match occurs. */
+  union {
+  __IO uint32_t MR[4];                      /*!< (@ 0x4000C018) Match Register. MR can be enabled through the MCR to reset the TC, stop both the TC and PC, and/or generate an interrupt every time MR matches the TC. */
+  struct{
+  __IO uint32_t MR0;                        /*!< (@ 0x4000C018) Match Register. MR0 */
+  __IO uint32_t MR1;                        /*!< (@ 0x4000C01C) Match Register. MR1 */
+  __IO uint32_t MR2;                        /*!< (@ 0x4000C020) Match Register. MR2 */
+  __IO uint32_t MR3;                        /*!< (@ 0x4000C024) Match Register. MR3 */
+  };
+  };
+  __IO uint32_t CCR;                        /*!< (@ 0x4000C028) Capture Control Register. The CCR controls which edges of the capture inputs are used to load the Capture Registers and whether or not an interrupt is generated when a capture takes place. */
+  union{
+  __I  uint32_t CR[4];                      /*!< (@ 0x4000C02C) Capture Register. CR is loaded with the value of TC when there is an event on the CT16B0_CAP input. */
+    struct{
+  __I  uint32_t CR0;			            /*!< (@ 0x4000C02C) Capture Register. CR 0 */
+  __I  uint32_t CR1;			            /*!< (@ 0x4000C030) Capture Register. CR 1 */
+  __I  uint32_t CR2;			            /*!< (@ 0x4000C034) Capture Register. CR 2 */
+  __I  uint32_t CR3;			            /*!< (@ 0x4000C038) Capture Register. CR 3 */
+  };
+  };
+  __IO uint32_t EMR;                        /*!< (@ 0x4000C03C) External Match Register. The EMR controls the match function and the external match pins  */
+  __I  uint32_t RESERVED0[12];
+  __IO uint32_t CTCR;                       /*!< (@ 0x4000C070) Count Control Register. The CTCR selects between Timer and Counter mode, and in Counter mode selects the signal and edge(s) for counting. */
+  __IO uint32_t PWMC;                       /*!< (@ 0x4000C074) PWM Control Register. The PWMCON enables PWM mode for the external match pins CT16B0_MAT[1:0] and CT16B1_MAT[1:0]. */
+} LPC_CT16B0_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                        CT16B1                                        -----
+// ------------------------------------------------------------------------------------------------
+
+typedef struct {                            /*!< (@ 0x40010000) CT16B1 Structure       */
+  __IO uint32_t IR;                         /*!< (@ 0x40010000) Interrupt Register. The IR can be written to clear interrupts. The IR can be read to identify which of eight possible interrupt sources are pending. */
+  __IO uint32_t TCR;                        /*!< (@ 0x40010004) Timer Control Register. The TCR is used to control the Timer Counter functions. The Timer Counter can be disabled or reset through the TCR. */
+  __IO uint32_t TC;                         /*!< (@ 0x40010008) Timer Counter. The 16-bit TC is incremented every PR+1 cycles of PCLK. The TC is controlled through the TCR. */
+  __IO uint32_t PR;                         /*!< (@ 0x4001000C) Prescale Register. When the Prescale Counter (below) is equal to this value, the next clock increments the TC and clears the PC. */
+  __IO uint32_t PC;                         /*!< (@ 0x40010010) Prescale Counter. The 16-bit PC is a counter which is incremented to the value stored in PR. When the value in PR is reached, the TC is incremented and the PC is cleared. The PC is observable and controllable through the bus interface. */
+  __IO uint32_t MCR;                        /*!< (@ 0x40010014) Match Control Register. The MCR is used to control if an interrupt is generated and if the TC is reset when a Match occurs. */
+  union {
+  __IO uint32_t MR[4];                      /*!< (@ 0x40010018) Match Register. MR can be enabled through the MCR to reset the TC, stop both the TC and PC, and/or generate an interrupt every time MR matches the TC. */
+  struct{
+  __IO uint32_t MR0;                        /*!< (@ 0x40010018) Match Register. MR0 */
+  __IO uint32_t MR1;                        /*!< (@ 0x4001001C) Match Register. MR1 */
+  __IO uint32_t MR2;                        /*!< (@ 0x40010020) Match Register. MR2 */
+  __IO uint32_t MR3;                        /*!< (@ 0x40010024) Match Register. MR3 */
+  };
+  };
+  __IO uint32_t CCR;                        /*!< (@ 0x40010028) Capture Control Register. The CCR controls which edges of the capture inputs are used to load the Capture Registers and whether or not an interrupt is generated when a capture takes place. */
+  union{
+  __I  uint32_t CR[4];                      /*!< (@ 0x4001002C) Capture Register. CR is loaded with the value of TC when there is an event on the CT16B0_CAP input. */
+    struct{
+  __I  uint32_t CR0;			            /*!< (@ 0x4001002C) Capture Register. CR 0 */
+  __I  uint32_t CR1;			            /*!< (@ 0x40010030) Capture Register. CR 1 */
+  __I  uint32_t CR2;			            /*!< (@ 0x40010034) Capture Register. CR 2 */
+  __I  uint32_t CR3;			            /*!< (@ 0x40010038) Capture Register. CR 3 */
+  };
+  };
+  __IO uint32_t EMR;                        /*!< (@ 0x4001003C) External Match Register. The EMR controls the match function and the external match pins  */
+  __I  uint32_t RESERVED0[12];
+  __IO uint32_t CTCR;                       /*!< (@ 0x40010070) Count Control Register. The CTCR selects between Timer and Counter mode, and in Counter mode selects the signal and edge(s) for counting. */
+  __IO uint32_t PWMC;                       /*!< (@ 0x40010074) PWM Control Register. The PWMCON enables PWM mode for the external match pins CT16B0_MAT[1:0] and CT16B1_MAT[1:0]. */
+} LPC_CT16B1_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                        CT32B0                                        -----
+// ------------------------------------------------------------------------------------------------
+typedef struct {                            /*!< (@ 0x40014000) CT32B0 Structure       */
+  __IO uint32_t IR;                         /*!< (@ 0x40014000) Interrupt Register. The IR can be written to clear interrupts. The IR can be read to identify which of eight possible interrupt sources are pending. */
+  __IO uint32_t TCR;                        /*!< (@ 0x40014004) Timer Control Register. The TCR is used to control the Timer Counter functions. The Timer Counter can be disabled or reset through the TCR. */
+  __IO uint32_t TC;                         /*!< (@ 0x40014008) Timer Counter. The 32-bit TC is incremented every PR+1 cycles of PCLK. The TC is controlled through the TCR. */
+  __IO uint32_t PR;                         /*!< (@ 0x4001400C) Prescale Register. When the Prescale Counter (below) is equal to this value, the next clock increments the TC and clears the PC. */
+  __IO uint32_t PC;                         /*!< (@ 0x40014010) Prescale Counter. The 32-bit PC is a counter which is incremented to the value stored in PR. When the value in PR is reached, the TC is incremented and the PC is cleared. The PC is observable and controllable through the bus interface. */
+  __IO uint32_t MCR;                        /*!< (@ 0x40014014) Match Control Register. The MCR is used to control if an interrupt is generated and if the TC is reset when a Match occurs. */
+  union {
+  __IO uint32_t MR[4];                      /*!< (@ 0x40014018) Match Register. MR can be enabled through the MCR to reset the TC, stop both the TC and PC, and/or generate an interrupt every time MR matches the TC. */
+  struct{
+  __IO uint32_t MR0;                        /*!< (@ 0x40014018) Match Register. MR0 */
+  __IO uint32_t MR1;                        /*!< (@ 0x4001401C) Match Register. MR1 */
+  __IO uint32_t MR2;                        /*!< (@ 0x40014020) Match Register. MR2 */
+  __IO uint32_t MR3;                        /*!< (@ 0x40014024) Match Register. MR3 */
+  };
+  };
+  __IO uint32_t CCR;                        /*!< (@ 0x40014028) Capture Control Register. The CCR controls which edges of the capture inputs are used to load the Capture Registers and whether or not an interrupt is generated when a capture takes place. */
+  union{
+  __I  uint32_t CR[4];                      /*!< (@ 0x4001402C) Capture Register. CR is loaded with the value of TC when there is an event on the CT32B_CAP0 input. */
+    struct{
+  __I  uint32_t CR0;			            /*!< (@ 0x4001402C) Capture Register. CR 0 */
+  __I  uint32_t CR1;			            /*!< (@ 0x40014030) Capture Register. CR 1 */
+  __I  uint32_t CR2;			            /*!< (@ 0x40014034) Capture Register. CR 2 */
+  __I  uint32_t CR3;			            /*!< (@ 0x40014038) Capture Register. CR 3 */
+  };
+  };
+  __IO uint32_t EMR;                        /*!< (@ 0x4001403C) External Match Register. The EMR controls the match function and the external match pins CT32Bn_MAT[3:0]. */
+  __I  uint32_t RESERVED0[12];
+  __IO uint32_t CTCR;                       /*!< (@ 0x40014070) Count Control Register. The CTCR selects between Timer and Counter mode, and in Counter mode selects the signal and edge(s) for counting. */
+  __IO uint32_t PWMC;                       /*!< (@ 0x40014074) PWM Control Register. The PWMCON enables PWM mode for the external match pins CT32Bn_MAT[3:0]. */
+} LPC_CT32B0_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                        CT32B1                                        -----
+// ------------------------------------------------------------------------------------------------
+typedef struct {                            /*!< (@ 0x40018000) CT32B1 Structure       */
+  __IO uint32_t IR;                         /*!< (@ 0x40018000) Interrupt Register. The IR can be written to clear interrupts. The IR can be read to identify which of eight possible interrupt sources are pending. */
+  __IO uint32_t TCR;                        /*!< (@ 0x40018004) Timer Control Register. The TCR is used to control the Timer Counter functions. The Timer Counter can be disabled or reset through the TCR. */
+  __IO uint32_t TC;                         /*!< (@ 0x40018008) Timer Counter. The 32-bit TC is incremented every PR+1 cycles of PCLK. The TC is controlled through the TCR. */
+  __IO uint32_t PR;                         /*!< (@ 0x4001800C) Prescale Register. When the Prescale Counter (below) is equal to this value, the next clock increments the TC and clears the PC. */
+  __IO uint32_t PC;                         /*!< (@ 0x40018010) Prescale Counter. The 32-bit PC is a counter which is incremented to the value stored in PR. When the value in PR is reached, the TC is incremented and the PC is cleared. The PC is observable and controllable through the bus interface. */
+  __IO uint32_t MCR;                        /*!< (@ 0x40018014) Match Control Register. The MCR is used to control if an interrupt is generated and if the TC is reset when a Match occurs. */
+  union {
+  __IO uint32_t MR[4];                      /*!< (@ 0x40018018) Match Register. MR can be enabled through the MCR to reset the TC, stop both the TC and PC, and/or generate an interrupt every time MR matches the TC. */
+  struct{
+  __IO uint32_t MR0;                        /*!< (@ 0x40018018) Match Register. MR0 */
+  __IO uint32_t MR1;                        /*!< (@ 0x4001801C) Match Register. MR1 */
+  __IO uint32_t MR2;                        /*!< (@ 0x40018020) Match Register. MR2 */
+  __IO uint32_t MR3;                        /*!< (@ 0x40018024) Match Register. MR3 */
+  };
+  };
+  __IO uint32_t CCR;                        /*!< (@ 0x40018028) Capture Control Register. The CCR controls which edges of the capture inputs are used to load the Capture Registers and whether or not an interrupt is generated when a capture takes place. */
+  union{
+  __I  uint32_t CR[4];                      /*!< (@ 0x4001802C) Capture Register. CR is loaded with the value of TC when there is an event on the CT32B_CAP0 input. */
+    struct{
+  __I  uint32_t CR0;			            /*!< (@ 0x4001802C) Capture Register. CR 0 */
+  __I  uint32_t CR1;			            /*!< (@ 0x40018030) Capture Register. CR 1 */
+  __I  uint32_t CR2;			            /*!< (@ 0x40018034) Capture Register. CR 2 */
+  __I  uint32_t CR3;			            /*!< (@ 0x40018038) Capture Register. CR 3 */
+  };
+  };
+  __IO uint32_t EMR;                        /*!< (@ 0x4001803C) External Match Register. The EMR controls the match function and the external match pins CT32Bn_MAT[3:0]. */
+  __I  uint32_t RESERVED0[12];
+  __IO uint32_t CTCR;                       /*!< (@ 0x40018070) Count Control Register. The CTCR selects between Timer and Counter mode, and in Counter mode selects the signal and edge(s) for counting. */
+  __IO uint32_t PWMC;                       /*!< (@ 0x40018074) PWM Control Register. The PWMCON enables PWM mode for the external match pins CT32Bn_MAT[3:0]. */
+} LPC_CT32B1_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                          ADC                                         -----
+// ------------------------------------------------------------------------------------------------
+typedef struct {                            /*!< (@ 0x4001C000) ADC Structure          */
+  __IO uint32_t CR;                         /*!< (@ 0x4001C000) A/D Control Register. The CR register must be written to select the operating mode before A/D conversion can occur. */
+  __IO uint32_t GDR;                        /*!< (@ 0x4001C004) A/D Global Data Register. Contains the result of the most recent A/D conversion. */
+  __I  uint32_t RESERVED0[1];
+  __IO uint32_t INTEN;                      /*!< (@ 0x4001C00C) A/D Interrupt Enable Register. This register contains enable bits that allow the DONE flag of each A/D channel to be included or excluded from contributing to the generation of an A/D interrupt. */
+  union{
+  __I  uint32_t DR[8];                      /*!< (@ 0x4001C010) A/D Channel Data Register*/
+    struct{
+  __I  uint32_t DR0;                      	/*!< (@ 0x4001C010) A/D Channel Data Register 0*/
+  __I  uint32_t DR1;                      	/*!< (@ 0x4001C014) A/D Channel Data Register 1*/
+  __I  uint32_t DR2;                      	/*!< (@ 0x4001C018) A/D Channel Data Register 2*/
+  __I  uint32_t DR3;                      	/*!< (@ 0x4001C01C) A/D Channel Data Register 3*/
+  __I  uint32_t DR4;                      	/*!< (@ 0x4001C020) A/D Channel Data Register 4*/
+  __I  uint32_t DR5;                      	/*!< (@ 0x4001C024) A/D Channel Data Register 5*/
+  __I  uint32_t DR6;                      	/*!< (@ 0x4001C028) A/D Channel Data Register 6*/
+  __I  uint32_t DR7;                      	/*!< (@ 0x4001C02C) A/D Channel Data Register 7*/
+  };
+  };
+  __I  uint32_t STAT;                       /*!< (@ 0x4001C030) A/D Status Register. This register contains DONE and OVERRUN flags for all of the A/D channels, as well as the A/D interrupt flag. */
+} LPC_ADC_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                          PMU                                         -----
+// ------------------------------------------------------------------------------------------------
+
+typedef struct {                            /*!< (@ 0x40038000) PMU Structure          */
+  __IO uint32_t PCON;                       /*!< (@ 0x40038000) Power control register */
+  union{
+  __IO uint32_t GPREG[4];                   /*!< (@ 0x40038004) General purpose register 0 */
+  struct{
+  __IO uint32_t GPREG0;                   	/*!< (@ 0x40038004) General purpose register 0 */
+  __IO uint32_t GPREG1;                   	/*!< (@ 0x40038008) General purpose register 1 */
+  __IO uint32_t GPREG2;                   	/*!< (@ 0x4003800C) General purpose register 2 */
+  __IO uint32_t GPREG3;                   	/*!< (@ 0x40038010) General purpose register 3 */
+  };
+  };
+  __IO uint32_t GPREG4;                     /*!< (@ 0x40038014) General purpose register 4 */
+} LPC_PMU_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                       FLASHCTRL                                      -----
+// ------------------------------------------------------------------------------------------------
+
+typedef struct {                            /*!< (@ 0x4003C000) FLASHCTRL Structure    */
+  __I  uint32_t RESERVED0[4];
+  __IO uint32_t FLASHCFG;                   /*!< (@ 0x4003C010) Flash memory access time configuration register */
+  __I  uint32_t RESERVED1[3];
+  __IO uint32_t FMSSTART;                   /*!< (@ 0x4003C020) Signature start address register */
+  __IO uint32_t FMSSTOP;                    /*!< (@ 0x4003C024) Signature stop-address register */
+  __I  uint32_t RESERVED2[1];
+  __I  uint32_t FMSW0;                      /*!< (@ 0x4003C02C) Word 0 [31:0]          */
+  __I  uint32_t FMSW1;                      /*!< (@ 0x4003C030) Word 1 [63:32]         */
+  __I  uint32_t FMSW2;                      /*!< (@ 0x4003C034) Word 2 [95:64]         */
+  __I  uint32_t FMSW3;                      /*!< (@ 0x4003C038) Word 3 [127:96]        */
+  __I  uint32_t RESERVED3[1001];
+  __I  uint32_t FMSTAT;                     /*!< (@ 0x4003CFE0) Signature generation status register */
+  __I  uint32_t RESERVED4[1];
+  __O  uint32_t FMSTATCLR;                  /*!< (@ 0x4003CFE8) Signature generation status clear register */
+} LPC_FLASHCTRL_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                         SSP0                                         -----
+// ------------------------------------------------------------------------------------------------
+typedef struct {                            /*!< (@ 0x40040000) SSP0 Structure         */
+  __IO uint32_t CR0;                        /*!< (@ 0x40040000) Control Register 0. Selects the serial clock rate, bus type, and data size. */
+  __IO uint32_t CR1;                        /*!< (@ 0x40040004) Control Register 1. Selects master/slave and other modes. */
+  __IO uint32_t DR;                         /*!< (@ 0x40040008) Data Register. Writes fill the transmit FIFO, and reads empty the receive FIFO. */
+  __I  uint32_t SR;                         /*!< (@ 0x4004000C) Status Register        */
+  __IO uint32_t CPSR;                       /*!< (@ 0x40040010) Clock Prescale Register */
+  __IO uint32_t IMSC;                       /*!< (@ 0x40040014) Interrupt Mask Set and Clear Register */
+  __I  uint32_t RIS;                        /*!< (@ 0x40040018) Raw Interrupt Status Register */
+  __I  uint32_t MIS;                        /*!< (@ 0x4004001C) Masked Interrupt Status Register */
+  __O  uint32_t ICR;                        /*!< (@ 0x40040020) SSPICR Interrupt Clear Register */
+} LPC_SSP0_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                         IOCON                                        -----
+// ------------------------------------------------------------------------------------------------
+typedef struct {                            /*!< (@ 0x40044000) IOCON Structure        */
+  __IO uint32_t RESET_PIO0_0;               /*!< (@ 0x40044000) I/O configuration for pin RESET/PIO0_0 */
+  __IO uint32_t PIO0_1;                     /*!< (@ 0x40044004) I/O configuration for pin PIO0_1/CLKOUT/CT32B0_MAT2/USB_FTOGGLE */
+  __IO uint32_t PIO0_2;                     /*!< (@ 0x40044008) I/O configuration for pin PIO0_2/SSEL0/CT16B0_CAP0 */
+  __IO uint32_t PIO0_3;                     /*!< (@ 0x4004400C) I/O configuration for pin PIO0_3/USB_VBUS */
+  __IO uint32_t PIO0_4;                     /*!< (@ 0x40044010) I/O configuration for pin PIO0_4/SCL */
+  __IO uint32_t PIO0_5;                     /*!< (@ 0x40044014) I/O configuration for pin PIO0_5/SDA */
+  __IO uint32_t PIO0_6;                     /*!< (@ 0x40044018) I/O configuration for pin PIO0_6/USB_CONNECT/SCK0 */
+  __IO uint32_t PIO0_7;                     /*!< (@ 0x4004401C) I/O configuration for pin PIO0_7/CTS */
+  __IO uint32_t PIO0_8;                     /*!< (@ 0x40044020) I/O configuration for pin PIO0_8/MISO0/CT16B0_MAT0/SWO */
+  __IO uint32_t PIO0_9;                     /*!< (@ 0x40044024) I/O configuration for pin PIO0_9/MOSI0/CT16B0_MAT1/TRACECLK */
+  __IO uint32_t SWCLK_PIO0_10;              /*!< (@ 0x40044028) I/O configuration for pin SWCLK/PIO0_10/ SCK0/CT16B0_MAT2 */
+  __IO uint32_t TDI_PIO0_11;                /*!< (@ 0x4004402C) I/O configuration for pin TDI/PIO0_11/AD0/CT32B0_MAT3 */
+  __IO uint32_t TMS_PIO0_12;                /*!< (@ 0x40044030) I/O configuration for pin TMS/PIO0_12/AD1/CT32B1_CAP0 */
+  __IO uint32_t TDO_PIO0_13;                /*!< (@ 0x40044034) I/O configuration for pin TDO/PIO0_13/AD2/CT32B1_MAT0 */
+  __IO uint32_t TRST_PIO0_14;               /*!< (@ 0x40044038) I/O configuration for pin TRST/PIO0_14/AD3/CT32B1_MAT1 */
+  __IO uint32_t SWDIO_PIO0_15;              /*!< (@ 0x4004403C) I/O configuration for pin SWDIO/PIO0_15/AD4/CT32B1_MAT2 */
+  __IO uint32_t PIO0_16;                    /*!< (@ 0x40044040) I/O configuration for pin PIO0_16/AD5/CT32B1_MAT3/ WAKEUP */
+  __IO uint32_t PIO0_17;                    /*!< (@ 0x40044044) I/O configuration for pin PIO0_17/RTS/CT32B0_CAP0/SCLK */
+  __IO uint32_t PIO0_18;                    /*!< (@ 0x40044048) I/O configuration for pin PIO0_18/RXD/CT32B0_MAT0 */
+  __IO uint32_t PIO0_19;                    /*!< (@ 0x4004404C) I/O configuration for pin PIO0_19/TXD/CT32B0_MAT1 */
+  __IO uint32_t PIO0_20;                    /*!< (@ 0x40044050) I/O configuration for pin PIO0_20/CT16B1_CAP0 */
+  __IO uint32_t PIO0_21;                    /*!< (@ 0x40044054) I/O configuration for pin PIO0_21/CT16B1_MAT0/MOSI1 */
+  __IO uint32_t PIO0_22;                    /*!< (@ 0x40044058) I/O configuration for pin PIO0_22/AD6/CT16B1_MAT1/MISO1 */
+  __IO uint32_t PIO0_23;                    /*!< (@ 0x4004405C) I/O configuration for pin PIO0_23/AD7 */
+  __IO uint32_t PIO1_0;                     /*!< (@ 0x40044060) I/O configuration for pin PIO1_0/CT32B1_MAT0 */
+  __IO uint32_t PIO1_1;                     /*!< (@ 0x40044064) I/O configuration for pin PIO1_1/CT32B1_MAT1 */
+  __IO uint32_t PIO1_2;                     /*!< (@ 0x40044068) I/O configuration for pin PIO1_2/CT32B1_MAT2 */
+  __IO uint32_t PIO1_3;                     /*!< (@ 0x4004406C) I/O configuration for pin PIO1_3/CT32B1_MAT3 */
+  __IO uint32_t PIO1_4;                     /*!< (@ 0x40044070) I/O configuration for pin PIO1_4/CT32B1_CAP0 */
+  __IO uint32_t PIO1_5;                     /*!< (@ 0x40044074) I/O configuration for pin PIO1_5/CT32B1_CAP1 */
+  __IO uint32_t PIO1_6;                     /*!< (@ 0x40044078) I/O configuration for pin PIO1_6 */
+  __IO uint32_t PIO1_7;                     /*!< (@ 0x4004407C) I/O configuration for pin PIO1_7 */
+  __IO uint32_t PIO1_8;                     /*!< (@ 0x40044080) I/O configuration for pin PIO1_8 */
+  __IO uint32_t PIO1_9;                     /*!< (@ 0x40044084) I/O configuration for pin PIO1_9 */
+  __IO uint32_t PIO1_10;                    /*!< (@ 0x40044088) I/O configuration for pin PIO1_10 */
+  __IO uint32_t PIO1_11;                    /*!< (@ 0x4004408C) I/O configuration for pin PIO1_11 */
+  __IO uint32_t PIO1_12;                    /*!< (@ 0x40044090) I/O configuration for pin PIO1_12 */
+  __IO uint32_t PIO1_13;                    /*!< (@ 0x40044094) I/O configuration for PIO1_13/DTR/CT16B0_MAT0/TXD */
+  __IO uint32_t PIO1_14;                    /*!< (@ 0x40044098) I/O configuration for PIO1_14/DSR/CT16B0_MAT1/RXD */
+  __IO uint32_t PIO1_15;                    /*!< (@ 0x4004409C) I/O configuration for pin PIO1_15/DCD/ CT16B0_MAT2/SCK1 */
+  __IO uint32_t PIO1_16;                    /*!< (@ 0x400440A0) I/O configuration for pin PIO1_16/RI/CT16B0_CAP0 */
+  __IO uint32_t PIO1_17;                    /*!< (@ 0x400440A4) I/O configuration for PIO1_17/CT16B0_CAP1/RXD */
+  __IO uint32_t PIO1_18;                    /*!< (@ 0x400440A8) I/O configuration for PIO1_18/CT16B1_CAP1/TXD */
+  __IO uint32_t PIO1_19;                    /*!< (@ 0x400440AC) I/O configuration for pin PIO1_19/DTR/SSEL1 */
+  __IO uint32_t PIO1_20;                    /*!< (@ 0x400440B0) I/O configuration for pin PIO1_20/DSR/SCK1 */
+  __IO uint32_t PIO1_21;                    /*!< (@ 0x400440B4) I/O configuration for pin PIO1_21/DCD/MISO1 */
+  __IO uint32_t PIO1_22;                    /*!< (@ 0x400440B8) I/O configuration for pin PIO1_22/RI/MOSI1 */
+  __IO uint32_t PIO1_23;                    /*!< (@ 0x400440BC) I/O configuration for pin PIO1_23/CT16B1_MAT1/SSEL1 */
+  __IO uint32_t PIO1_24;                    /*!< (@ 0x400440C0) I/O configuration for pin PIO1_24/ CT32B0_MAT0 */
+  __IO uint32_t PIO1_25;                    /*!< (@ 0x400440C4) I/O configuration for pin PIO1_25/CT32B0_MAT1 */
+  __IO uint32_t PIO1_26;                    /*!< (@ 0x400440C8) I/O configuration for pin PIO1_26/CT32B0_MAT2/ RXD */
+  __IO uint32_t PIO1_27;                    /*!< (@ 0x400440CC) I/O configuration for pin PIO1_27/CT32B0_MAT3/ TXD */
+  __IO uint32_t PIO1_28;                    /*!< (@ 0x400440D0) I/O configuration for pin PIO1_28/CT32B0_CAP0/ SCLK */
+  __IO uint32_t PIO1_29;                    /*!< (@ 0x400440D4) I/O configuration for pin PIO1_29/SCK0/ CT32B0_CAP1 */
+  __IO uint32_t PIO1_30;                    /*!< (@ 0x400440D8) I/O configuration for pin PIO1_30 */
+  __IO uint32_t PIO1_31;                    /*!< (@ 0x400440DC) I/O configuration for pin PIO1_31 */
+} LPC_IOCON_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                        SYSCON                                        -----
+// ------------------------------------------------------------------------------------------------
+
+typedef struct {                            /*!< (@ 0x40048000) SYSCON Structure       */
+  __IO uint32_t SYSMEMREMAP;                /*!< (@ 0x40048000) System memory remap    */
+  __IO uint32_t PRESETCTRL;                 /*!< (@ 0x40048004) Peripheral reset control */
+  __IO uint32_t SYSPLLCTRL;                 /*!< (@ 0x40048008) System PLL control     */
+  __I  uint32_t SYSPLLSTAT;                 /*!< (@ 0x4004800C) System PLL status      */
+  __IO uint32_t USBPLLCTRL;                 /*!< (@ 0x40048010) USB PLL control        */
+  __I  uint32_t USBPLLSTAT;                 /*!< (@ 0x40048014) USB PLL status         */
+  __I  uint32_t RESERVED0[2];
+  __IO uint32_t SYSOSCCTRL;                 /*!< (@ 0x40048020) System oscillator control */
+  __IO uint32_t WDTOSCCTRL;                 /*!< (@ 0x40048024) Watchdog oscillator control */
+  __I  uint32_t RESERVED1[2];
+  __IO uint32_t SYSRSTSTAT;                 /*!< (@ 0x40048030) System reset status register */
+  __I  uint32_t RESERVED2[3];
+  __IO uint32_t SYSPLLCLKSEL;               /*!< (@ 0x40048040) System PLL clock source select */
+  __I  uint32_t RESERVED3;
+  __IO uint32_t USBPLLCLKSEL;               /*!< (@ 0x40048048) USB PLL clock source select */
+  __I  uint32_t RESERVED4[9];
+  __IO uint32_t MAINCLKSEL;                 /*!< (@ 0x40048070) Main clock source select */
+  __I  uint32_t RESERVED5;
+  __IO uint32_t SYSAHBCLKDIV;               /*!< (@ 0x40048078) System clock divider   */
+  __I  uint32_t RESERVED6;
+  __IO uint32_t SYSAHBCLKCTRL;              /*!< (@ 0x40048080) System clock control   */
+  __I  uint32_t RESERVED7[4];
+  __IO uint32_t SSP0CLKDIV;                 /*!< (@ 0x40048094) SSP0 clock divider     */
+  __IO uint32_t UARTCLKDIV;                 /*!< (@ 0x40048098) UART clock divider     */
+  __IO uint32_t SSP1CLKDIV;                 /*!< (@ 0x4004809C) SSP1 clock divider     */
+  __I  uint32_t RESERVED8[3];
+  __IO uint32_t TRACECLKDIV;                /*!< (@ 0x400480AC) ARM trace clock divider */
+  __IO uint32_t SYSTICKCLKDIV;              /*!< (@ 0x400480B0) SYSTICK clock divder   */
+  __I  uint32_t RESERVED9[3];
+  __IO uint32_t USBCLKSEL;                  /*!< (@ 0x400480C0) USB clock source select */
+  __I  uint32_t RESERVED10;
+  __IO uint32_t USBCLKDIV;                  /*!< (@ 0x400480C8) USB clock source divider */
+  __I  uint32_t RESERVED11[5];
+  __IO uint32_t CLKOUTSEL;                  /*!< (@ 0x400480E0) CLKOUT clock source select */
+  __I  uint32_t RESERVED12;
+  __IO uint32_t CLKOUTDIV;                  /*!< (@ 0x400480E8) CLKOUT clock divider   */
+  __I  uint32_t RESERVED13[5];
+  __I  uint32_t PIOPORCAP0;                 /*!< (@ 0x40048100) POR captured PIO status 0 */
+  __I  uint32_t PIOPORCAP1;                 /*!< (@ 0x40048104) POR captured PIO status 1 */
+  __I  uint32_t RESERVED14[18];
+  __IO uint32_t BODCTRL;                    /*!< (@ 0x40048150) Brown-Out Detect       */
+  __IO uint32_t SYSTCKCAL;                  /*!< (@ 0x40048154) System tick counter calibration */
+  __I  uint32_t RESERVED15[6];
+  __IO uint32_t IRQLATENCY;                 /*!< (@ 0x40048170) IQR delay. Allows trade-off between interrupt latency and determinism. */
+  __IO uint32_t NMISRC;                     /*!< (@ 0x40048174) NMI Source Control     */
+  __IO uint32_t PINSEL[8];                  /*!< (@ 0x40048178) GPIO Pin Interrupt Select register */
+  __IO uint32_t USBCLKCTRL;                 /*!< (@ 0x40048198) USB clock control      */
+  __I  uint32_t USBCLKST;                   /*!< (@ 0x4004819C) USB clock status       */
+  __I  uint32_t RESERVED16[25];
+  __IO uint32_t STARTERP0;                  /*!< (@ 0x40048204) Start logic 0 interrupt wake-up enable register 0 */
+  __I  uint32_t RESERVED17[3];
+  __IO uint32_t STARTERP1;                  /*!< (@ 0x40048214) Start logic 1 interrupt wake-up enable register 1 */
+  __I  uint32_t RESERVED18[6];
+  __IO uint32_t PDSLEEPCFG;                 /*!< (@ 0x40048230) Power-down states in deep-sleep mode */
+  __IO uint32_t PDAWAKECFG;                 /*!< (@ 0x40048234) Power-down states for wake-up from deep-sleep */
+  __IO uint32_t PDRUNCFG;                   /*!< (@ 0x40048238) Power configuration register */
+  __I  uint32_t RESERVED19[111];
+  __I  uint32_t DEVICE_ID;                  /*!< (@ 0x400483F8) Device ID              */
+} LPC_SYSCON_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                     GPIO_PIN_INT                                     -----
+// ------------------------------------------------------------------------------------------------
+typedef struct {                            /*!< (@ 0x4004C000) GPIO_PIN_INT Structure */
+  __IO uint32_t ISEL;                       /*!< (@ 0x4004C000) Pin Interrupt Mode register */
+  __IO uint32_t IENR;                       /*!< (@ 0x4004C004) Pin Interrupt Enable (Rising) register */
+  __O  uint32_t SIENR;                      /*!< (@ 0x4004C008) Set Pin Interrupt Enable (Rising) register */
+  __O  uint32_t CIENR;                      /*!< (@ 0x4004C00C) Clear Pin Interrupt Enable (Rising) register */
+  __IO uint32_t IENF;                       /*!< (@ 0x4004C010) Pin Interrupt Enable Falling Edge / Active Level register */
+  __O  uint32_t SIENF;                      /*!< (@ 0x4004C014) Set Pin Interrupt Enable Falling Edge / Active Level register */
+  __O  uint32_t CIENF;                      /*!< (@ 0x4004C018) Clear Pin Interrupt Enable Falling Edge / Active Level address */
+  __IO uint32_t RISE;                       /*!< (@ 0x4004C01C) Pin Interrupt Rising Edge register */
+  __IO uint32_t FALL;                       /*!< (@ 0x4004C020) Pin Interrupt Falling Edge register */
+  __IO uint32_t IST;                        /*!< (@ 0x4004C024) Pin Interrupt Status register */
+} LPC_GPIO_PIN_INT_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                         SSP1                                         -----
+// ------------------------------------------------------------------------------------------------
+typedef struct {                            /*!< (@ 0x40058000) SSP1 Structure         */
+  __IO uint32_t CR0;                        /*!< (@ 0x40058000) Control Register 0. Selects the serial clock rate, bus type, and data size. */
+  __IO uint32_t CR1;                        /*!< (@ 0x40058004) Control Register 1. Selects master/slave and other modes. */
+  __IO uint32_t DR;                         /*!< (@ 0x40058008) Data Register. Writes fill the transmit FIFO, and reads empty the receive FIFO. */
+  __I  uint32_t SR;                         /*!< (@ 0x4005800C) Status Register        */
+  __IO uint32_t CPSR;                       /*!< (@ 0x40058010) Clock Prescale Register */
+  __IO uint32_t IMSC;                       /*!< (@ 0x40058014) Interrupt Mask Set and Clear Register */
+  __I  uint32_t RIS;                        /*!< (@ 0x40058018) Raw Interrupt Status Register */
+  __I  uint32_t MIS;                        /*!< (@ 0x4005801C) Masked Interrupt Status Register */
+  __O  uint32_t ICR;                        /*!< (@ 0x40058020) SSPICR Interrupt Clear Register */
+} LPC_SSP1_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                    GPIO_GROUP_INT0                                   -----
+// ------------------------------------------------------------------------------------------------
+typedef struct {                            /*!< (@ 0x4005C000) GPIO_GROUP_INT0 Structure */
+  __IO uint32_t CTRL;                       /*!< (@ 0x4005C000) GPIO grouped interrupt control register */
+  __I  uint32_t RESERVED0[7];
+  __IO uint32_t PORT_POL[2];                /*!< (@ 0x4005C020) GPIO grouped interrupt port 0 polarity register */
+  __I  uint32_t RESERVED1[6];
+  __IO uint32_t PORT_ENA[2];                /*!< (@ 0x4005C040) GPIO grouped interrupt port 0/1 enable register */
+} LPC_GPIO_GROUP_INT0_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                    GPIO_GROUP_INT1                                   -----
+// ------------------------------------------------------------------------------------------------
+
+typedef struct {                            /*!< (@ 0x40060000) GPIO_GROUP_INT1 Structure */
+  __IO uint32_t CTRL;                       /*!< (@ 0x40060000) GPIO grouped interrupt control register */
+  __I  uint32_t RESERVED0[7];
+  __IO uint32_t PORT_POL[2];                /*!< (@ 0x40060020) GPIO grouped interrupt port 0 polarity register */
+  __I  uint32_t RESERVED1[6];
+  __IO uint32_t PORT_ENA[2];                /*!< (@ 0x40060040) GPIO grouped interrupt port 0/1 enable register */
+} LPC_GPIO_GROUP_INT1_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                          Repetitive Interrupt Timer (RIT)                            -----
+// ------------------------------------------------------------------------------------------------
+
+typedef struct {                            /*!< (@ 0x40064000) RITIMER Structure */
+  __IO uint32_t COMPVAL;                    /*!< (@ 0x40064000) RITIMER compare register */
+  __IO uint32_t MASK;                       /*!< (@ 0x40064004) RITIMER mask register */
+  __IO uint32_t CTRL;                       /*!< (@ 0x40064008) RITIMER control register */
+  __IO uint32_t COUNTER;                    /*!< (@ 0x4006400C) RITIMER counter register */
+  __IO uint32_t COMPVAL_H;                  /*!< (@ 0x40064010) RITIMER compare upper register */
+  __IO uint32_t MASK_H;                     /*!< (@ 0x40064014) RITIMER mask upper register */
+  __I  uint32_t RESERVED0[1];
+  __IO uint32_t COUNTER_H;                  /*!< (@ 0x4006401C) RITIMER counter upper register */
+} LPC_RITIMER_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                          USB                                         -----
+// ------------------------------------------------------------------------------------------------
+typedef struct {                            /*!< (@ 0x40020000) USB Structure          */
+  __IO uint32_t DEVCMDSTAT;                 /*!< (@ 0x40020000) USB Device Command/Status register */
+  __IO uint32_t INFO;                       /*!< (@ 0x40020004) USB Info register      */
+  __IO uint32_t EPLISTSTART;                /*!< (@ 0x40020008) USB EP Command/Status List start address */
+  __IO uint32_t DATABUFSTART;               /*!< (@ 0x4002000C) USB Data buffer start address */
+  __IO uint32_t LPM;                        /*!< (@ 0x40020010) Link Power Management register */
+  __IO uint32_t EPSKIP;                     /*!< (@ 0x40020014) USB Endpoint skip      */
+  __IO uint32_t EPINUSE;                    /*!< (@ 0x40020018) USB Endpoint Buffer in use */
+  __IO uint32_t EPBUFCFG;                   /*!< (@ 0x4002001C) USB Endpoint Buffer Configuration register */
+  __IO uint32_t INTSTAT;                    /*!< (@ 0x40020020) USB interrupt status register */
+  __IO uint32_t INTEN;                      /*!< (@ 0x40020024) USB interrupt enable register */
+  __IO uint32_t INTSETSTAT;                 /*!< (@ 0x40020028) USB set interrupt status register */
+  __IO uint32_t INTROUTING;                 /*!< (@ 0x4002002C) USB interrupt routing register */
+  __I  uint32_t RESERVED0[1];
+  __I  uint32_t EPTOGGLE;                   /*!< (@ 0x40020034) USB Endpoint toggle register */
+} LPC_USB_Type;
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                       GPIO_PORT                                      -----
+// ------------------------------------------------------------------------------------------------
+
+typedef struct {                            /*!< (@ 0x50000000) GPIO_PORT Structure    */
+  union {
+    struct {
+      __IO uint8_t B0[32];                  /*!< (@ 0x50000000) Byte pin registers port 0; pins PIO0_0 to PIO0_31 */
+      __IO uint8_t B1[32];                  /*!< (@ 0x50000020) Byte pin registers port 1 */
+    };
+    __IO uint8_t B[64];                     /*!< (@ 0x50000000) Byte pin registers port 0/1 */
+  };
+  __I  uint32_t RESERVED0[1008];
+  union {
+    struct {
+      __IO uint32_t W0[32];                 /*!< (@ 0x50001000) Word pin registers port 0 */
+      __IO uint32_t W1[32];                 /*!< (@ 0x50001080) Word pin registers port 1 */
+    };
+    __IO uint32_t W[64];                    /*!< (@ 0x50001000) Word pin registers port 0/1 */
+  };
+  __I  uint32_t RESERVED1[960];
+  __IO uint32_t DIR[2];                     /*!< (@ 0x50002000) Direction registers port 0/1 */
+  __I  uint32_t RESERVED2[30];
+  __IO uint32_t MASK[2];                    /*!< (@ 0x50002080) Mask register port 0/1 */
+  __I  uint32_t RESERVED3[30];
+  __IO uint32_t PIN[2];                     /*!< (@ 0x50002100) Portpin register port 0 */
+  __I  uint32_t RESERVED4[30];
+  __IO uint32_t MPIN[2];                    /*!< (@ 0x50002180) Masked port register port 0/1 */
+  __I  uint32_t RESERVED5[30];
+  __IO uint32_t SET[2];                     /*!< (@ 0x50002200) Write: Set register for port 0/1 Read: output bits for port 0/1 */
+  __I  uint32_t RESERVED6[30];
+  __O  uint32_t CLR[2];                     /*!< (@ 0x50002280) Clear port 0/1         */
+  __I  uint32_t RESERVED7[30];
+  __O  uint32_t NOT[2];                     /*!< (@ 0x50002300) Toggle port 0/1        */
+} LPC_GPIO_Type;
+
+
+#if defined ( __CC_ARM   )
+  #pragma no_anon_unions
+#endif
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                 Peripheral memory map                                -----
+// ------------------------------------------------------------------------------------------------
+
+#define LPC_I2C_BASE              (0x40000000)
+#define LPC_WWDT_BASE             (0x40004000)
+#define LPC_USART_BASE            (0x40008000)
+#define LPC_CT16B0_BASE           (0x4000C000)
+#define LPC_CT16B1_BASE           (0x40010000)
+#define LPC_CT32B0_BASE           (0x40014000)
+#define LPC_CT32B1_BASE           (0x40018000)
+#define LPC_ADC_BASE              (0x4001C000)
+#define LPC_PMU_BASE              (0x40038000)
+#define LPC_FLASHCTRL_BASE        (0x4003C000)
+#define LPC_SSP0_BASE             (0x40040000)
+#define LPC_IOCON_BASE            (0x40044000)
+#define LPC_SYSCON_BASE           (0x40048000)
+#define LPC_GPIO_PIN_INT_BASE     (0x4004C000)
+#define LPC_SSP1_BASE             (0x40058000)
+#define LPC_GPIO_GROUP_INT0_BASE  (0x4005C000)
+#define LPC_GPIO_GROUP_INT1_BASE  (0x40060000)
+#define LPC_RITIMER_BASE          (0x40064000)
+#define LPC_USB_BASE              (0x40080000)
+#define LPC_GPIO_BASE             (0x50000000)
+
+
+// ------------------------------------------------------------------------------------------------
+// -----                                Peripheral declaration                                -----
+// ------------------------------------------------------------------------------------------------
+
+#define LPC_I2C                   ((LPC_I2C_Type            *) LPC_I2C_BASE)
+#define LPC_WWDT                  ((LPC_WWDT_Type           *) LPC_WWDT_BASE)
+#define LPC_USART                 ((LPC_USART_Type          *) LPC_USART_BASE)
+#define LPC_CT16B0                ((LPC_CT16B0_Type         *) LPC_CT16B0_BASE)
+#define LPC_CT16B1                ((LPC_CT16B1_Type         *) LPC_CT16B1_BASE)
+#define LPC_CT32B0                ((LPC_CT32B0_Type         *) LPC_CT32B0_BASE)
+#define LPC_CT32B1                ((LPC_CT32B1_Type         *) LPC_CT32B1_BASE)
+#define LPC_ADC                   ((LPC_ADC_Type            *) LPC_ADC_BASE)
+#define LPC_PMU                   ((LPC_PMU_Type            *) LPC_PMU_BASE)
+#define LPC_FLASHCTRL             ((LPC_FLASHCTRL_Type      *) LPC_FLASHCTRL_BASE)
+#define LPC_SSP0                  ((LPC_SSP0_Type           *) LPC_SSP0_BASE)
+#define LPC_SSP1                  ((LPC_SSP1_Type           *) LPC_SSP1_BASE)
+#define LPC_IOCON                 ((LPC_IOCON_Type          *) LPC_IOCON_BASE)
+#define LPC_SYSCON                ((LPC_SYSCON_Type         *) LPC_SYSCON_BASE)
+#define LPC_GPIO_PIN_INT          ((LPC_GPIO_PIN_INT_Type   *) LPC_GPIO_PIN_INT_BASE)
+#define LPC_GPIO_GROUP_INT0       ((LPC_GPIO_GROUP_INT0_Type*) LPC_GPIO_GROUP_INT0_BASE)
+#define LPC_GPIO_GROUP_INT1       ((LPC_GPIO_GROUP_INT1_Type*) LPC_GPIO_GROUP_INT1_BASE)
+#define LPC_RITIMER               ((LPC_RITIMER_Type        *) LPC_RITIMER_BASE)
+#define LPC_USB                   ((LPC_USB_Type            *) LPC_USB_BASE)
+#define LPC_GPIO                  ((LPC_GPIO_Type           *) LPC_GPIO_BASE)
+
+
+/** @} */ /* End of group Device_Peripheral_Registers */
+/** @} */ /* End of group (null) */
+/** @} */ /* End of group h1usf */
+
+#ifdef __cplusplus
+}
+#endif 
+
+
+#endif  // __LPC13UXX_H__
diff --git a/reform2-lpc-fw/cmsis/RTX_CM_lib.h b/reform2-lpc-fw/cmsis/RTX_CM_lib.h
new file mode 100644
index 0000000000000000000000000000000000000000..0365eaba661c4c4215dea945e19622a9ca7b3695
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/RTX_CM_lib.h
@@ -0,0 +1,381 @@
+/*----------------------------------------------------------------------------
+ *      RL-ARM - RTX
+ *----------------------------------------------------------------------------
+ *      Name:    RTX_CM_LIB.H
+ *      Purpose: RTX Kernel System Configuration
+ *      Rev.:    V4.70
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used 
+ *    to endorse or promote products derived from this software without 
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#if   defined (__CC_ARM)
+#pragma O3
+#define __USED __attribute__((used))
+#elif defined (__GNUC__)
+#pragma GCC optimize ("O3")
+#define __USED __attribute__((used))
+#elif defined (__ICCARM__)
+#define __USED __root
+#endif
+
+
+/*----------------------------------------------------------------------------
+ *      Definitions
+ *---------------------------------------------------------------------------*/
+
+#define _declare_box(pool,size,cnt)  uint32_t pool[(((size)+3)/4)*(cnt) + 3]
+#define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2]
+
+#define OS_TCB_SIZE     48
+#define OS_TMR_SIZE     8
+
+#if defined (__CC_ARM) && !defined (__MICROLIB)
+
+typedef void    *OS_ID;
+typedef uint32_t OS_TID;
+typedef uint32_t OS_MUT[3];
+typedef uint32_t OS_RESULT;
+
+#define runtask_id()    rt_tsk_self()
+#define mutex_init(m)   rt_mut_init(m)
+#define mutex_wait(m)   os_mut_wait(m,0xFFFF)
+#define mutex_rel(m)    os_mut_release(m)
+
+extern OS_TID    rt_tsk_self    (void);
+extern void      rt_mut_init    (OS_ID mutex);
+extern OS_RESULT rt_mut_release (OS_ID mutex);
+extern OS_RESULT rt_mut_wait    (OS_ID mutex, uint16_t timeout);
+
+#define os_mut_wait(mutex,timeout) _os_mut_wait((uint32_t)rt_mut_wait,mutex,timeout)
+#define os_mut_release(mutex)      _os_mut_release((uint32_t)rt_mut_release,mutex)
+
+OS_RESULT _os_mut_release (uint32_t p, OS_ID mutex)                   __svc_indirect(0);
+OS_RESULT _os_mut_wait    (uint32_t p, OS_ID mutex, uint16_t timeout) __svc_indirect(0);
+
+#endif
+
+
+/*----------------------------------------------------------------------------
+ *      Global Variables
+ *---------------------------------------------------------------------------*/
+
+#if (OS_TIMERS != 0)
+#define OS_TASK_CNT (OS_TASKCNT + 1)
+#define OS_PRIV_CNT (OS_PRIVCNT + 2)
+#define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE+OS_TIMERSTKSZ))
+#else
+#define OS_TASK_CNT  OS_TASKCNT
+#define OS_PRIV_CNT (OS_PRIVCNT + 1)
+#define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE))
+#endif
+
+uint16_t const os_maxtaskrun = OS_TASK_CNT;
+uint32_t const os_stackinfo  = (OS_STKCHECK<<24)| (OS_PRIV_CNT<<16) | (OS_STKSIZE*4);
+uint32_t const os_rrobin     = (OS_ROBIN << 16) | OS_ROBINTOUT;
+uint32_t const os_tickfreq   = OS_CLOCK;
+uint16_t const os_tickus_i   = OS_CLOCK/1000000;
+uint16_t const os_tickus_f   = (((uint64_t)(OS_CLOCK-1000000*(OS_CLOCK/1000000)))<<16)/1000000;
+uint32_t const os_trv        = OS_TRV;
+uint8_t  const os_flags      = OS_RUNPRIV;
+
+/* Export following defines to uVision debugger. */
+__USED uint32_t const os_clockrate = OS_TICK;
+__USED uint32_t const os_timernum  = 0;
+
+/* Memory pool for TCB allocation    */
+_declare_box  (mp_tcb, OS_TCB_SIZE, OS_TASK_CNT);
+uint16_t const mp_tcb_size = sizeof(mp_tcb);
+
+/* Memory pool for System stack allocation (+os_idle_demon). */
+_declare_box8 (mp_stk, OS_STKSIZE*4, OS_TASK_CNT-OS_PRIV_CNT+1);
+uint32_t const mp_stk_size = sizeof(mp_stk);
+
+/* Memory pool for user specified stack allocation (+main, +timer) */
+uint64_t       os_stack_mem[2+OS_PRIV_CNT+(OS_STACK_SZ/8)];
+uint32_t const os_stack_sz = sizeof(os_stack_mem);
+
+#ifndef OS_FIFOSZ
+ #define OS_FIFOSZ      16
+#endif
+
+/* Fifo Queue buffer for ISR requests.*/
+uint32_t       os_fifo[OS_FIFOSZ*2+1];
+uint8_t  const os_fifo_size = OS_FIFOSZ;
+
+/* An array of Active task pointers. */
+void *os_active_TCB[OS_TASK_CNT];
+
+/* User Timers Resources */
+#if (OS_TIMERS != 0)
+extern void osTimerThread (void const *argument);
+osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 1, 4*OS_TIMERSTKSZ);
+osThreadId osThreadId_osTimerThread;
+osMessageQDef(osTimerMessageQ, OS_TIMERCBQS, void *);
+osMessageQId osMessageQId_osTimerMessageQ;
+#else
+osThreadDef_t os_thread_def_osTimerThread = { NULL };
+osThreadId osThreadId_osTimerThread;
+osMessageQDef(osTimerMessageQ, 0, void *);
+osMessageQId osMessageQId_osTimerMessageQ;
+#endif
+
+/* Legacy RTX User Timers not used */
+uint32_t       os_tmr = 0; 
+uint32_t const *m_tmr = NULL;
+uint16_t const mp_tmr_size = 0;
+
+#if defined (__CC_ARM) && !defined (__MICROLIB)
+ /* A memory space for arm standard library. */
+ static uint32_t std_libspace[OS_TASK_CNT][96/4];
+ static OS_MUT   std_libmutex[OS_MUTEXCNT];
+ static uint32_t nr_mutex;
+ extern void  *__libspace_start;
+#endif
+
+
+/*----------------------------------------------------------------------------
+ *      RTX Optimizations (empty functions)
+ *---------------------------------------------------------------------------*/
+
+#if OS_ROBIN == 0
+ void rt_init_robin (void) {;}
+ void rt_chk_robin  (void) {;}
+#endif
+
+#if OS_STKCHECK == 0
+ void rt_stk_check  (void) {;}
+#endif
+
+
+/*----------------------------------------------------------------------------
+ *      Standard Library multithreading interface
+ *---------------------------------------------------------------------------*/
+
+#if defined (__CC_ARM) && !defined (__MICROLIB)
+
+/*--------------------------- __user_perthread_libspace ---------------------*/
+
+void *__user_perthread_libspace (void) {
+  /* Provide a separate libspace for each task. */
+  uint32_t idx;
+
+  idx = runtask_id ();
+  if (idx == 0) {
+    /* RTX not running yet. */
+    return (&__libspace_start);
+  }
+  return ((void *)&std_libspace[idx-1]);
+}
+
+/*--------------------------- _mutex_initialize -----------------------------*/
+
+int _mutex_initialize (OS_ID *mutex) {
+  /* Allocate and initialize a system mutex. */
+
+  if (nr_mutex >= OS_MUTEXCNT) {
+    /* If you are here, you need to increase the number OS_MUTEXCNT. */
+    for (;;);
+  }
+  *mutex = &std_libmutex[nr_mutex++];
+  mutex_init (*mutex);
+  return (1);
+}
+
+
+/*--------------------------- _mutex_acquire --------------------------------*/
+
+__attribute__((used)) void _mutex_acquire (OS_ID *mutex) {
+  /* Acquire a system mutex, lock stdlib resources. */
+  if (runtask_id ()) {
+    /* RTX running, acquire a mutex. */
+    mutex_wait (*mutex);
+  }
+}
+
+
+/*--------------------------- _mutex_release --------------------------------*/
+
+__attribute__((used)) void _mutex_release (OS_ID *mutex) {
+  /* Release a system mutex, unlock stdlib resources. */
+  if (runtask_id ()) {
+    /* RTX running, release a mutex. */
+    mutex_rel (*mutex);
+  }
+}
+
+#endif
+
+#if 0
+/*----------------------------------------------------------------------------
+ *      RTX Startup
+ *---------------------------------------------------------------------------*/
+
+/* Main Thread definition */
+extern int main (void);
+osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 1, 4*OS_MAINSTKSIZE };
+
+
+#if defined (__CC_ARM)
+
+#ifdef __MICROLIB
+void _main_init (void) __attribute__((section(".ARM.Collect$$$$000000FF")));
+void _main_init (void) {
+  osKernelInitialize();
+  osThreadCreate(&os_thread_def_main, NULL);
+  osKernelStart();
+  for (;;);
+}
+#else
+__asm void __rt_entry (void) {
+
+  IMPORT  __user_setup_stackheap
+  IMPORT  __rt_lib_init
+  IMPORT  os_thread_def_main
+  IMPORT  osKernelInitialize
+  IMPORT  osKernelStart
+  IMPORT  osThreadCreate
+  IMPORT  exit
+
+  BL      __user_setup_stackheap
+  MOV     R1,R2
+  BL      __rt_lib_init
+  BL      osKernelInitialize
+  LDR     R0,=os_thread_def_main
+  MOVS    R1,#0
+  BL      osThreadCreate
+  BL      osKernelStart
+  BL      exit
+
+  ALIGN
+}
+#endif
+
+#elif defined (__GNUC__)
+
+#ifdef __CS3__
+
+/* CS3 start_c routine.
+ *
+ * Copyright (c) 2006, 2007 CodeSourcery Inc
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include "cs3.h"
+
+extern void __libc_init_array (void);
+
+__attribute ((noreturn)) void __cs3_start_c (void){
+  unsigned regions = __cs3_region_num;
+  const struct __cs3_region *rptr = __cs3_regions;
+
+  /* Initialize memory */
+  for (regions = __cs3_region_num, rptr = __cs3_regions; regions--; rptr++) {
+    long long *src = (long long *)rptr->init;
+    long long *dst = (long long *)rptr->data;
+    unsigned limit = rptr->init_size;
+    unsigned count;
+
+    if (src != dst)
+      for (count = 0; count != limit; count += sizeof (long long))
+        *dst++ = *src++;
+    else 
+      dst = (long long *)((char *)dst + limit);
+    limit = rptr->zero_size;
+    for (count = 0; count != limit; count += sizeof (long long))
+      *dst++ = 0;
+  }
+
+  /* Run initializers.  */
+  __libc_init_array ();
+
+  osKernelInitialize();
+  osThreadCreate(&os_thread_def_main, NULL);
+  osKernelStart();
+  for (;;);
+}
+
+#else
+
+__attribute__((naked)) void software_init_hook (void) {
+  __asm (
+    ".syntax unified\n"
+    ".thumb\n"
+    "movs r0,#0\n"
+    "movs r1,#0\n"
+    "mov  r4,r0\n"
+    "mov  r5,r1\n"
+    "ldr  r0,= __libc_fini_array\n"
+    "bl   atexit\n"
+    "bl   __libc_init_array\n"
+    "mov  r0,r4\n"
+    "mov  r1,r5\n"
+    "bl   osKernelInitialize\n"
+    "ldr  r0,=os_thread_def_main\n"
+    "movs r1,#0\n"
+    "bl   osThreadCreate\n"
+    "bl   osKernelStart\n"
+    "bl   exit\n"
+  );
+}
+
+#endif
+
+#elif defined (__ICCARM__)
+
+extern int  __low_level_init(void);
+extern void __iar_data_init3(void);
+extern void exit(int arg);
+
+__noreturn __stackless void __cmain(void) {
+  int a;
+  
+  if (__low_level_init() != 0) {
+    __iar_data_init3();
+  }
+  osKernelInitialize();
+  osThreadCreate(&os_thread_def_main, NULL);
+  a = osKernelStart();
+  exit(a);
+}
+
+#endif
+
+#endif
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+
diff --git a/reform2-lpc-fw/cmsis/RTX_hook.c b/reform2-lpc-fw/cmsis/RTX_hook.c
new file mode 100644
index 0000000000000000000000000000000000000000..21d9908bf90d67c75053f82891626874b2e09d1f
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/RTX_hook.c
@@ -0,0 +1,104 @@
+/**************************************************************************/
+/*!
+    @file     rtx_hook.c
+    @author   Hau Huynh
+
+    @brief    Board file for the LPC1347 LPCXpresso board from NXP
+    @ingroup  Boards
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012 K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#if defined CFG_CMSIS_RTOS
+/*----------------------------------------------------------------------------
+ *      Global Functions
+ *---------------------------------------------------------------------------*/
+
+/*--------------------------- os_idle_demon ---------------------------------*/
+
+void os_idle_demon (void) {
+  /* The idle demon is a system thread, running when no other thread is      */
+  /* ready to run.                                                           */
+
+  for (;;) {
+    /* HERE: include optional user code to be executed when no thread runs.*/
+  }
+}
+
+#if (OS_SYSTICK == 0)   // Functions for alternative timer as RTX kernel timer
+
+/*--------------------------- os_tick_init ----------------------------------*/
+
+// Initialize alternative hardware timer as RTX kernel timer
+// Return: IRQ number of the alternative hardware timer
+int os_tick_init (void) {
+  return (-1);  /* Return IRQ number of timer (0..239) */
+}
+
+/*--------------------------- os_tick_val -----------------------------------*/
+
+// Get alternative hardware timer current value (0 .. OS_TRV)
+uint32_t os_tick_val (void) {
+  return (0);
+}
+
+/*--------------------------- os_tick_ovf -----------------------------------*/
+
+// Get alternative hardware timer overflow flag
+// Return: 1 - overflow, 0 - no overflow
+uint32_t os_tick_ovf (void) {
+  return (0);
+}
+
+/*--------------------------- os_tick_irqack --------------------------------*/
+
+// Acknowledge alternative hardware timer interrupt
+void os_tick_irqack (void) {
+  /* ... */
+}
+
+#endif   // (OS_SYSTICK == 0)
+
+/*--------------------------- os_error --------------------------------------*/
+
+void os_error (uint32_t err_code) {
+  /* This function is called when a runtime error is detected. Parameter */
+  /* 'err_code' holds the runtime error code (defined in RTL.H).         */
+
+  /* HERE: include optional code to be executed on runtime error. */
+  for (;;);
+}
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+#endif
diff --git a/reform2-lpc-fw/cmsis/arm_common_tables.h b/reform2-lpc-fw/cmsis/arm_common_tables.h
new file mode 100644
index 0000000000000000000000000000000000000000..7a59b5923e9edcfc684691f70cb06360d20ddfff
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/arm_common_tables.h
@@ -0,0 +1,93 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
+*
+* $Date:        17. January 2013
+* $Revision:    V1.4.1
+*
+* Project:      CMSIS DSP Library
+* Title:        arm_common_tables.h
+*
+* Description:  This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions
+*
+* Target Processor: Cortex-M4/Cortex-M3
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*   - Redistributions of source code must retain the above copyright
+*     notice, this list of conditions and the following disclaimer.
+*   - Redistributions in binary form must reproduce the above copyright
+*     notice, this list of conditions and the following disclaimer in
+*     the documentation and/or other materials provided with the
+*     distribution.
+*   - Neither the name of ARM LIMITED nor the names of its contributors
+*     may be used to endorse or promote products derived from this
+*     software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+* -------------------------------------------------------------------- */
+
+#ifndef _ARM_COMMON_TABLES_H
+#define _ARM_COMMON_TABLES_H
+
+#include "arm_math.h"
+
+extern const uint16_t armBitRevTable[1024];
+extern const q15_t armRecipTableQ15[64];
+extern const q31_t armRecipTableQ31[64];
+extern const q31_t realCoefAQ31[1024];
+extern const q31_t realCoefBQ31[1024];
+extern const float32_t twiddleCoef_16[32];
+extern const float32_t twiddleCoef_32[64];
+extern const float32_t twiddleCoef_64[128];
+extern const float32_t twiddleCoef_128[256];
+extern const float32_t twiddleCoef_256[512];
+extern const float32_t twiddleCoef_512[1024];
+extern const float32_t twiddleCoef_1024[2048];
+extern const float32_t twiddleCoef_2048[4096];
+extern const float32_t twiddleCoef_4096[8192];
+#define twiddleCoef twiddleCoef_4096
+extern const q31_t twiddleCoefQ31[6144];
+extern const q15_t twiddleCoefQ15[6144];
+extern const float32_t twiddleCoef_rfft_32[32];
+extern const float32_t twiddleCoef_rfft_64[64];
+extern const float32_t twiddleCoef_rfft_128[128];
+extern const float32_t twiddleCoef_rfft_256[256];
+extern const float32_t twiddleCoef_rfft_512[512];
+extern const float32_t twiddleCoef_rfft_1024[1024];
+extern const float32_t twiddleCoef_rfft_2048[2048];
+extern const float32_t twiddleCoef_rfft_4096[4096];
+
+
+#define ARMBITREVINDEXTABLE__16_TABLE_LENGTH ((uint16_t)20  )
+#define ARMBITREVINDEXTABLE__32_TABLE_LENGTH ((uint16_t)48  )
+#define ARMBITREVINDEXTABLE__64_TABLE_LENGTH ((uint16_t)56  )
+#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 )
+#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 )
+#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 )
+#define ARMBITREVINDEXTABLE1024_TABLE_LENGTH ((uint16_t)1800)
+#define ARMBITREVINDEXTABLE2048_TABLE_LENGTH ((uint16_t)3808)
+#define ARMBITREVINDEXTABLE4096_TABLE_LENGTH ((uint16_t)4032)
+
+extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE__16_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE__32_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE__64_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE1024_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE2048_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE4096_TABLE_LENGTH];
+
+#endif /*  ARM_COMMON_TABLES_H */
diff --git a/reform2-lpc-fw/cmsis/arm_const_structs.h b/reform2-lpc-fw/cmsis/arm_const_structs.h
new file mode 100644
index 0000000000000000000000000000000000000000..8d7fac0f04e7b971161600376203961b9f9395b7
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/arm_const_structs.h
@@ -0,0 +1,85 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
+*
+* $Date:        17. January 2013
+* $Revision:    V1.4.1
+*
+* Project:      CMSIS DSP Library
+* Title:        arm_const_structs.h
+*
+* Description:  This file has constant structs that are initialized for
+*               user convenience.  For example, some can be given as
+*               arguments to the arm_cfft_f32() function.
+*
+* Target Processor: Cortex-M4/Cortex-M3
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*   - Redistributions of source code must retain the above copyright
+*     notice, this list of conditions and the following disclaimer.
+*   - Redistributions in binary form must reproduce the above copyright
+*     notice, this list of conditions and the following disclaimer in
+*     the documentation and/or other materials provided with the
+*     distribution.
+*   - Neither the name of ARM LIMITED nor the names of its contributors
+*     may be used to endorse or promote products derived from this
+*     software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+* -------------------------------------------------------------------- */
+
+#ifndef _ARM_CONST_STRUCTS_H
+#define _ARM_CONST_STRUCTS_H
+
+#include "arm_math.h"
+#include "arm_common_tables.h"
+
+   const arm_cfft_instance_f32 arm_cfft_sR_f32_len16 = {
+      16, twiddleCoef_16, armBitRevIndexTable16, ARMBITREVINDEXTABLE__16_TABLE_LENGTH
+   };
+
+   const arm_cfft_instance_f32 arm_cfft_sR_f32_len32 = {
+      32, twiddleCoef_32, armBitRevIndexTable32, ARMBITREVINDEXTABLE__32_TABLE_LENGTH
+   };
+
+   const arm_cfft_instance_f32 arm_cfft_sR_f32_len64 = {
+      64, twiddleCoef_64, armBitRevIndexTable64, ARMBITREVINDEXTABLE__64_TABLE_LENGTH
+   };
+
+   const arm_cfft_instance_f32 arm_cfft_sR_f32_len128 = {
+      128, twiddleCoef_128, armBitRevIndexTable128, ARMBITREVINDEXTABLE_128_TABLE_LENGTH
+   };
+
+   const arm_cfft_instance_f32 arm_cfft_sR_f32_len256 = {
+      256, twiddleCoef_256, armBitRevIndexTable256, ARMBITREVINDEXTABLE_256_TABLE_LENGTH
+   };
+
+   const arm_cfft_instance_f32 arm_cfft_sR_f32_len512 = {
+      512, twiddleCoef_512, armBitRevIndexTable512, ARMBITREVINDEXTABLE_512_TABLE_LENGTH
+   };
+
+   const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024 = {
+      1024, twiddleCoef_1024, armBitRevIndexTable1024, ARMBITREVINDEXTABLE1024_TABLE_LENGTH
+   };
+
+   const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048 = {
+      2048, twiddleCoef_2048, armBitRevIndexTable2048, ARMBITREVINDEXTABLE2048_TABLE_LENGTH
+   };
+
+   const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096 = {
+      4096, twiddleCoef_4096, armBitRevIndexTable4096, ARMBITREVINDEXTABLE4096_TABLE_LENGTH
+   };
+
+#endif
diff --git a/reform2-lpc-fw/cmsis/arm_math.h b/reform2-lpc-fw/cmsis/arm_math.h
new file mode 100644
index 0000000000000000000000000000000000000000..65304c127d6c5ad0a49cab6b0c30be220035a16a
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/arm_math.h
@@ -0,0 +1,7306 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
+*
+* $Date:        17. January 2013
+* $Revision:    V1.4.1
+*
+* Project:      CMSIS DSP Library
+* Title:        arm_math.h
+*
+* Description:  Public header file for CMSIS DSP Library
+*
+* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*   - Redistributions of source code must retain the above copyright
+*     notice, this list of conditions and the following disclaimer.
+*   - Redistributions in binary form must reproduce the above copyright
+*     notice, this list of conditions and the following disclaimer in
+*     the documentation and/or other materials provided with the
+*     distribution.
+*   - Neither the name of ARM LIMITED nor the names of its contributors
+*     may be used to endorse or promote products derived from this
+*     software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+ * -------------------------------------------------------------------- */
+
+/**
+   \mainpage CMSIS DSP Software Library
+   *
+   * <b>Introduction</b>
+   *
+   * This user manual describes the CMSIS DSP software library,
+   * a suite of common signal processing functions for use on Cortex-M processor based devices.
+   *
+   * The library is divided into a number of functions each covering a specific category:
+   * - Basic math functions
+   * - Fast math functions
+   * - Complex math functions
+   * - Filters
+   * - Matrix functions
+   * - Transforms
+   * - Motor control functions
+   * - Statistical functions
+   * - Support functions
+   * - Interpolation functions
+   *
+   * The library has separate functions for operating on 8-bit integers, 16-bit integers,
+   * 32-bit integer and 32-bit floating-point values.
+   *
+   * <b>Using the Library</b>
+   *
+   * The library installer contains prebuilt versions of the libraries in the <code>Lib</code> folder.
+   * - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4)
+   * - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4)
+   * - arm_cortexM4l_math.lib (Little endian on Cortex-M4)
+   * - arm_cortexM4b_math.lib (Big endian on Cortex-M4)
+   * - arm_cortexM3l_math.lib (Little endian on Cortex-M3)
+   * - arm_cortexM3b_math.lib (Big endian on Cortex-M3)
+   * - arm_cortexM0l_math.lib (Little endian on Cortex-M0)
+   * - arm_cortexM0b_math.lib (Big endian on Cortex-M3)
+   *
+   * The library functions are declared in the public file <code>arm_math.h</code> which is placed in the <code>Include</code> folder.
+   * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single
+   * public header file <code> arm_math.h</code> for Cortex-M4/M3/M0 with little endian and big endian. Same header file will be used for floating point unit(FPU) variants.
+   * Define the appropriate pre processor MACRO ARM_MATH_CM4 or  ARM_MATH_CM3 or
+   * ARM_MATH_CM0 or ARM_MATH_CM0PLUS depending on the target processor in the application.
+   *
+   * <b>Examples</b>
+   *
+   * The library ships with a number of examples which demonstrate how to use the library functions.
+   *
+   * <b>Toolchain Support</b>
+   *
+   * The library has been developed and tested with MDK-ARM version 4.60.
+   * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly.
+   *
+   * <b>Building the Library</b>
+   *
+   * The library installer contains project files to re build libraries on MDK Tool chain in the <code>CMSIS\\DSP_Lib\\Source\\ARM</code> folder.
+   * - arm_cortexM0b_math.uvproj
+   * - arm_cortexM0l_math.uvproj
+   * - arm_cortexM3b_math.uvproj
+   * - arm_cortexM3l_math.uvproj
+   * - arm_cortexM4b_math.uvproj
+   * - arm_cortexM4l_math.uvproj
+   * - arm_cortexM4bf_math.uvproj
+   * - arm_cortexM4lf_math.uvproj
+   *
+   *
+   * The project can be built by opening the appropriate project in MDK-ARM 4.60 chain and defining the optional pre processor MACROs detailed above.
+   *
+   * <b>Pre-processor Macros</b>
+   *
+   * Each library project have differant pre-processor macros.
+   *
+   * - UNALIGNED_SUPPORT_DISABLE:
+   *
+   * Define macro UNALIGNED_SUPPORT_DISABLE, If the silicon does not support unaligned memory access
+   *
+   * - ARM_MATH_BIG_ENDIAN:
+   *
+   * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets.
+   *
+   * - ARM_MATH_MATRIX_CHECK:
+   *
+   * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices
+   *
+   * - ARM_MATH_ROUNDING:
+   *
+   * Define macro ARM_MATH_ROUNDING for rounding on support functions
+   *
+   * - ARM_MATH_CMx:
+   *
+   * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target
+   * and ARM_MATH_CM0 for building library on cortex-M0 target, ARM_MATH_CM0PLUS for building library on cortex-M0+ target.
+   *
+   * - __FPU_PRESENT:
+   *
+   * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for M4bf and M4lf libraries
+   *
+   * <b>Copyright Notice</b>
+   *
+   * Copyright (C) 2010-2013 ARM Limited. All rights reserved.
+   */
+
+
+/**
+ * @defgroup groupMath Basic Math Functions
+ */
+
+/**
+ * @defgroup groupFastMath Fast Math Functions
+ * This set of functions provides a fast approximation to sine, cosine, and square root.
+ * As compared to most of the other functions in the CMSIS math library, the fast math functions
+ * operate on individual values and not arrays.
+ * There are separate functions for Q15, Q31, and floating-point data.
+ *
+ */
+
+/**
+ * @defgroup groupCmplxMath Complex Math Functions
+ * This set of functions operates on complex data vectors.
+ * The data in the complex arrays is stored in an interleaved fashion
+ * (real, imag, real, imag, ...).
+ * In the API functions, the number of samples in a complex array refers
+ * to the number of complex values; the array contains twice this number of
+ * real values.
+ */
+
+/**
+ * @defgroup groupFilters Filtering Functions
+ */
+
+/**
+ * @defgroup groupMatrix Matrix Functions
+ *
+ * This set of functions provides basic matrix math operations.
+ * The functions operate on matrix data structures.  For example,
+ * the type
+ * definition for the floating-point matrix structure is shown
+ * below:
+ * <pre>
+ *     typedef struct
+ *     {
+ *       uint16_t numRows;     // number of rows of the matrix.
+ *       uint16_t numCols;     // number of columns of the matrix.
+ *       float32_t *pData;     // points to the data of the matrix.
+ *     } arm_matrix_instance_f32;
+ * </pre>
+ * There are similar definitions for Q15 and Q31 data types.
+ *
+ * The structure specifies the size of the matrix and then points to
+ * an array of data.  The array is of size <code>numRows X numCols</code>
+ * and the values are arranged in row order.  That is, the
+ * matrix element (i, j) is stored at:
+ * <pre>
+ *     pData[i*numCols + j]
+ * </pre>
+ *
+ * \par Init Functions
+ * There is an associated initialization function for each type of matrix
+ * data structure.
+ * The initialization function sets the values of the internal structure fields.
+ * Refer to the function <code>arm_mat_init_f32()</code>, <code>arm_mat_init_q31()</code>
+ * and <code>arm_mat_init_q15()</code> for floating-point, Q31 and Q15 types,  respectively.
+ *
+ * \par
+ * Use of the initialization function is optional. However, if initialization function is used
+ * then the instance structure cannot be placed into a const data section.
+ * To place the instance structure in a const data
+ * section, manually initialize the data structure.  For example:
+ * <pre>
+ * <code>arm_matrix_instance_f32 S = {nRows, nColumns, pData};</code>
+ * <code>arm_matrix_instance_q31 S = {nRows, nColumns, pData};</code>
+ * <code>arm_matrix_instance_q15 S = {nRows, nColumns, pData};</code>
+ * </pre>
+ * where <code>nRows</code> specifies the number of rows, <code>nColumns</code>
+ * specifies the number of columns, and <code>pData</code> points to the
+ * data array.
+ *
+ * \par Size Checking
+ * By default all of the matrix functions perform size checking on the input and
+ * output matrices.  For example, the matrix addition function verifies that the
+ * two input matrices and the output matrix all have the same number of rows and
+ * columns.  If the size check fails the functions return:
+ * <pre>
+ *     ARM_MATH_SIZE_MISMATCH
+ * </pre>
+ * Otherwise the functions return
+ * <pre>
+ *     ARM_MATH_SUCCESS
+ * </pre>
+ * There is some overhead associated with this matrix size checking.
+ * The matrix size checking is enabled via the \#define
+ * <pre>
+ *     ARM_MATH_MATRIX_CHECK
+ * </pre>
+ * within the library project settings.  By default this macro is defined
+ * and size checking is enabled.  By changing the project settings and
+ * undefining this macro size checking is eliminated and the functions
+ * run a bit faster.  With size checking disabled the functions always
+ * return <code>ARM_MATH_SUCCESS</code>.
+ */
+
+/**
+ * @defgroup groupTransforms Transform Functions
+ */
+
+/**
+ * @defgroup groupController Controller Functions
+ */
+
+/**
+ * @defgroup groupStats Statistics Functions
+ */
+/**
+ * @defgroup groupSupport Support Functions
+ */
+
+/**
+ * @defgroup groupInterpolation Interpolation Functions
+ * These functions perform 1- and 2-dimensional interpolation of data.
+ * Linear interpolation is used for 1-dimensional data and
+ * bilinear interpolation is used for 2-dimensional data.
+ */
+
+/**
+ * @defgroup groupExamples Examples
+ */
+#ifndef _ARM_MATH_H
+#define _ARM_MATH_H
+
+#define __CMSIS_GENERIC         /* disable NVIC and Systick functions */
+
+#if defined (ARM_MATH_CM4)
+#include "core_cm4.h"
+#elif defined (ARM_MATH_CM3)
+#include "core_cm3.h"
+#elif defined (ARM_MATH_CM0)
+#include "core_cm0.h"
+#define ARM_MATH_CM0_FAMILY
+#elif defined (ARM_MATH_CM0PLUS)
+#include "core_cm0plus.h"
+#define ARM_MATH_CM0_FAMILY
+#else
+#include "ARMCM4.h"
+#warning "Define either ARM_MATH_CM4 OR ARM_MATH_CM3...By Default building on ARM_MATH_CM4....."
+#endif
+
+#undef  __CMSIS_GENERIC         /* enable NVIC and Systick functions */
+#include "string.h"
+#include "math.h"
+#ifdef	__cplusplus
+extern "C"
+{
+#endif
+
+
+  /**
+   * @brief Macros required for reciprocal calculation in Normalized LMS
+   */
+
+#define DELTA_Q31 			(0x100)
+#define DELTA_Q15 			0x5
+#define INDEX_MASK 			0x0000003F
+#ifndef PI
+#define PI					3.14159265358979f
+#endif
+
+  /**
+   * @brief Macros required for SINE and COSINE Fast math approximations
+   */
+
+#define TABLE_SIZE			256
+#define TABLE_SPACING_Q31	0x800000
+#define TABLE_SPACING_Q15	0x80
+
+  /**
+   * @brief Macros required for SINE and COSINE Controller functions
+   */
+  /* 1.31(q31) Fixed value of 2/360 */
+  /* -1 to +1 is divided into 360 values so total spacing is (2/360) */
+#define INPUT_SPACING			0xB60B61
+
+  /**
+   * @brief Macro for Unaligned Support
+   */
+#ifndef UNALIGNED_SUPPORT_DISABLE
+    #define ALIGN4
+#else
+  #if defined  (__GNUC__)
+    #define ALIGN4 __attribute__((aligned(4)))
+  #else
+    #define ALIGN4 __align(4)
+  #endif
+#endif	/*	#ifndef UNALIGNED_SUPPORT_DISABLE	*/
+
+  /**
+   * @brief Error status returned by some functions in the library.
+   */
+
+  typedef enum
+  {
+    ARM_MATH_SUCCESS = 0,                /**< No error */
+    ARM_MATH_ARGUMENT_ERROR = -1,        /**< One or more arguments are incorrect */
+    ARM_MATH_LENGTH_ERROR = -2,          /**< Length of data buffer is incorrect */
+    ARM_MATH_SIZE_MISMATCH = -3,         /**< Size of matrices is not compatible with the operation. */
+    ARM_MATH_NANINF = -4,                /**< Not-a-number (NaN) or infinity is generated */
+    ARM_MATH_SINGULAR = -5,              /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */
+    ARM_MATH_TEST_FAILURE = -6           /**< Test Failed  */
+  } arm_status;
+
+  /**
+   * @brief 8-bit fractional data type in 1.7 format.
+   */
+  typedef int8_t q7_t;
+
+  /**
+   * @brief 16-bit fractional data type in 1.15 format.
+   */
+  typedef int16_t q15_t;
+
+  /**
+   * @brief 32-bit fractional data type in 1.31 format.
+   */
+  typedef int32_t q31_t;
+
+  /**
+   * @brief 64-bit fractional data type in 1.63 format.
+   */
+  typedef int64_t q63_t;
+
+  /**
+   * @brief 32-bit floating-point type definition.
+   */
+  typedef float float32_t;
+
+  /**
+   * @brief 64-bit floating-point type definition.
+   */
+  typedef double float64_t;
+
+  /**
+   * @brief definition to read/write two 16 bit values.
+   */
+#if defined __CC_ARM
+#define __SIMD32_TYPE int32_t __packed
+#define CMSIS_UNUSED __attribute__((unused))
+#elif defined __ICCARM__
+#define CMSIS_UNUSED
+#define __SIMD32_TYPE int32_t __packed
+#elif defined __GNUC__
+#define __SIMD32_TYPE int32_t
+#define CMSIS_UNUSED __attribute__((unused))
+#else
+#error Unknown compiler
+#endif
+
+#define __SIMD32(addr)  (*(__SIMD32_TYPE **) & (addr))
+#define __SIMD32_CONST(addr)  ((__SIMD32_TYPE *)(addr))
+
+#define _SIMD32_OFFSET(addr)  (*(__SIMD32_TYPE *)  (addr))
+
+#define __SIMD64(addr)  (*(int64_t **) & (addr))
+
+#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY)
+  /**
+   * @brief definition to pack two 16 bit values.
+   */
+#define __PKHBT(ARG1, ARG2, ARG3)      ( (((int32_t)(ARG1) <<  0) & (int32_t)0x0000FFFF) | \
+                                         (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000)  )
+#define __PKHTB(ARG1, ARG2, ARG3)      ( (((int32_t)(ARG1) <<  0) & (int32_t)0xFFFF0000) | \
+                                         (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF)  )
+
+#endif
+
+
+   /**
+   * @brief definition to pack four 8 bit values.
+   */
+#ifndef ARM_MATH_BIG_ENDIAN
+
+#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) <<  0) & (int32_t)0x000000FF) |	\
+                                (((int32_t)(v1) <<  8) & (int32_t)0x0000FF00) |	\
+							    (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) |	\
+							    (((int32_t)(v3) << 24) & (int32_t)0xFF000000)  )
+#else
+
+#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) <<  0) & (int32_t)0x000000FF) |	\
+                                (((int32_t)(v2) <<  8) & (int32_t)0x0000FF00) |	\
+							    (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) |	\
+							    (((int32_t)(v0) << 24) & (int32_t)0xFF000000)  )
+
+#endif
+
+
+  /**
+   * @brief Clips Q63 to Q31 values.
+   */
+  static __INLINE q31_t clip_q63_to_q31(
+  q63_t x)
+  {
+    return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ?
+      ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x;
+  }
+
+  /**
+   * @brief Clips Q63 to Q15 values.
+   */
+  static __INLINE q15_t clip_q63_to_q15(
+  q63_t x)
+  {
+    return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ?
+      ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15);
+  }
+
+  /**
+   * @brief Clips Q31 to Q7 values.
+   */
+  static __INLINE q7_t clip_q31_to_q7(
+  q31_t x)
+  {
+    return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ?
+      ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x;
+  }
+
+  /**
+   * @brief Clips Q31 to Q15 values.
+   */
+  static __INLINE q15_t clip_q31_to_q15(
+  q31_t x)
+  {
+    return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ?
+      ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x;
+  }
+
+  /**
+   * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format.
+   */
+
+  static __INLINE q63_t mult32x64(
+  q63_t x,
+  q31_t y)
+  {
+    return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) +
+            (((q63_t) (x >> 32) * y)));
+  }
+
+
+#if defined (ARM_MATH_CM0_FAMILY) && defined ( __CC_ARM   )
+#define __CLZ __clz
+#endif
+
+#if defined (ARM_MATH_CM0_FAMILY) && ((defined (__ICCARM__)) ||(defined (__GNUC__)) || defined (__TASKING__) )
+
+  static __INLINE uint32_t __CLZ(
+  q31_t data);
+
+
+  static __INLINE uint32_t __CLZ(
+  q31_t data)
+  {
+    uint32_t count = 0;
+    uint32_t mask = 0x80000000;
+
+    while((data & mask) == 0)
+    {
+      count += 1u;
+      mask = mask >> 1u;
+    }
+
+    return (count);
+
+  }
+
+#endif
+
+  /**
+   * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type.
+   */
+
+  static __INLINE uint32_t arm_recip_q31(
+  q31_t in,
+  q31_t * dst,
+  q31_t * pRecipTable)
+  {
+
+    uint32_t out, tempVal;
+    uint32_t index, i;
+    uint32_t signBits;
+
+    if(in > 0)
+    {
+      signBits = __CLZ(in) - 1;
+    }
+    else
+    {
+      signBits = __CLZ(-in) - 1;
+    }
+
+    /* Convert input sample to 1.31 format */
+    in = in << signBits;
+
+    /* calculation of index for initial approximated Val */
+    index = (uint32_t) (in >> 24u);
+    index = (index & INDEX_MASK);
+
+    /* 1.31 with exp 1 */
+    out = pRecipTable[index];
+
+    /* calculation of reciprocal value */
+    /* running approximation for two iterations */
+    for (i = 0u; i < 2u; i++)
+    {
+      tempVal = (q31_t) (((q63_t) in * out) >> 31u);
+      tempVal = 0x7FFFFFFF - tempVal;
+      /*      1.31 with exp 1 */
+      //out = (q31_t) (((q63_t) out * tempVal) >> 30u);
+      out = (q31_t) clip_q63_to_q31(((q63_t) out * tempVal) >> 30u);
+    }
+
+    /* write output */
+    *dst = out;
+
+    /* return num of signbits of out = 1/in value */
+    return (signBits + 1u);
+
+  }
+
+  /**
+   * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type.
+   */
+  static __INLINE uint32_t arm_recip_q15(
+  q15_t in,
+  q15_t * dst,
+  q15_t * pRecipTable)
+  {
+
+    uint32_t out = 0, tempVal = 0;
+    uint32_t index = 0, i = 0;
+    uint32_t signBits = 0;
+
+    if(in > 0)
+    {
+      signBits = __CLZ(in) - 17;
+    }
+    else
+    {
+      signBits = __CLZ(-in) - 17;
+    }
+
+    /* Convert input sample to 1.15 format */
+    in = in << signBits;
+
+    /* calculation of index for initial approximated Val */
+    index = in >> 8;
+    index = (index & INDEX_MASK);
+
+    /*      1.15 with exp 1  */
+    out = pRecipTable[index];
+
+    /* calculation of reciprocal value */
+    /* running approximation for two iterations */
+    for (i = 0; i < 2; i++)
+    {
+      tempVal = (q15_t) (((q31_t) in * out) >> 15);
+      tempVal = 0x7FFF - tempVal;
+      /*      1.15 with exp 1 */
+      out = (q15_t) (((q31_t) out * tempVal) >> 14);
+    }
+
+    /* write output */
+    *dst = out;
+
+    /* return num of signbits of out = 1/in value */
+    return (signBits + 1);
+
+  }
+
+
+  /*
+   * @brief C custom defined intrinisic function for only M0 processors
+   */
+#if defined(ARM_MATH_CM0_FAMILY)
+
+  static __INLINE q31_t __SSAT(
+  q31_t x,
+  uint32_t y)
+  {
+    int32_t posMax, negMin;
+    uint32_t i;
+
+    posMax = 1;
+    for (i = 0; i < (y - 1); i++)
+    {
+      posMax = posMax * 2;
+    }
+
+    if(x > 0)
+    {
+      posMax = (posMax - 1);
+
+      if(x > posMax)
+      {
+        x = posMax;
+      }
+    }
+    else
+    {
+      negMin = -posMax;
+
+      if(x < negMin)
+      {
+        x = negMin;
+      }
+    }
+    return (x);
+
+
+  }
+
+#endif /* end of ARM_MATH_CM0_FAMILY */
+
+
+
+  /*
+   * @brief C custom defined intrinsic function for M3 and M0 processors
+   */
+#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY)
+
+  /*
+   * @brief C custom defined QADD8 for M3 and M0 processors
+   */
+  static __INLINE q31_t __QADD8(
+  q31_t x,
+  q31_t y)
+  {
+
+    q31_t sum;
+    q7_t r, s, t, u;
+
+    r = (q7_t) x;
+    s = (q7_t) y;
+
+    r = __SSAT((q31_t) (r + s), 8);
+    s = __SSAT(((q31_t) (((x << 16) >> 24) + ((y << 16) >> 24))), 8);
+    t = __SSAT(((q31_t) (((x << 8) >> 24) + ((y << 8) >> 24))), 8);
+    u = __SSAT(((q31_t) ((x >> 24) + (y >> 24))), 8);
+
+    sum =
+      (((q31_t) u << 24) & 0xFF000000) | (((q31_t) t << 16) & 0x00FF0000) |
+      (((q31_t) s << 8) & 0x0000FF00) | (r & 0x000000FF);
+
+    return sum;
+
+  }
+
+  /*
+   * @brief C custom defined QSUB8 for M3 and M0 processors
+   */
+  static __INLINE q31_t __QSUB8(
+  q31_t x,
+  q31_t y)
+  {
+
+    q31_t sum;
+    q31_t r, s, t, u;
+
+    r = (q7_t) x;
+    s = (q7_t) y;
+
+    r = __SSAT((r - s), 8);
+    s = __SSAT(((q31_t) (((x << 16) >> 24) - ((y << 16) >> 24))), 8) << 8;
+    t = __SSAT(((q31_t) (((x << 8) >> 24) - ((y << 8) >> 24))), 8) << 16;
+    u = __SSAT(((q31_t) ((x >> 24) - (y >> 24))), 8) << 24;
+
+    sum =
+      (u & 0xFF000000) | (t & 0x00FF0000) | (s & 0x0000FF00) | (r &
+                                                                0x000000FF);
+
+    return sum;
+  }
+
+  /*
+   * @brief C custom defined QADD16 for M3 and M0 processors
+   */
+
+  /*
+   * @brief C custom defined QADD16 for M3 and M0 processors
+   */
+  static __INLINE q31_t __QADD16(
+  q31_t x,
+  q31_t y)
+  {
+
+    q31_t sum;
+    q31_t r, s;
+
+    r = (short) x;
+    s = (short) y;
+
+    r = __SSAT(r + s, 16);
+    s = __SSAT(((q31_t) ((x >> 16) + (y >> 16))), 16) << 16;
+
+    sum = (s & 0xFFFF0000) | (r & 0x0000FFFF);
+
+    return sum;
+
+  }
+
+  /*
+   * @brief C custom defined SHADD16 for M3 and M0 processors
+   */
+  static __INLINE q31_t __SHADD16(
+  q31_t x,
+  q31_t y)
+  {
+
+    q31_t sum;
+    q31_t r, s;
+
+    r = (short) x;
+    s = (short) y;
+
+    r = ((r >> 1) + (s >> 1));
+    s = ((q31_t) ((x >> 17) + (y >> 17))) << 16;
+
+    sum = (s & 0xFFFF0000) | (r & 0x0000FFFF);
+
+    return sum;
+
+  }
+
+  /*
+   * @brief C custom defined QSUB16 for M3 and M0 processors
+   */
+  static __INLINE q31_t __QSUB16(
+  q31_t x,
+  q31_t y)
+  {
+
+    q31_t sum;
+    q31_t r, s;
+
+    r = (short) x;
+    s = (short) y;
+
+    r = __SSAT(r - s, 16);
+    s = __SSAT(((q31_t) ((x >> 16) - (y >> 16))), 16) << 16;
+
+    sum = (s & 0xFFFF0000) | (r & 0x0000FFFF);
+
+    return sum;
+  }
+
+  /*
+   * @brief C custom defined SHSUB16 for M3 and M0 processors
+   */
+  static __INLINE q31_t __SHSUB16(
+  q31_t x,
+  q31_t y)
+  {
+
+    q31_t diff;
+    q31_t r, s;
+
+    r = (short) x;
+    s = (short) y;
+
+    r = ((r >> 1) - (s >> 1));
+    s = (((x >> 17) - (y >> 17)) << 16);
+
+    diff = (s & 0xFFFF0000) | (r & 0x0000FFFF);
+
+    return diff;
+  }
+
+  /*
+   * @brief C custom defined QASX for M3 and M0 processors
+   */
+  static __INLINE q31_t __QASX(
+  q31_t x,
+  q31_t y)
+  {
+
+    q31_t sum = 0;
+
+    sum =
+      ((sum +
+        clip_q31_to_q15((q31_t) ((short) (x >> 16) + (short) y))) << 16) +
+      clip_q31_to_q15((q31_t) ((short) x - (short) (y >> 16)));
+
+    return sum;
+  }
+
+  /*
+   * @brief C custom defined SHASX for M3 and M0 processors
+   */
+  static __INLINE q31_t __SHASX(
+  q31_t x,
+  q31_t y)
+  {
+
+    q31_t sum;
+    q31_t r, s;
+
+    r = (short) x;
+    s = (short) y;
+
+    r = ((r >> 1) - (y >> 17));
+    s = (((x >> 17) + (s >> 1)) << 16);
+
+    sum = (s & 0xFFFF0000) | (r & 0x0000FFFF);
+
+    return sum;
+  }
+
+
+  /*
+   * @brief C custom defined QSAX for M3 and M0 processors
+   */
+  static __INLINE q31_t __QSAX(
+  q31_t x,
+  q31_t y)
+  {
+
+    q31_t sum = 0;
+
+    sum =
+      ((sum +
+        clip_q31_to_q15((q31_t) ((short) (x >> 16) - (short) y))) << 16) +
+      clip_q31_to_q15((q31_t) ((short) x + (short) (y >> 16)));
+
+    return sum;
+  }
+
+  /*
+   * @brief C custom defined SHSAX for M3 and M0 processors
+   */
+  static __INLINE q31_t __SHSAX(
+  q31_t x,
+  q31_t y)
+  {
+
+    q31_t sum;
+    q31_t r, s;
+
+    r = (short) x;
+    s = (short) y;
+
+    r = ((r >> 1) + (y >> 17));
+    s = (((x >> 17) - (s >> 1)) << 16);
+
+    sum = (s & 0xFFFF0000) | (r & 0x0000FFFF);
+
+    return sum;
+  }
+
+  /*
+   * @brief C custom defined SMUSDX for M3 and M0 processors
+   */
+  static __INLINE q31_t __SMUSDX(
+  q31_t x,
+  q31_t y)
+  {
+
+    return ((q31_t) (((short) x * (short) (y >> 16)) -
+                     ((short) (x >> 16) * (short) y)));
+  }
+
+  /*
+   * @brief C custom defined SMUADX for M3 and M0 processors
+   */
+  static __INLINE q31_t __SMUADX(
+  q31_t x,
+  q31_t y)
+  {
+
+    return ((q31_t) (((short) x * (short) (y >> 16)) +
+                     ((short) (x >> 16) * (short) y)));
+  }
+
+  /*
+   * @brief C custom defined QADD for M3 and M0 processors
+   */
+  static __INLINE q31_t __QADD(
+  q31_t x,
+  q31_t y)
+  {
+    return clip_q63_to_q31((q63_t) x + y);
+  }
+
+  /*
+   * @brief C custom defined QSUB for M3 and M0 processors
+   */
+  static __INLINE q31_t __QSUB(
+  q31_t x,
+  q31_t y)
+  {
+    return clip_q63_to_q31((q63_t) x - y);
+  }
+
+  /*
+   * @brief C custom defined SMLAD for M3 and M0 processors
+   */
+  static __INLINE q31_t __SMLAD(
+  q31_t x,
+  q31_t y,
+  q31_t sum)
+  {
+
+    return (sum + ((short) (x >> 16) * (short) (y >> 16)) +
+            ((short) x * (short) y));
+  }
+
+  /*
+   * @brief C custom defined SMLADX for M3 and M0 processors
+   */
+  static __INLINE q31_t __SMLADX(
+  q31_t x,
+  q31_t y,
+  q31_t sum)
+  {
+
+    return (sum + ((short) (x >> 16) * (short) (y)) +
+            ((short) x * (short) (y >> 16)));
+  }
+
+  /*
+   * @brief C custom defined SMLSDX for M3 and M0 processors
+   */
+  static __INLINE q31_t __SMLSDX(
+  q31_t x,
+  q31_t y,
+  q31_t sum)
+  {
+
+    return (sum - ((short) (x >> 16) * (short) (y)) +
+            ((short) x * (short) (y >> 16)));
+  }
+
+  /*
+   * @brief C custom defined SMLALD for M3 and M0 processors
+   */
+  static __INLINE q63_t __SMLALD(
+  q31_t x,
+  q31_t y,
+  q63_t sum)
+  {
+
+    return (sum + ((short) (x >> 16) * (short) (y >> 16)) +
+            ((short) x * (short) y));
+  }
+
+  /*
+   * @brief C custom defined SMLALDX for M3 and M0 processors
+   */
+  static __INLINE q63_t __SMLALDX(
+  q31_t x,
+  q31_t y,
+  q63_t sum)
+  {
+
+    return (sum + ((short) (x >> 16) * (short) y)) +
+      ((short) x * (short) (y >> 16));
+  }
+
+  /*
+   * @brief C custom defined SMUAD for M3 and M0 processors
+   */
+  static __INLINE q31_t __SMUAD(
+  q31_t x,
+  q31_t y)
+  {
+
+    return (((x >> 16) * (y >> 16)) +
+            (((x << 16) >> 16) * ((y << 16) >> 16)));
+  }
+
+  /*
+   * @brief C custom defined SMUSD for M3 and M0 processors
+   */
+  static __INLINE q31_t __SMUSD(
+  q31_t x,
+  q31_t y)
+  {
+
+    return (-((x >> 16) * (y >> 16)) +
+            (((x << 16) >> 16) * ((y << 16) >> 16)));
+  }
+
+
+  /*
+   * @brief C custom defined SXTB16 for M3 and M0 processors
+   */
+  static __INLINE q31_t __SXTB16(
+  q31_t x)
+  {
+
+    return ((((x << 24) >> 24) & 0x0000FFFF) |
+            (((x << 8) >> 8) & 0xFFFF0000));
+  }
+
+
+#endif /* defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */
+
+
+  /**
+   * @brief Instance structure for the Q7 FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;        /**< number of filter coefficients in the filter. */
+    q7_t *pState;            /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q7_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps.*/
+  } arm_fir_instance_q7;
+
+  /**
+   * @brief Instance structure for the Q15 FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;         /**< number of filter coefficients in the filter. */
+    q15_t *pState;            /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q15_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps.*/
+  } arm_fir_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;         /**< number of filter coefficients in the filter. */
+    q31_t *pState;            /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q31_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps. */
+  } arm_fir_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;     /**< number of filter coefficients in the filter. */
+    float32_t *pState;    /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    float32_t *pCoeffs;   /**< points to the coefficient array. The array is of length numTaps. */
+  } arm_fir_instance_f32;
+
+
+  /**
+   * @brief Processing function for the Q7 FIR filter.
+   * @param[in] *S points to an instance of the Q7 FIR filter structure.
+   * @param[in] *pSrc points to the block of input data.
+   * @param[out] *pDst points to the block of output data.
+   * @param[in] blockSize number of samples to process.
+   * @return none.
+   */
+  void arm_fir_q7(
+  const arm_fir_instance_q7 * S,
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q7 FIR filter.
+   * @param[in,out] *S points to an instance of the Q7 FIR structure.
+   * @param[in] numTaps  Number of filter coefficients in the filter.
+   * @param[in] *pCoeffs points to the filter coefficients.
+   * @param[in] *pState points to the state buffer.
+   * @param[in] blockSize number of samples that are processed.
+   * @return none
+   */
+  void arm_fir_init_q7(
+  arm_fir_instance_q7 * S,
+  uint16_t numTaps,
+  q7_t * pCoeffs,
+  q7_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q15 FIR filter.
+   * @param[in] *S points to an instance of the Q15 FIR structure.
+   * @param[in] *pSrc points to the block of input data.
+   * @param[out] *pDst points to the block of output data.
+   * @param[in] blockSize number of samples to process.
+   * @return none.
+   */
+  void arm_fir_q15(
+  const arm_fir_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4.
+   * @param[in] *S points to an instance of the Q15 FIR filter structure.
+   * @param[in] *pSrc points to the block of input data.
+   * @param[out] *pDst points to the block of output data.
+   * @param[in] blockSize number of samples to process.
+   * @return none.
+   */
+  void arm_fir_fast_q15(
+  const arm_fir_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Initialization function for the Q15 FIR filter.
+   * @param[in,out] *S points to an instance of the Q15 FIR filter structure.
+   * @param[in] numTaps  Number of filter coefficients in the filter. Must be even and greater than or equal to 4.
+   * @param[in] *pCoeffs points to the filter coefficients.
+   * @param[in] *pState points to the state buffer.
+   * @param[in] blockSize number of samples that are processed at a time.
+   * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if
+   * <code>numTaps</code> is not a supported value.
+   */
+
+  arm_status arm_fir_init_q15(
+  arm_fir_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+  /**
+   * @brief Processing function for the Q31 FIR filter.
+   * @param[in] *S points to an instance of the Q31 FIR filter structure.
+   * @param[in] *pSrc points to the block of input data.
+   * @param[out] *pDst points to the block of output data.
+   * @param[in] blockSize number of samples to process.
+   * @return none.
+   */
+  void arm_fir_q31(
+  const arm_fir_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4.
+   * @param[in] *S points to an instance of the Q31 FIR structure.
+   * @param[in] *pSrc points to the block of input data.
+   * @param[out] *pDst points to the block of output data.
+   * @param[in] blockSize number of samples to process.
+   * @return none.
+   */
+  void arm_fir_fast_q31(
+  const arm_fir_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Initialization function for the Q31 FIR filter.
+   * @param[in,out] *S points to an instance of the Q31 FIR structure.
+   * @param[in] 	numTaps  Number of filter coefficients in the filter.
+   * @param[in] 	*pCoeffs points to the filter coefficients.
+   * @param[in] 	*pState points to the state buffer.
+   * @param[in] 	blockSize number of samples that are processed at a time.
+   * @return 		none.
+   */
+  void arm_fir_init_q31(
+  arm_fir_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+  /**
+   * @brief Processing function for the floating-point FIR filter.
+   * @param[in] *S points to an instance of the floating-point FIR structure.
+   * @param[in] *pSrc points to the block of input data.
+   * @param[out] *pDst points to the block of output data.
+   * @param[in] blockSize number of samples to process.
+   * @return none.
+   */
+  void arm_fir_f32(
+  const arm_fir_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Initialization function for the floating-point FIR filter.
+   * @param[in,out] *S points to an instance of the floating-point FIR filter structure.
+   * @param[in] 	numTaps  Number of filter coefficients in the filter.
+   * @param[in] 	*pCoeffs points to the filter coefficients.
+   * @param[in] 	*pState points to the state buffer.
+   * @param[in] 	blockSize number of samples that are processed at a time.
+   * @return    	none.
+   */
+  void arm_fir_init_f32(
+  arm_fir_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q15 Biquad cascade filter.
+   */
+  typedef struct
+  {
+    int8_t numStages;         /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    q15_t *pState;            /**< Points to the array of state coefficients.  The array is of length 4*numStages. */
+    q15_t *pCoeffs;           /**< Points to the array of coefficients.  The array is of length 5*numStages. */
+    int8_t postShift;         /**< Additional shift, in bits, applied to each output sample. */
+
+  } arm_biquad_casd_df1_inst_q15;
+
+
+  /**
+   * @brief Instance structure for the Q31 Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint32_t numStages;      /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    q31_t *pState;           /**< Points to the array of state coefficients.  The array is of length 4*numStages. */
+    q31_t *pCoeffs;          /**< Points to the array of coefficients.  The array is of length 5*numStages. */
+    uint8_t postShift;       /**< Additional shift, in bits, applied to each output sample. */
+
+  } arm_biquad_casd_df1_inst_q31;
+
+  /**
+   * @brief Instance structure for the floating-point Biquad cascade filter.
+   */
+  typedef struct
+  {
+    uint32_t numStages;         /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    float32_t *pState;          /**< Points to the array of state coefficients.  The array is of length 4*numStages. */
+    float32_t *pCoeffs;         /**< Points to the array of coefficients.  The array is of length 5*numStages. */
+
+
+  } arm_biquad_casd_df1_inst_f32;
+
+
+
+  /**
+   * @brief Processing function for the Q15 Biquad cascade filter.
+   * @param[in]  *S points to an instance of the Q15 Biquad cascade structure.
+   * @param[in]  *pSrc points to the block of input data.
+   * @param[out] *pDst points to the block of output data.
+   * @param[in]  blockSize number of samples to process.
+   * @return     none.
+   */
+
+  void arm_biquad_cascade_df1_q15(
+  const arm_biquad_casd_df1_inst_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Initialization function for the Q15 Biquad cascade filter.
+   * @param[in,out] *S           points to an instance of the Q15 Biquad cascade structure.
+   * @param[in]     numStages    number of 2nd order stages in the filter.
+   * @param[in]     *pCoeffs     points to the filter coefficients.
+   * @param[in]     *pState      points to the state buffer.
+   * @param[in]     postShift    Shift to be applied to the output. Varies according to the coefficients format
+   * @return        none
+   */
+
+  void arm_biquad_cascade_df1_init_q15(
+  arm_biquad_casd_df1_inst_q15 * S,
+  uint8_t numStages,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  int8_t postShift);
+
+
+  /**
+   * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4.
+   * @param[in]  *S points to an instance of the Q15 Biquad cascade structure.
+   * @param[in]  *pSrc points to the block of input data.
+   * @param[out] *pDst points to the block of output data.
+   * @param[in]  blockSize number of samples to process.
+   * @return     none.
+   */
+
+  void arm_biquad_cascade_df1_fast_q15(
+  const arm_biquad_casd_df1_inst_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q31 Biquad cascade filter
+   * @param[in]  *S         points to an instance of the Q31 Biquad cascade structure.
+   * @param[in]  *pSrc      points to the block of input data.
+   * @param[out] *pDst      points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   * @return     none.
+   */
+
+  void arm_biquad_cascade_df1_q31(
+  const arm_biquad_casd_df1_inst_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4.
+   * @param[in]  *S         points to an instance of the Q31 Biquad cascade structure.
+   * @param[in]  *pSrc      points to the block of input data.
+   * @param[out] *pDst      points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   * @return     none.
+   */
+
+  void arm_biquad_cascade_df1_fast_q31(
+  const arm_biquad_casd_df1_inst_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Initialization function for the Q31 Biquad cascade filter.
+   * @param[in,out] *S           points to an instance of the Q31 Biquad cascade structure.
+   * @param[in]     numStages      number of 2nd order stages in the filter.
+   * @param[in]     *pCoeffs     points to the filter coefficients.
+   * @param[in]     *pState      points to the state buffer.
+   * @param[in]     postShift    Shift to be applied to the output. Varies according to the coefficients format
+   * @return        none
+   */
+
+  void arm_biquad_cascade_df1_init_q31(
+  arm_biquad_casd_df1_inst_q31 * S,
+  uint8_t numStages,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  int8_t postShift);
+
+  /**
+   * @brief Processing function for the floating-point Biquad cascade filter.
+   * @param[in]  *S         points to an instance of the floating-point Biquad cascade structure.
+   * @param[in]  *pSrc      points to the block of input data.
+   * @param[out] *pDst      points to the block of output data.
+   * @param[in]  blockSize  number of samples to process.
+   * @return     none.
+   */
+
+  void arm_biquad_cascade_df1_f32(
+  const arm_biquad_casd_df1_inst_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Initialization function for the floating-point Biquad cascade filter.
+   * @param[in,out] *S           points to an instance of the floating-point Biquad cascade structure.
+   * @param[in]     numStages    number of 2nd order stages in the filter.
+   * @param[in]     *pCoeffs     points to the filter coefficients.
+   * @param[in]     *pState      points to the state buffer.
+   * @return        none
+   */
+
+  void arm_biquad_cascade_df1_init_f32(
+  arm_biquad_casd_df1_inst_f32 * S,
+  uint8_t numStages,
+  float32_t * pCoeffs,
+  float32_t * pState);
+
+
+  /**
+   * @brief Instance structure for the floating-point matrix structure.
+   */
+
+  typedef struct
+  {
+    uint16_t numRows;     /**< number of rows of the matrix.     */
+    uint16_t numCols;     /**< number of columns of the matrix.  */
+    float32_t *pData;     /**< points to the data of the matrix. */
+  } arm_matrix_instance_f32;
+
+  /**
+   * @brief Instance structure for the Q15 matrix structure.
+   */
+
+  typedef struct
+  {
+    uint16_t numRows;     /**< number of rows of the matrix.     */
+    uint16_t numCols;     /**< number of columns of the matrix.  */
+    q15_t *pData;         /**< points to the data of the matrix. */
+
+  } arm_matrix_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 matrix structure.
+   */
+
+  typedef struct
+  {
+    uint16_t numRows;     /**< number of rows of the matrix.     */
+    uint16_t numCols;     /**< number of columns of the matrix.  */
+    q31_t *pData;         /**< points to the data of the matrix. */
+
+  } arm_matrix_instance_q31;
+
+
+
+  /**
+   * @brief Floating-point matrix addition.
+   * @param[in]       *pSrcA points to the first input matrix structure
+   * @param[in]       *pSrcB points to the second input matrix structure
+   * @param[out]      *pDst points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+
+  arm_status arm_mat_add_f32(
+  const arm_matrix_instance_f32 * pSrcA,
+  const arm_matrix_instance_f32 * pSrcB,
+  arm_matrix_instance_f32 * pDst);
+
+  /**
+   * @brief Q15 matrix addition.
+   * @param[in]       *pSrcA points to the first input matrix structure
+   * @param[in]       *pSrcB points to the second input matrix structure
+   * @param[out]      *pDst points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+
+  arm_status arm_mat_add_q15(
+  const arm_matrix_instance_q15 * pSrcA,
+  const arm_matrix_instance_q15 * pSrcB,
+  arm_matrix_instance_q15 * pDst);
+
+  /**
+   * @brief Q31 matrix addition.
+   * @param[in]       *pSrcA points to the first input matrix structure
+   * @param[in]       *pSrcB points to the second input matrix structure
+   * @param[out]      *pDst points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+
+  arm_status arm_mat_add_q31(
+  const arm_matrix_instance_q31 * pSrcA,
+  const arm_matrix_instance_q31 * pSrcB,
+  arm_matrix_instance_q31 * pDst);
+
+
+  /**
+   * @brief Floating-point matrix transpose.
+   * @param[in]  *pSrc points to the input matrix
+   * @param[out] *pDst points to the output matrix
+   * @return 	The function returns either  <code>ARM_MATH_SIZE_MISMATCH</code>
+   * or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+
+  arm_status arm_mat_trans_f32(
+  const arm_matrix_instance_f32 * pSrc,
+  arm_matrix_instance_f32 * pDst);
+
+
+  /**
+   * @brief Q15 matrix transpose.
+   * @param[in]  *pSrc points to the input matrix
+   * @param[out] *pDst points to the output matrix
+   * @return 	The function returns either  <code>ARM_MATH_SIZE_MISMATCH</code>
+   * or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+
+  arm_status arm_mat_trans_q15(
+  const arm_matrix_instance_q15 * pSrc,
+  arm_matrix_instance_q15 * pDst);
+
+  /**
+   * @brief Q31 matrix transpose.
+   * @param[in]  *pSrc points to the input matrix
+   * @param[out] *pDst points to the output matrix
+   * @return 	The function returns either  <code>ARM_MATH_SIZE_MISMATCH</code>
+   * or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+
+  arm_status arm_mat_trans_q31(
+  const arm_matrix_instance_q31 * pSrc,
+  arm_matrix_instance_q31 * pDst);
+
+
+  /**
+   * @brief Floating-point matrix multiplication
+   * @param[in]       *pSrcA points to the first input matrix structure
+   * @param[in]       *pSrcB points to the second input matrix structure
+   * @param[out]      *pDst points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+
+  arm_status arm_mat_mult_f32(
+  const arm_matrix_instance_f32 * pSrcA,
+  const arm_matrix_instance_f32 * pSrcB,
+  arm_matrix_instance_f32 * pDst);
+
+  /**
+   * @brief Q15 matrix multiplication
+   * @param[in]       *pSrcA points to the first input matrix structure
+   * @param[in]       *pSrcB points to the second input matrix structure
+   * @param[out]      *pDst points to output matrix structure
+   * @param[in]		  *pState points to the array for storing intermediate results
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+
+  arm_status arm_mat_mult_q15(
+  const arm_matrix_instance_q15 * pSrcA,
+  const arm_matrix_instance_q15 * pSrcB,
+  arm_matrix_instance_q15 * pDst,
+  q15_t * pState);
+
+  /**
+   * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4
+   * @param[in]       *pSrcA  points to the first input matrix structure
+   * @param[in]       *pSrcB  points to the second input matrix structure
+   * @param[out]      *pDst   points to output matrix structure
+   * @param[in]		  *pState points to the array for storing intermediate results
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+
+  arm_status arm_mat_mult_fast_q15(
+  const arm_matrix_instance_q15 * pSrcA,
+  const arm_matrix_instance_q15 * pSrcB,
+  arm_matrix_instance_q15 * pDst,
+  q15_t * pState);
+
+  /**
+   * @brief Q31 matrix multiplication
+   * @param[in]       *pSrcA points to the first input matrix structure
+   * @param[in]       *pSrcB points to the second input matrix structure
+   * @param[out]      *pDst points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+
+  arm_status arm_mat_mult_q31(
+  const arm_matrix_instance_q31 * pSrcA,
+  const arm_matrix_instance_q31 * pSrcB,
+  arm_matrix_instance_q31 * pDst);
+
+  /**
+   * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4
+   * @param[in]       *pSrcA points to the first input matrix structure
+   * @param[in]       *pSrcB points to the second input matrix structure
+   * @param[out]      *pDst points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+
+  arm_status arm_mat_mult_fast_q31(
+  const arm_matrix_instance_q31 * pSrcA,
+  const arm_matrix_instance_q31 * pSrcB,
+  arm_matrix_instance_q31 * pDst);
+
+
+  /**
+   * @brief Floating-point matrix subtraction
+   * @param[in]       *pSrcA points to the first input matrix structure
+   * @param[in]       *pSrcB points to the second input matrix structure
+   * @param[out]      *pDst points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+
+  arm_status arm_mat_sub_f32(
+  const arm_matrix_instance_f32 * pSrcA,
+  const arm_matrix_instance_f32 * pSrcB,
+  arm_matrix_instance_f32 * pDst);
+
+  /**
+   * @brief Q15 matrix subtraction
+   * @param[in]       *pSrcA points to the first input matrix structure
+   * @param[in]       *pSrcB points to the second input matrix structure
+   * @param[out]      *pDst points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+
+  arm_status arm_mat_sub_q15(
+  const arm_matrix_instance_q15 * pSrcA,
+  const arm_matrix_instance_q15 * pSrcB,
+  arm_matrix_instance_q15 * pDst);
+
+  /**
+   * @brief Q31 matrix subtraction
+   * @param[in]       *pSrcA points to the first input matrix structure
+   * @param[in]       *pSrcB points to the second input matrix structure
+   * @param[out]      *pDst points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+
+  arm_status arm_mat_sub_q31(
+  const arm_matrix_instance_q31 * pSrcA,
+  const arm_matrix_instance_q31 * pSrcB,
+  arm_matrix_instance_q31 * pDst);
+
+  /**
+   * @brief Floating-point matrix scaling.
+   * @param[in]  *pSrc points to the input matrix
+   * @param[in]  scale scale factor
+   * @param[out] *pDst points to the output matrix
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+
+  arm_status arm_mat_scale_f32(
+  const arm_matrix_instance_f32 * pSrc,
+  float32_t scale,
+  arm_matrix_instance_f32 * pDst);
+
+  /**
+   * @brief Q15 matrix scaling.
+   * @param[in]       *pSrc points to input matrix
+   * @param[in]       scaleFract fractional portion of the scale factor
+   * @param[in]       shift number of bits to shift the result by
+   * @param[out]      *pDst points to output matrix
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+
+  arm_status arm_mat_scale_q15(
+  const arm_matrix_instance_q15 * pSrc,
+  q15_t scaleFract,
+  int32_t shift,
+  arm_matrix_instance_q15 * pDst);
+
+  /**
+   * @brief Q31 matrix scaling.
+   * @param[in]       *pSrc points to input matrix
+   * @param[in]       scaleFract fractional portion of the scale factor
+   * @param[in]       shift number of bits to shift the result by
+   * @param[out]      *pDst points to output matrix structure
+   * @return     The function returns either
+   * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+   */
+
+  arm_status arm_mat_scale_q31(
+  const arm_matrix_instance_q31 * pSrc,
+  q31_t scaleFract,
+  int32_t shift,
+  arm_matrix_instance_q31 * pDst);
+
+
+  /**
+   * @brief  Q31 matrix initialization.
+   * @param[in,out] *S             points to an instance of the floating-point matrix structure.
+   * @param[in]     nRows          number of rows in the matrix.
+   * @param[in]     nColumns       number of columns in the matrix.
+   * @param[in]     *pData	       points to the matrix data array.
+   * @return        none
+   */
+
+  void arm_mat_init_q31(
+  arm_matrix_instance_q31 * S,
+  uint16_t nRows,
+  uint16_t nColumns,
+  q31_t * pData);
+
+  /**
+   * @brief  Q15 matrix initialization.
+   * @param[in,out] *S             points to an instance of the floating-point matrix structure.
+   * @param[in]     nRows          number of rows in the matrix.
+   * @param[in]     nColumns       number of columns in the matrix.
+   * @param[in]     *pData	       points to the matrix data array.
+   * @return        none
+   */
+
+  void arm_mat_init_q15(
+  arm_matrix_instance_q15 * S,
+  uint16_t nRows,
+  uint16_t nColumns,
+  q15_t * pData);
+
+  /**
+   * @brief  Floating-point matrix initialization.
+   * @param[in,out] *S             points to an instance of the floating-point matrix structure.
+   * @param[in]     nRows          number of rows in the matrix.
+   * @param[in]     nColumns       number of columns in the matrix.
+   * @param[in]     *pData	       points to the matrix data array.
+   * @return        none
+   */
+
+  void arm_mat_init_f32(
+  arm_matrix_instance_f32 * S,
+  uint16_t nRows,
+  uint16_t nColumns,
+  float32_t * pData);
+
+
+
+  /**
+   * @brief Instance structure for the Q15 PID Control.
+   */
+  typedef struct
+  {
+    q15_t A0;    /**< The derived gain, A0 = Kp + Ki + Kd . */
+#ifdef ARM_MATH_CM0_FAMILY
+    q15_t A1;
+    q15_t A2;
+#else
+    q31_t A1;           /**< The derived gain A1 = -Kp - 2Kd | Kd.*/
+#endif
+    q15_t state[3];       /**< The state array of length 3. */
+    q15_t Kp;           /**< The proportional gain. */
+    q15_t Ki;           /**< The integral gain. */
+    q15_t Kd;           /**< The derivative gain. */
+  } arm_pid_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 PID Control.
+   */
+  typedef struct
+  {
+    q31_t A0;            /**< The derived gain, A0 = Kp + Ki + Kd . */
+    q31_t A1;            /**< The derived gain, A1 = -Kp - 2Kd. */
+    q31_t A2;            /**< The derived gain, A2 = Kd . */
+    q31_t state[3];      /**< The state array of length 3. */
+    q31_t Kp;            /**< The proportional gain. */
+    q31_t Ki;            /**< The integral gain. */
+    q31_t Kd;            /**< The derivative gain. */
+
+  } arm_pid_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point PID Control.
+   */
+  typedef struct
+  {
+    float32_t A0;          /**< The derived gain, A0 = Kp + Ki + Kd . */
+    float32_t A1;          /**< The derived gain, A1 = -Kp - 2Kd. */
+    float32_t A2;          /**< The derived gain, A2 = Kd . */
+    float32_t state[3];    /**< The state array of length 3. */
+    float32_t Kp;               /**< The proportional gain. */
+    float32_t Ki;               /**< The integral gain. */
+    float32_t Kd;               /**< The derivative gain. */
+  } arm_pid_instance_f32;
+
+
+
+  /**
+   * @brief  Initialization function for the floating-point PID Control.
+   * @param[in,out] *S      points to an instance of the PID structure.
+   * @param[in]     resetStateFlag  flag to reset the state. 0 = no change in state 1 = reset the state.
+   * @return none.
+   */
+  void arm_pid_init_f32(
+  arm_pid_instance_f32 * S,
+  int32_t resetStateFlag);
+
+  /**
+   * @brief  Reset function for the floating-point PID Control.
+   * @param[in,out] *S is an instance of the floating-point PID Control structure
+   * @return none
+   */
+  void arm_pid_reset_f32(
+  arm_pid_instance_f32 * S);
+
+
+  /**
+   * @brief  Initialization function for the Q31 PID Control.
+   * @param[in,out] *S points to an instance of the Q15 PID structure.
+   * @param[in]     resetStateFlag  flag to reset the state. 0 = no change in state 1 = reset the state.
+   * @return none.
+   */
+  void arm_pid_init_q31(
+  arm_pid_instance_q31 * S,
+  int32_t resetStateFlag);
+
+
+  /**
+   * @brief  Reset function for the Q31 PID Control.
+   * @param[in,out] *S points to an instance of the Q31 PID Control structure
+   * @return none
+   */
+
+  void arm_pid_reset_q31(
+  arm_pid_instance_q31 * S);
+
+  /**
+   * @brief  Initialization function for the Q15 PID Control.
+   * @param[in,out] *S points to an instance of the Q15 PID structure.
+   * @param[in] resetStateFlag  flag to reset the state. 0 = no change in state 1 = reset the state.
+   * @return none.
+   */
+  void arm_pid_init_q15(
+  arm_pid_instance_q15 * S,
+  int32_t resetStateFlag);
+
+  /**
+   * @brief  Reset function for the Q15 PID Control.
+   * @param[in,out] *S points to an instance of the q15 PID Control structure
+   * @return none
+   */
+  void arm_pid_reset_q15(
+  arm_pid_instance_q15 * S);
+
+
+  /**
+   * @brief Instance structure for the floating-point Linear Interpolate function.
+   */
+  typedef struct
+  {
+    uint32_t nValues;           /**< nValues */
+    float32_t x1;               /**< x1 */
+    float32_t xSpacing;         /**< xSpacing */
+    float32_t *pYData;          /**< pointer to the table of Y values */
+  } arm_linear_interp_instance_f32;
+
+  /**
+   * @brief Instance structure for the floating-point bilinear interpolation function.
+   */
+
+  typedef struct
+  {
+    uint16_t numRows;   /**< number of rows in the data table. */
+    uint16_t numCols;   /**< number of columns in the data table. */
+    float32_t *pData;   /**< points to the data table. */
+  } arm_bilinear_interp_instance_f32;
+
+   /**
+   * @brief Instance structure for the Q31 bilinear interpolation function.
+   */
+
+  typedef struct
+  {
+    uint16_t numRows;   /**< number of rows in the data table. */
+    uint16_t numCols;   /**< number of columns in the data table. */
+    q31_t *pData;       /**< points to the data table. */
+  } arm_bilinear_interp_instance_q31;
+
+   /**
+   * @brief Instance structure for the Q15 bilinear interpolation function.
+   */
+
+  typedef struct
+  {
+    uint16_t numRows;   /**< number of rows in the data table. */
+    uint16_t numCols;   /**< number of columns in the data table. */
+    q15_t *pData;       /**< points to the data table. */
+  } arm_bilinear_interp_instance_q15;
+
+   /**
+   * @brief Instance structure for the Q15 bilinear interpolation function.
+   */
+
+  typedef struct
+  {
+    uint16_t numRows;   /**< number of rows in the data table. */
+    uint16_t numCols;   /**< number of columns in the data table. */
+    q7_t *pData;                /**< points to the data table. */
+  } arm_bilinear_interp_instance_q7;
+
+
+  /**
+   * @brief Q7 vector multiplication.
+   * @param[in]       *pSrcA points to the first input vector
+   * @param[in]       *pSrcB points to the second input vector
+   * @param[out]      *pDst  points to the output vector
+   * @param[in]       blockSize number of samples in each vector
+   * @return none.
+   */
+
+  void arm_mult_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Q15 vector multiplication.
+   * @param[in]       *pSrcA points to the first input vector
+   * @param[in]       *pSrcB points to the second input vector
+   * @param[out]      *pDst  points to the output vector
+   * @param[in]       blockSize number of samples in each vector
+   * @return none.
+   */
+
+  void arm_mult_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Q31 vector multiplication.
+   * @param[in]       *pSrcA points to the first input vector
+   * @param[in]       *pSrcB points to the second input vector
+   * @param[out]      *pDst points to the output vector
+   * @param[in]       blockSize number of samples in each vector
+   * @return none.
+   */
+
+  void arm_mult_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Floating-point vector multiplication.
+   * @param[in]       *pSrcA points to the first input vector
+   * @param[in]       *pSrcB points to the second input vector
+   * @param[out]      *pDst points to the output vector
+   * @param[in]       blockSize number of samples in each vector
+   * @return none.
+   */
+
+  void arm_mult_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+
+
+
+
+  /**
+   * @brief Instance structure for the Q15 CFFT/CIFFT function.
+   */
+
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q15_t *pTwiddle;                     /**< points to the Sin twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } arm_cfft_radix2_instance_q15;
+
+  arm_status arm_cfft_radix2_init_q15(
+  arm_cfft_radix2_instance_q15 * S,
+  uint16_t fftLen,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+  void arm_cfft_radix2_q15(
+  const arm_cfft_radix2_instance_q15 * S,
+  q15_t * pSrc);
+
+
+
+  /**
+   * @brief Instance structure for the Q15 CFFT/CIFFT function.
+   */
+
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q15_t *pTwiddle;                 /**< points to the twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } arm_cfft_radix4_instance_q15;
+
+  arm_status arm_cfft_radix4_init_q15(
+  arm_cfft_radix4_instance_q15 * S,
+  uint16_t fftLen,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+  void arm_cfft_radix4_q15(
+  const arm_cfft_radix4_instance_q15 * S,
+  q15_t * pSrc);
+
+  /**
+   * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function.
+   */
+
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q31_t *pTwiddle;                     /**< points to the Twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } arm_cfft_radix2_instance_q31;
+
+  arm_status arm_cfft_radix2_init_q31(
+  arm_cfft_radix2_instance_q31 * S,
+  uint16_t fftLen,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+  void arm_cfft_radix2_q31(
+  const arm_cfft_radix2_instance_q31 * S,
+  q31_t * pSrc);
+
+  /**
+   * @brief Instance structure for the Q31 CFFT/CIFFT function.
+   */
+
+  typedef struct
+  {
+    uint16_t fftLen;                 /**< length of the FFT. */
+    uint8_t ifftFlag;                /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;          /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    q31_t *pTwiddle;                 /**< points to the twiddle factor table. */
+    uint16_t *pBitRevTable;          /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;       /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;           /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+  } arm_cfft_radix4_instance_q31;
+
+
+  void arm_cfft_radix4_q31(
+  const arm_cfft_radix4_instance_q31 * S,
+  q31_t * pSrc);
+
+  arm_status arm_cfft_radix4_init_q31(
+  arm_cfft_radix4_instance_q31 * S,
+  uint16_t fftLen,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+  /**
+   * @brief Instance structure for the floating-point CFFT/CIFFT function.
+   */
+
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    uint8_t ifftFlag;                  /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;            /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    float32_t *pTwiddle;               /**< points to the Twiddle factor table. */
+    uint16_t *pBitRevTable;            /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;         /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;             /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+    float32_t onebyfftLen;                 /**< value of 1/fftLen. */
+  } arm_cfft_radix2_instance_f32;
+
+/* Deprecated */
+  arm_status arm_cfft_radix2_init_f32(
+  arm_cfft_radix2_instance_f32 * S,
+  uint16_t fftLen,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+/* Deprecated */
+  void arm_cfft_radix2_f32(
+  const arm_cfft_radix2_instance_f32 * S,
+  float32_t * pSrc);
+
+  /**
+   * @brief Instance structure for the floating-point CFFT/CIFFT function.
+   */
+
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    uint8_t ifftFlag;                  /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+    uint8_t bitReverseFlag;            /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+    float32_t *pTwiddle;               /**< points to the Twiddle factor table. */
+    uint16_t *pBitRevTable;            /**< points to the bit reversal table. */
+    uint16_t twidCoefModifier;         /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    uint16_t bitRevFactor;             /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+    float32_t onebyfftLen;                 /**< value of 1/fftLen. */
+  } arm_cfft_radix4_instance_f32;
+
+/* Deprecated */
+  arm_status arm_cfft_radix4_init_f32(
+  arm_cfft_radix4_instance_f32 * S,
+  uint16_t fftLen,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+/* Deprecated */
+  void arm_cfft_radix4_f32(
+  const arm_cfft_radix4_instance_f32 * S,
+  float32_t * pSrc);
+
+  /**
+   * @brief Instance structure for the floating-point CFFT/CIFFT function.
+   */
+
+  typedef struct
+  {
+    uint16_t fftLen;                   /**< length of the FFT. */
+    const float32_t *pTwiddle;         /**< points to the Twiddle factor table. */
+    const uint16_t *pBitRevTable;      /**< points to the bit reversal table. */
+    uint16_t bitRevLength;             /**< bit reversal table length. */
+  } arm_cfft_instance_f32;
+
+  void arm_cfft_f32(
+  const arm_cfft_instance_f32 * S,
+  float32_t * p1,
+  uint8_t ifftFlag,
+  uint8_t bitReverseFlag);
+
+  /**
+   * @brief Instance structure for the Q15 RFFT/RIFFT function.
+   */
+
+  typedef struct
+  {
+    uint32_t fftLenReal;                      /**< length of the real FFT. */
+    uint32_t fftLenBy2;                       /**< length of the complex FFT. */
+    uint8_t ifftFlagR;                        /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+    uint8_t bitReverseFlagR;                      /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+    uint32_t twidCoefRModifier;               /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    q15_t *pTwiddleAReal;                     /**< points to the real twiddle factor table. */
+    q15_t *pTwiddleBReal;                     /**< points to the imag twiddle factor table. */
+    arm_cfft_radix4_instance_q15 *pCfft;          /**< points to the complex FFT instance. */
+  } arm_rfft_instance_q15;
+
+  arm_status arm_rfft_init_q15(
+  arm_rfft_instance_q15 * S,
+  arm_cfft_radix4_instance_q15 * S_CFFT,
+  uint32_t fftLenReal,
+  uint32_t ifftFlagR,
+  uint32_t bitReverseFlag);
+
+  void arm_rfft_q15(
+  const arm_rfft_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst);
+
+  /**
+   * @brief Instance structure for the Q31 RFFT/RIFFT function.
+   */
+
+  typedef struct
+  {
+    uint32_t fftLenReal;                        /**< length of the real FFT. */
+    uint32_t fftLenBy2;                         /**< length of the complex FFT. */
+    uint8_t ifftFlagR;                          /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+    uint8_t bitReverseFlagR;                        /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+    uint32_t twidCoefRModifier;                 /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    q31_t *pTwiddleAReal;                       /**< points to the real twiddle factor table. */
+    q31_t *pTwiddleBReal;                       /**< points to the imag twiddle factor table. */
+    arm_cfft_radix4_instance_q31 *pCfft;        /**< points to the complex FFT instance. */
+  } arm_rfft_instance_q31;
+
+  arm_status arm_rfft_init_q31(
+  arm_rfft_instance_q31 * S,
+  arm_cfft_radix4_instance_q31 * S_CFFT,
+  uint32_t fftLenReal,
+  uint32_t ifftFlagR,
+  uint32_t bitReverseFlag);
+
+  void arm_rfft_q31(
+  const arm_rfft_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst);
+
+  /**
+   * @brief Instance structure for the floating-point RFFT/RIFFT function.
+   */
+
+  typedef struct
+  {
+    uint32_t fftLenReal;                        /**< length of the real FFT. */
+    uint16_t fftLenBy2;                         /**< length of the complex FFT. */
+    uint8_t ifftFlagR;                          /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+    uint8_t bitReverseFlagR;                    /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+    uint32_t twidCoefRModifier;                     /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+    float32_t *pTwiddleAReal;                   /**< points to the real twiddle factor table. */
+    float32_t *pTwiddleBReal;                   /**< points to the imag twiddle factor table. */
+    arm_cfft_radix4_instance_f32 *pCfft;        /**< points to the complex FFT instance. */
+  } arm_rfft_instance_f32;
+
+  arm_status arm_rfft_init_f32(
+  arm_rfft_instance_f32 * S,
+  arm_cfft_radix4_instance_f32 * S_CFFT,
+  uint32_t fftLenReal,
+  uint32_t ifftFlagR,
+  uint32_t bitReverseFlag);
+
+  void arm_rfft_f32(
+  const arm_rfft_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst);
+
+  /**
+   * @brief Instance structure for the floating-point RFFT/RIFFT function.
+   */
+
+typedef struct
+  {
+    arm_cfft_instance_f32 Sint;      /**< Internal CFFT structure. */
+    uint16_t fftLenRFFT;                        /**< length of the real sequence */
+	float32_t * pTwiddleRFFT;					/**< Twiddle factors real stage  */
+  } arm_rfft_fast_instance_f32 ;
+
+arm_status arm_rfft_fast_init_f32 (
+	arm_rfft_fast_instance_f32 * S,
+	uint16_t fftLen);
+
+void arm_rfft_fast_f32(
+  arm_rfft_fast_instance_f32 * S,
+  float32_t * p, float32_t * pOut,
+  uint8_t ifftFlag);
+
+  /**
+   * @brief Instance structure for the floating-point DCT4/IDCT4 function.
+   */
+
+  typedef struct
+  {
+    uint16_t N;                         /**< length of the DCT4. */
+    uint16_t Nby2;                      /**< half of the length of the DCT4. */
+    float32_t normalize;                /**< normalizing factor. */
+    float32_t *pTwiddle;                /**< points to the twiddle factor table. */
+    float32_t *pCosFactor;              /**< points to the cosFactor table. */
+    arm_rfft_instance_f32 *pRfft;        /**< points to the real FFT instance. */
+    arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */
+  } arm_dct4_instance_f32;
+
+  /**
+   * @brief  Initialization function for the floating-point DCT4/IDCT4.
+   * @param[in,out] *S         points to an instance of floating-point DCT4/IDCT4 structure.
+   * @param[in]     *S_RFFT    points to an instance of floating-point RFFT/RIFFT structure.
+   * @param[in]     *S_CFFT    points to an instance of floating-point CFFT/CIFFT structure.
+   * @param[in]     N          length of the DCT4.
+   * @param[in]     Nby2       half of the length of the DCT4.
+   * @param[in]     normalize  normalizing factor.
+   * @return		arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>fftLenReal</code> is not a supported transform length.
+   */
+
+  arm_status arm_dct4_init_f32(
+  arm_dct4_instance_f32 * S,
+  arm_rfft_instance_f32 * S_RFFT,
+  arm_cfft_radix4_instance_f32 * S_CFFT,
+  uint16_t N,
+  uint16_t Nby2,
+  float32_t normalize);
+
+  /**
+   * @brief Processing function for the floating-point DCT4/IDCT4.
+   * @param[in]       *S             points to an instance of the floating-point DCT4/IDCT4 structure.
+   * @param[in]       *pState        points to state buffer.
+   * @param[in,out]   *pInlineBuffer points to the in-place input and output buffer.
+   * @return none.
+   */
+
+  void arm_dct4_f32(
+  const arm_dct4_instance_f32 * S,
+  float32_t * pState,
+  float32_t * pInlineBuffer);
+
+  /**
+   * @brief Instance structure for the Q31 DCT4/IDCT4 function.
+   */
+
+  typedef struct
+  {
+    uint16_t N;                         /**< length of the DCT4. */
+    uint16_t Nby2;                      /**< half of the length of the DCT4. */
+    q31_t normalize;                    /**< normalizing factor. */
+    q31_t *pTwiddle;                    /**< points to the twiddle factor table. */
+    q31_t *pCosFactor;                  /**< points to the cosFactor table. */
+    arm_rfft_instance_q31 *pRfft;        /**< points to the real FFT instance. */
+    arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */
+  } arm_dct4_instance_q31;
+
+  /**
+   * @brief  Initialization function for the Q31 DCT4/IDCT4.
+   * @param[in,out] *S         points to an instance of Q31 DCT4/IDCT4 structure.
+   * @param[in]     *S_RFFT    points to an instance of Q31 RFFT/RIFFT structure
+   * @param[in]     *S_CFFT    points to an instance of Q31 CFFT/CIFFT structure
+   * @param[in]     N          length of the DCT4.
+   * @param[in]     Nby2       half of the length of the DCT4.
+   * @param[in]     normalize  normalizing factor.
+   * @return		arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>N</code> is not a supported transform length.
+   */
+
+  arm_status arm_dct4_init_q31(
+  arm_dct4_instance_q31 * S,
+  arm_rfft_instance_q31 * S_RFFT,
+  arm_cfft_radix4_instance_q31 * S_CFFT,
+  uint16_t N,
+  uint16_t Nby2,
+  q31_t normalize);
+
+  /**
+   * @brief Processing function for the Q31 DCT4/IDCT4.
+   * @param[in]       *S             points to an instance of the Q31 DCT4 structure.
+   * @param[in]       *pState        points to state buffer.
+   * @param[in,out]   *pInlineBuffer points to the in-place input and output buffer.
+   * @return none.
+   */
+
+  void arm_dct4_q31(
+  const arm_dct4_instance_q31 * S,
+  q31_t * pState,
+  q31_t * pInlineBuffer);
+
+  /**
+   * @brief Instance structure for the Q15 DCT4/IDCT4 function.
+   */
+
+  typedef struct
+  {
+    uint16_t N;                         /**< length of the DCT4. */
+    uint16_t Nby2;                      /**< half of the length of the DCT4. */
+    q15_t normalize;                    /**< normalizing factor. */
+    q15_t *pTwiddle;                    /**< points to the twiddle factor table. */
+    q15_t *pCosFactor;                  /**< points to the cosFactor table. */
+    arm_rfft_instance_q15 *pRfft;        /**< points to the real FFT instance. */
+    arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */
+  } arm_dct4_instance_q15;
+
+  /**
+   * @brief  Initialization function for the Q15 DCT4/IDCT4.
+   * @param[in,out] *S         points to an instance of Q15 DCT4/IDCT4 structure.
+   * @param[in]     *S_RFFT    points to an instance of Q15 RFFT/RIFFT structure.
+   * @param[in]     *S_CFFT    points to an instance of Q15 CFFT/CIFFT structure.
+   * @param[in]     N          length of the DCT4.
+   * @param[in]     Nby2       half of the length of the DCT4.
+   * @param[in]     normalize  normalizing factor.
+   * @return		arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>N</code> is not a supported transform length.
+   */
+
+  arm_status arm_dct4_init_q15(
+  arm_dct4_instance_q15 * S,
+  arm_rfft_instance_q15 * S_RFFT,
+  arm_cfft_radix4_instance_q15 * S_CFFT,
+  uint16_t N,
+  uint16_t Nby2,
+  q15_t normalize);
+
+  /**
+   * @brief Processing function for the Q15 DCT4/IDCT4.
+   * @param[in]       *S             points to an instance of the Q15 DCT4 structure.
+   * @param[in]       *pState        points to state buffer.
+   * @param[in,out]   *pInlineBuffer points to the in-place input and output buffer.
+   * @return none.
+   */
+
+  void arm_dct4_q15(
+  const arm_dct4_instance_q15 * S,
+  q15_t * pState,
+  q15_t * pInlineBuffer);
+
+  /**
+   * @brief Floating-point vector addition.
+   * @param[in]       *pSrcA points to the first input vector
+   * @param[in]       *pSrcB points to the second input vector
+   * @param[out]      *pDst points to the output vector
+   * @param[in]       blockSize number of samples in each vector
+   * @return none.
+   */
+
+  void arm_add_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Q7 vector addition.
+   * @param[in]       *pSrcA points to the first input vector
+   * @param[in]       *pSrcB points to the second input vector
+   * @param[out]      *pDst points to the output vector
+   * @param[in]       blockSize number of samples in each vector
+   * @return none.
+   */
+
+  void arm_add_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Q15 vector addition.
+   * @param[in]       *pSrcA points to the first input vector
+   * @param[in]       *pSrcB points to the second input vector
+   * @param[out]      *pDst points to the output vector
+   * @param[in]       blockSize number of samples in each vector
+   * @return none.
+   */
+
+  void arm_add_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Q31 vector addition.
+   * @param[in]       *pSrcA points to the first input vector
+   * @param[in]       *pSrcB points to the second input vector
+   * @param[out]      *pDst points to the output vector
+   * @param[in]       blockSize number of samples in each vector
+   * @return none.
+   */
+
+  void arm_add_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Floating-point vector subtraction.
+   * @param[in]       *pSrcA points to the first input vector
+   * @param[in]       *pSrcB points to the second input vector
+   * @param[out]      *pDst points to the output vector
+   * @param[in]       blockSize number of samples in each vector
+   * @return none.
+   */
+
+  void arm_sub_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Q7 vector subtraction.
+   * @param[in]       *pSrcA points to the first input vector
+   * @param[in]       *pSrcB points to the second input vector
+   * @param[out]      *pDst points to the output vector
+   * @param[in]       blockSize number of samples in each vector
+   * @return none.
+   */
+
+  void arm_sub_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Q15 vector subtraction.
+   * @param[in]       *pSrcA points to the first input vector
+   * @param[in]       *pSrcB points to the second input vector
+   * @param[out]      *pDst points to the output vector
+   * @param[in]       blockSize number of samples in each vector
+   * @return none.
+   */
+
+  void arm_sub_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Q31 vector subtraction.
+   * @param[in]       *pSrcA points to the first input vector
+   * @param[in]       *pSrcB points to the second input vector
+   * @param[out]      *pDst points to the output vector
+   * @param[in]       blockSize number of samples in each vector
+   * @return none.
+   */
+
+  void arm_sub_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Multiplies a floating-point vector by a scalar.
+   * @param[in]       *pSrc points to the input vector
+   * @param[in]       scale scale factor to be applied
+   * @param[out]      *pDst points to the output vector
+   * @param[in]       blockSize number of samples in the vector
+   * @return none.
+   */
+
+  void arm_scale_f32(
+  float32_t * pSrc,
+  float32_t scale,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Multiplies a Q7 vector by a scalar.
+   * @param[in]       *pSrc points to the input vector
+   * @param[in]       scaleFract fractional portion of the scale value
+   * @param[in]       shift number of bits to shift the result by
+   * @param[out]      *pDst points to the output vector
+   * @param[in]       blockSize number of samples in the vector
+   * @return none.
+   */
+
+  void arm_scale_q7(
+  q7_t * pSrc,
+  q7_t scaleFract,
+  int8_t shift,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Multiplies a Q15 vector by a scalar.
+   * @param[in]       *pSrc points to the input vector
+   * @param[in]       scaleFract fractional portion of the scale value
+   * @param[in]       shift number of bits to shift the result by
+   * @param[out]      *pDst points to the output vector
+   * @param[in]       blockSize number of samples in the vector
+   * @return none.
+   */
+
+  void arm_scale_q15(
+  q15_t * pSrc,
+  q15_t scaleFract,
+  int8_t shift,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Multiplies a Q31 vector by a scalar.
+   * @param[in]       *pSrc points to the input vector
+   * @param[in]       scaleFract fractional portion of the scale value
+   * @param[in]       shift number of bits to shift the result by
+   * @param[out]      *pDst points to the output vector
+   * @param[in]       blockSize number of samples in the vector
+   * @return none.
+   */
+
+  void arm_scale_q31(
+  q31_t * pSrc,
+  q31_t scaleFract,
+  int8_t shift,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Q7 vector absolute value.
+   * @param[in]       *pSrc points to the input buffer
+   * @param[out]      *pDst points to the output buffer
+   * @param[in]       blockSize number of samples in each vector
+   * @return none.
+   */
+
+  void arm_abs_q7(
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Floating-point vector absolute value.
+   * @param[in]       *pSrc points to the input buffer
+   * @param[out]      *pDst points to the output buffer
+   * @param[in]       blockSize number of samples in each vector
+   * @return none.
+   */
+
+  void arm_abs_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Q15 vector absolute value.
+   * @param[in]       *pSrc points to the input buffer
+   * @param[out]      *pDst points to the output buffer
+   * @param[in]       blockSize number of samples in each vector
+   * @return none.
+   */
+
+  void arm_abs_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Q31 vector absolute value.
+   * @param[in]       *pSrc points to the input buffer
+   * @param[out]      *pDst points to the output buffer
+   * @param[in]       blockSize number of samples in each vector
+   * @return none.
+   */
+
+  void arm_abs_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Dot product of floating-point vectors.
+   * @param[in]       *pSrcA points to the first input vector
+   * @param[in]       *pSrcB points to the second input vector
+   * @param[in]       blockSize number of samples in each vector
+   * @param[out]      *result output result returned here
+   * @return none.
+   */
+
+  void arm_dot_prod_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  uint32_t blockSize,
+  float32_t * result);
+
+  /**
+   * @brief Dot product of Q7 vectors.
+   * @param[in]       *pSrcA points to the first input vector
+   * @param[in]       *pSrcB points to the second input vector
+   * @param[in]       blockSize number of samples in each vector
+   * @param[out]      *result output result returned here
+   * @return none.
+   */
+
+  void arm_dot_prod_q7(
+  q7_t * pSrcA,
+  q7_t * pSrcB,
+  uint32_t blockSize,
+  q31_t * result);
+
+  /**
+   * @brief Dot product of Q15 vectors.
+   * @param[in]       *pSrcA points to the first input vector
+   * @param[in]       *pSrcB points to the second input vector
+   * @param[in]       blockSize number of samples in each vector
+   * @param[out]      *result output result returned here
+   * @return none.
+   */
+
+  void arm_dot_prod_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  uint32_t blockSize,
+  q63_t * result);
+
+  /**
+   * @brief Dot product of Q31 vectors.
+   * @param[in]       *pSrcA points to the first input vector
+   * @param[in]       *pSrcB points to the second input vector
+   * @param[in]       blockSize number of samples in each vector
+   * @param[out]      *result output result returned here
+   * @return none.
+   */
+
+  void arm_dot_prod_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  uint32_t blockSize,
+  q63_t * result);
+
+  /**
+   * @brief  Shifts the elements of a Q7 vector a specified number of bits.
+   * @param[in]  *pSrc points to the input vector
+   * @param[in]  shiftBits number of bits to shift.  A positive value shifts left; a negative value shifts right.
+   * @param[out]  *pDst points to the output vector
+   * @param[in]  blockSize number of samples in the vector
+   * @return none.
+   */
+
+  void arm_shift_q7(
+  q7_t * pSrc,
+  int8_t shiftBits,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Shifts the elements of a Q15 vector a specified number of bits.
+   * @param[in]  *pSrc points to the input vector
+   * @param[in]  shiftBits number of bits to shift.  A positive value shifts left; a negative value shifts right.
+   * @param[out]  *pDst points to the output vector
+   * @param[in]  blockSize number of samples in the vector
+   * @return none.
+   */
+
+  void arm_shift_q15(
+  q15_t * pSrc,
+  int8_t shiftBits,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Shifts the elements of a Q31 vector a specified number of bits.
+   * @param[in]  *pSrc points to the input vector
+   * @param[in]  shiftBits number of bits to shift.  A positive value shifts left; a negative value shifts right.
+   * @param[out]  *pDst points to the output vector
+   * @param[in]  blockSize number of samples in the vector
+   * @return none.
+   */
+
+  void arm_shift_q31(
+  q31_t * pSrc,
+  int8_t shiftBits,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Adds a constant offset to a floating-point vector.
+   * @param[in]  *pSrc points to the input vector
+   * @param[in]  offset is the offset to be added
+   * @param[out]  *pDst points to the output vector
+   * @param[in]  blockSize number of samples in the vector
+   * @return none.
+   */
+
+  void arm_offset_f32(
+  float32_t * pSrc,
+  float32_t offset,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Adds a constant offset to a Q7 vector.
+   * @param[in]  *pSrc points to the input vector
+   * @param[in]  offset is the offset to be added
+   * @param[out]  *pDst points to the output vector
+   * @param[in]  blockSize number of samples in the vector
+   * @return none.
+   */
+
+  void arm_offset_q7(
+  q7_t * pSrc,
+  q7_t offset,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Adds a constant offset to a Q15 vector.
+   * @param[in]  *pSrc points to the input vector
+   * @param[in]  offset is the offset to be added
+   * @param[out]  *pDst points to the output vector
+   * @param[in]  blockSize number of samples in the vector
+   * @return none.
+   */
+
+  void arm_offset_q15(
+  q15_t * pSrc,
+  q15_t offset,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Adds a constant offset to a Q31 vector.
+   * @param[in]  *pSrc points to the input vector
+   * @param[in]  offset is the offset to be added
+   * @param[out]  *pDst points to the output vector
+   * @param[in]  blockSize number of samples in the vector
+   * @return none.
+   */
+
+  void arm_offset_q31(
+  q31_t * pSrc,
+  q31_t offset,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Negates the elements of a floating-point vector.
+   * @param[in]  *pSrc points to the input vector
+   * @param[out]  *pDst points to the output vector
+   * @param[in]  blockSize number of samples in the vector
+   * @return none.
+   */
+
+  void arm_negate_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Negates the elements of a Q7 vector.
+   * @param[in]  *pSrc points to the input vector
+   * @param[out]  *pDst points to the output vector
+   * @param[in]  blockSize number of samples in the vector
+   * @return none.
+   */
+
+  void arm_negate_q7(
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Negates the elements of a Q15 vector.
+   * @param[in]  *pSrc points to the input vector
+   * @param[out]  *pDst points to the output vector
+   * @param[in]  blockSize number of samples in the vector
+   * @return none.
+   */
+
+  void arm_negate_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Negates the elements of a Q31 vector.
+   * @param[in]  *pSrc points to the input vector
+   * @param[out]  *pDst points to the output vector
+   * @param[in]  blockSize number of samples in the vector
+   * @return none.
+   */
+
+  void arm_negate_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+  /**
+   * @brief  Copies the elements of a floating-point vector.
+   * @param[in]  *pSrc input pointer
+   * @param[out]  *pDst output pointer
+   * @param[in]  blockSize number of samples to process
+   * @return none.
+   */
+  void arm_copy_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Copies the elements of a Q7 vector.
+   * @param[in]  *pSrc input pointer
+   * @param[out]  *pDst output pointer
+   * @param[in]  blockSize number of samples to process
+   * @return none.
+   */
+  void arm_copy_q7(
+  q7_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Copies the elements of a Q15 vector.
+   * @param[in]  *pSrc input pointer
+   * @param[out]  *pDst output pointer
+   * @param[in]  blockSize number of samples to process
+   * @return none.
+   */
+  void arm_copy_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Copies the elements of a Q31 vector.
+   * @param[in]  *pSrc input pointer
+   * @param[out]  *pDst output pointer
+   * @param[in]  blockSize number of samples to process
+   * @return none.
+   */
+  void arm_copy_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+  /**
+   * @brief  Fills a constant value into a floating-point vector.
+   * @param[in]  value input value to be filled
+   * @param[out]  *pDst output pointer
+   * @param[in]  blockSize number of samples to process
+   * @return none.
+   */
+  void arm_fill_f32(
+  float32_t value,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Fills a constant value into a Q7 vector.
+   * @param[in]  value input value to be filled
+   * @param[out]  *pDst output pointer
+   * @param[in]  blockSize number of samples to process
+   * @return none.
+   */
+  void arm_fill_q7(
+  q7_t value,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Fills a constant value into a Q15 vector.
+   * @param[in]  value input value to be filled
+   * @param[out]  *pDst output pointer
+   * @param[in]  blockSize number of samples to process
+   * @return none.
+   */
+  void arm_fill_q15(
+  q15_t value,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Fills a constant value into a Q31 vector.
+   * @param[in]  value input value to be filled
+   * @param[out]  *pDst output pointer
+   * @param[in]  blockSize number of samples to process
+   * @return none.
+   */
+  void arm_fill_q31(
+  q31_t value,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+/**
+ * @brief Convolution of floating-point sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the location where the output result is written.  Length srcALen+srcBLen-1.
+ * @return none.
+ */
+
+  void arm_conv_f32(
+  float32_t * pSrcA,
+  uint32_t srcALen,
+  float32_t * pSrcB,
+  uint32_t srcBLen,
+  float32_t * pDst);
+
+
+  /**
+   * @brief Convolution of Q15 sequences.
+   * @param[in] *pSrcA points to the first input sequence.
+   * @param[in] srcALen length of the first input sequence.
+   * @param[in] *pSrcB points to the second input sequence.
+   * @param[in] srcBLen length of the second input sequence.
+   * @param[out] *pDst points to the block of output data  Length srcALen+srcBLen-1.
+   * @param[in]  *pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]  *pScratch2 points to scratch buffer of size min(srcALen, srcBLen).
+   * @return none.
+   */
+
+
+  void arm_conv_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+/**
+ * @brief Convolution of Q15 sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the location where the output result is written.  Length srcALen+srcBLen-1.
+ * @return none.
+ */
+
+  void arm_conv_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst);
+
+  /**
+   * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in] *pSrcA points to the first input sequence.
+   * @param[in] srcALen length of the first input sequence.
+   * @param[in] *pSrcB points to the second input sequence.
+   * @param[in] srcBLen length of the second input sequence.
+   * @param[out] *pDst points to the block of output data  Length srcALen+srcBLen-1.
+   * @return none.
+   */
+
+  void arm_conv_fast_q15(
+			  q15_t * pSrcA,
+			 uint32_t srcALen,
+			  q15_t * pSrcB,
+			 uint32_t srcBLen,
+			 q15_t * pDst);
+
+  /**
+   * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in] *pSrcA points to the first input sequence.
+   * @param[in] srcALen length of the first input sequence.
+   * @param[in] *pSrcB points to the second input sequence.
+   * @param[in] srcBLen length of the second input sequence.
+   * @param[out] *pDst points to the block of output data  Length srcALen+srcBLen-1.
+   * @param[in]  *pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]  *pScratch2 points to scratch buffer of size min(srcALen, srcBLen).
+   * @return none.
+   */
+
+  void arm_conv_fast_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+
+  /**
+   * @brief Convolution of Q31 sequences.
+   * @param[in] *pSrcA points to the first input sequence.
+   * @param[in] srcALen length of the first input sequence.
+   * @param[in] *pSrcB points to the second input sequence.
+   * @param[in] srcBLen length of the second input sequence.
+   * @param[out] *pDst points to the block of output data  Length srcALen+srcBLen-1.
+   * @return none.
+   */
+
+  void arm_conv_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+  /**
+   * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in] *pSrcA points to the first input sequence.
+   * @param[in] srcALen length of the first input sequence.
+   * @param[in] *pSrcB points to the second input sequence.
+   * @param[in] srcBLen length of the second input sequence.
+   * @param[out] *pDst points to the block of output data  Length srcALen+srcBLen-1.
+   * @return none.
+   */
+
+  void arm_conv_fast_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+
+    /**
+   * @brief Convolution of Q7 sequences.
+   * @param[in] *pSrcA points to the first input sequence.
+   * @param[in] srcALen length of the first input sequence.
+   * @param[in] *pSrcB points to the second input sequence.
+   * @param[in] srcBLen length of the second input sequence.
+   * @param[out] *pDst points to the block of output data  Length srcALen+srcBLen-1.
+   * @param[in]  *pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]  *pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen).
+   * @return none.
+   */
+
+  void arm_conv_opt_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+
+  /**
+   * @brief Convolution of Q7 sequences.
+   * @param[in] *pSrcA points to the first input sequence.
+   * @param[in] srcALen length of the first input sequence.
+   * @param[in] *pSrcB points to the second input sequence.
+   * @param[in] srcBLen length of the second input sequence.
+   * @param[out] *pDst points to the block of output data  Length srcALen+srcBLen-1.
+   * @return none.
+   */
+
+  void arm_conv_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst);
+
+
+  /**
+   * @brief Partial convolution of floating-point sequences.
+   * @param[in]       *pSrcA points to the first input sequence.
+   * @param[in]       srcALen length of the first input sequence.
+   * @param[in]       *pSrcB points to the second input sequence.
+   * @param[in]       srcBLen length of the second input sequence.
+   * @param[out]      *pDst points to the block of output data
+   * @param[in]       firstIndex is the first output sample to start with.
+   * @param[in]       numPoints is the number of output points to be computed.
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+
+  arm_status arm_conv_partial_f32(
+  float32_t * pSrcA,
+  uint32_t srcALen,
+  float32_t * pSrcB,
+  uint32_t srcBLen,
+  float32_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+    /**
+   * @brief Partial convolution of Q15 sequences.
+   * @param[in]       *pSrcA points to the first input sequence.
+   * @param[in]       srcALen length of the first input sequence.
+   * @param[in]       *pSrcB points to the second input sequence.
+   * @param[in]       srcBLen length of the second input sequence.
+   * @param[out]      *pDst points to the block of output data
+   * @param[in]       firstIndex is the first output sample to start with.
+   * @param[in]       numPoints is the number of output points to be computed.
+   * @param[in]       * pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]       * pScratch2 points to scratch buffer of size min(srcALen, srcBLen).
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+
+  arm_status arm_conv_partial_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+/**
+   * @brief Partial convolution of Q15 sequences.
+   * @param[in]       *pSrcA points to the first input sequence.
+   * @param[in]       srcALen length of the first input sequence.
+   * @param[in]       *pSrcB points to the second input sequence.
+   * @param[in]       srcBLen length of the second input sequence.
+   * @param[out]      *pDst points to the block of output data
+   * @param[in]       firstIndex is the first output sample to start with.
+   * @param[in]       numPoints is the number of output points to be computed.
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+
+  arm_status arm_conv_partial_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+  /**
+   * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in]       *pSrcA points to the first input sequence.
+   * @param[in]       srcALen length of the first input sequence.
+   * @param[in]       *pSrcB points to the second input sequence.
+   * @param[in]       srcBLen length of the second input sequence.
+   * @param[out]      *pDst points to the block of output data
+   * @param[in]       firstIndex is the first output sample to start with.
+   * @param[in]       numPoints is the number of output points to be computed.
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+
+  arm_status arm_conv_partial_fast_q15(
+				        q15_t * pSrcA,
+				       uint32_t srcALen,
+				        q15_t * pSrcB,
+				       uint32_t srcBLen,
+				       q15_t * pDst,
+				       uint32_t firstIndex,
+				       uint32_t numPoints);
+
+
+  /**
+   * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in]       *pSrcA points to the first input sequence.
+   * @param[in]       srcALen length of the first input sequence.
+   * @param[in]       *pSrcB points to the second input sequence.
+   * @param[in]       srcBLen length of the second input sequence.
+   * @param[out]      *pDst points to the block of output data
+   * @param[in]       firstIndex is the first output sample to start with.
+   * @param[in]       numPoints is the number of output points to be computed.
+   * @param[in]       * pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]       * pScratch2 points to scratch buffer of size min(srcALen, srcBLen).
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+
+  arm_status arm_conv_partial_fast_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+  /**
+   * @brief Partial convolution of Q31 sequences.
+   * @param[in]       *pSrcA points to the first input sequence.
+   * @param[in]       srcALen length of the first input sequence.
+   * @param[in]       *pSrcB points to the second input sequence.
+   * @param[in]       srcBLen length of the second input sequence.
+   * @param[out]      *pDst points to the block of output data
+   * @param[in]       firstIndex is the first output sample to start with.
+   * @param[in]       numPoints is the number of output points to be computed.
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+
+  arm_status arm_conv_partial_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+
+  /**
+   * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in]       *pSrcA points to the first input sequence.
+   * @param[in]       srcALen length of the first input sequence.
+   * @param[in]       *pSrcB points to the second input sequence.
+   * @param[in]       srcBLen length of the second input sequence.
+   * @param[out]      *pDst points to the block of output data
+   * @param[in]       firstIndex is the first output sample to start with.
+   * @param[in]       numPoints is the number of output points to be computed.
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+
+  arm_status arm_conv_partial_fast_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+
+  /**
+   * @brief Partial convolution of Q7 sequences
+   * @param[in]       *pSrcA points to the first input sequence.
+   * @param[in]       srcALen length of the first input sequence.
+   * @param[in]       *pSrcB points to the second input sequence.
+   * @param[in]       srcBLen length of the second input sequence.
+   * @param[out]      *pDst points to the block of output data
+   * @param[in]       firstIndex is the first output sample to start with.
+   * @param[in]       numPoints is the number of output points to be computed.
+   * @param[in]  *pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]  *pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen).
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+
+  arm_status arm_conv_partial_opt_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+/**
+   * @brief Partial convolution of Q7 sequences.
+   * @param[in]       *pSrcA points to the first input sequence.
+   * @param[in]       srcALen length of the first input sequence.
+   * @param[in]       *pSrcB points to the second input sequence.
+   * @param[in]       srcBLen length of the second input sequence.
+   * @param[out]      *pDst points to the block of output data
+   * @param[in]       firstIndex is the first output sample to start with.
+   * @param[in]       numPoints is the number of output points to be computed.
+   * @return  Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+   */
+
+  arm_status arm_conv_partial_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  uint32_t firstIndex,
+  uint32_t numPoints);
+
+
+
+  /**
+   * @brief Instance structure for the Q15 FIR decimator.
+   */
+
+  typedef struct
+  {
+    uint8_t M;                      /**< decimation factor. */
+    uint16_t numTaps;               /**< number of coefficients in the filter. */
+    q15_t *pCoeffs;                  /**< points to the coefficient array. The array is of length numTaps.*/
+    q15_t *pState;                   /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+  } arm_fir_decimate_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR decimator.
+   */
+
+  typedef struct
+  {
+    uint8_t M;                  /**< decimation factor. */
+    uint16_t numTaps;           /**< number of coefficients in the filter. */
+    q31_t *pCoeffs;              /**< points to the coefficient array. The array is of length numTaps.*/
+    q31_t *pState;               /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+
+  } arm_fir_decimate_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR decimator.
+   */
+
+  typedef struct
+  {
+    uint8_t M;                          /**< decimation factor. */
+    uint16_t numTaps;                   /**< number of coefficients in the filter. */
+    float32_t *pCoeffs;                  /**< points to the coefficient array. The array is of length numTaps.*/
+    float32_t *pState;                   /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+
+  } arm_fir_decimate_instance_f32;
+
+
+
+  /**
+   * @brief Processing function for the floating-point FIR decimator.
+   * @param[in] *S points to an instance of the floating-point FIR decimator structure.
+   * @param[in] *pSrc points to the block of input data.
+   * @param[out] *pDst points to the block of output data
+   * @param[in] blockSize number of input samples to process per call.
+   * @return none
+   */
+
+  void arm_fir_decimate_f32(
+  const arm_fir_decimate_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the floating-point FIR decimator.
+   * @param[in,out] *S points to an instance of the floating-point FIR decimator structure.
+   * @param[in] numTaps  number of coefficients in the filter.
+   * @param[in] M  decimation factor.
+   * @param[in] *pCoeffs points to the filter coefficients.
+   * @param[in] *pState points to the state buffer.
+   * @param[in] blockSize number of input samples to process per call.
+   * @return    The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+   * <code>blockSize</code> is not a multiple of <code>M</code>.
+   */
+
+  arm_status arm_fir_decimate_init_f32(
+  arm_fir_decimate_instance_f32 * S,
+  uint16_t numTaps,
+  uint8_t M,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+  /**
+   * @brief Processing function for the Q15 FIR decimator.
+   * @param[in] *S points to an instance of the Q15 FIR decimator structure.
+   * @param[in] *pSrc points to the block of input data.
+   * @param[out] *pDst points to the block of output data
+   * @param[in] blockSize number of input samples to process per call.
+   * @return none
+   */
+
+  void arm_fir_decimate_q15(
+  const arm_fir_decimate_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4.
+   * @param[in] *S points to an instance of the Q15 FIR decimator structure.
+   * @param[in] *pSrc points to the block of input data.
+   * @param[out] *pDst points to the block of output data
+   * @param[in] blockSize number of input samples to process per call.
+   * @return none
+   */
+
+  void arm_fir_decimate_fast_q15(
+  const arm_fir_decimate_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+
+  /**
+   * @brief  Initialization function for the Q15 FIR decimator.
+   * @param[in,out] *S points to an instance of the Q15 FIR decimator structure.
+   * @param[in] numTaps  number of coefficients in the filter.
+   * @param[in] M  decimation factor.
+   * @param[in] *pCoeffs points to the filter coefficients.
+   * @param[in] *pState points to the state buffer.
+   * @param[in] blockSize number of input samples to process per call.
+   * @return    The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+   * <code>blockSize</code> is not a multiple of <code>M</code>.
+   */
+
+  arm_status arm_fir_decimate_init_q15(
+  arm_fir_decimate_instance_q15 * S,
+  uint16_t numTaps,
+  uint8_t M,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+  /**
+   * @brief Processing function for the Q31 FIR decimator.
+   * @param[in] *S points to an instance of the Q31 FIR decimator structure.
+   * @param[in] *pSrc points to the block of input data.
+   * @param[out] *pDst points to the block of output data
+   * @param[in] blockSize number of input samples to process per call.
+   * @return none
+   */
+
+  void arm_fir_decimate_q31(
+  const arm_fir_decimate_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4.
+   * @param[in] *S points to an instance of the Q31 FIR decimator structure.
+   * @param[in] *pSrc points to the block of input data.
+   * @param[out] *pDst points to the block of output data
+   * @param[in] blockSize number of input samples to process per call.
+   * @return none
+   */
+
+  void arm_fir_decimate_fast_q31(
+  arm_fir_decimate_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q31 FIR decimator.
+   * @param[in,out] *S points to an instance of the Q31 FIR decimator structure.
+   * @param[in] numTaps  number of coefficients in the filter.
+   * @param[in] M  decimation factor.
+   * @param[in] *pCoeffs points to the filter coefficients.
+   * @param[in] *pState points to the state buffer.
+   * @param[in] blockSize number of input samples to process per call.
+   * @return    The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+   * <code>blockSize</code> is not a multiple of <code>M</code>.
+   */
+
+  arm_status arm_fir_decimate_init_q31(
+  arm_fir_decimate_instance_q31 * S,
+  uint16_t numTaps,
+  uint8_t M,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+
+
+  /**
+   * @brief Instance structure for the Q15 FIR interpolator.
+   */
+
+  typedef struct
+  {
+    uint8_t L;                      /**< upsample factor. */
+    uint16_t phaseLength;           /**< length of each polyphase filter component. */
+    q15_t *pCoeffs;                 /**< points to the coefficient array. The array is of length L*phaseLength. */
+    q15_t *pState;                  /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */
+  } arm_fir_interpolate_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR interpolator.
+   */
+
+  typedef struct
+  {
+    uint8_t L;                      /**< upsample factor. */
+    uint16_t phaseLength;           /**< length of each polyphase filter component. */
+    q31_t *pCoeffs;                  /**< points to the coefficient array. The array is of length L*phaseLength. */
+    q31_t *pState;                   /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */
+  } arm_fir_interpolate_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR interpolator.
+   */
+
+  typedef struct
+  {
+    uint8_t L;                     /**< upsample factor. */
+    uint16_t phaseLength;          /**< length of each polyphase filter component. */
+    float32_t *pCoeffs;             /**< points to the coefficient array. The array is of length L*phaseLength. */
+    float32_t *pState;              /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */
+  } arm_fir_interpolate_instance_f32;
+
+
+  /**
+   * @brief Processing function for the Q15 FIR interpolator.
+   * @param[in] *S        points to an instance of the Q15 FIR interpolator structure.
+   * @param[in] *pSrc     points to the block of input data.
+   * @param[out] *pDst    points to the block of output data.
+   * @param[in] blockSize number of input samples to process per call.
+   * @return none.
+   */
+
+  void arm_fir_interpolate_q15(
+  const arm_fir_interpolate_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q15 FIR interpolator.
+   * @param[in,out] *S        points to an instance of the Q15 FIR interpolator structure.
+   * @param[in]     L         upsample factor.
+   * @param[in]     numTaps   number of filter coefficients in the filter.
+   * @param[in]     *pCoeffs  points to the filter coefficient buffer.
+   * @param[in]     *pState   points to the state buffer.
+   * @param[in]     blockSize number of input samples to process per call.
+   * @return        The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+   * the filter length <code>numTaps</code> is not a multiple of the interpolation factor <code>L</code>.
+   */
+
+  arm_status arm_fir_interpolate_init_q15(
+  arm_fir_interpolate_instance_q15 * S,
+  uint8_t L,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+  /**
+   * @brief Processing function for the Q31 FIR interpolator.
+   * @param[in] *S        points to an instance of the Q15 FIR interpolator structure.
+   * @param[in] *pSrc     points to the block of input data.
+   * @param[out] *pDst    points to the block of output data.
+   * @param[in] blockSize number of input samples to process per call.
+   * @return none.
+   */
+
+  void arm_fir_interpolate_q31(
+  const arm_fir_interpolate_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Initialization function for the Q31 FIR interpolator.
+   * @param[in,out] *S        points to an instance of the Q31 FIR interpolator structure.
+   * @param[in]     L         upsample factor.
+   * @param[in]     numTaps   number of filter coefficients in the filter.
+   * @param[in]     *pCoeffs  points to the filter coefficient buffer.
+   * @param[in]     *pState   points to the state buffer.
+   * @param[in]     blockSize number of input samples to process per call.
+   * @return        The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+   * the filter length <code>numTaps</code> is not a multiple of the interpolation factor <code>L</code>.
+   */
+
+  arm_status arm_fir_interpolate_init_q31(
+  arm_fir_interpolate_instance_q31 * S,
+  uint8_t L,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the floating-point FIR interpolator.
+   * @param[in] *S        points to an instance of the floating-point FIR interpolator structure.
+   * @param[in] *pSrc     points to the block of input data.
+   * @param[out] *pDst    points to the block of output data.
+   * @param[in] blockSize number of input samples to process per call.
+   * @return none.
+   */
+
+  void arm_fir_interpolate_f32(
+  const arm_fir_interpolate_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Initialization function for the floating-point FIR interpolator.
+   * @param[in,out] *S        points to an instance of the floating-point FIR interpolator structure.
+   * @param[in]     L         upsample factor.
+   * @param[in]     numTaps   number of filter coefficients in the filter.
+   * @param[in]     *pCoeffs  points to the filter coefficient buffer.
+   * @param[in]     *pState   points to the state buffer.
+   * @param[in]     blockSize number of input samples to process per call.
+   * @return        The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+   * the filter length <code>numTaps</code> is not a multiple of the interpolation factor <code>L</code>.
+   */
+
+  arm_status arm_fir_interpolate_init_f32(
+  arm_fir_interpolate_instance_f32 * S,
+  uint8_t L,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+  /**
+   * @brief Instance structure for the high precision Q31 Biquad cascade filter.
+   */
+
+  typedef struct
+  {
+    uint8_t numStages;       /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    q63_t *pState;           /**< points to the array of state coefficients.  The array is of length 4*numStages. */
+    q31_t *pCoeffs;          /**< points to the array of coefficients.  The array is of length 5*numStages. */
+    uint8_t postShift;       /**< additional shift, in bits, applied to each output sample. */
+
+  } arm_biquad_cas_df1_32x64_ins_q31;
+
+
+  /**
+   * @param[in]  *S        points to an instance of the high precision Q31 Biquad cascade filter structure.
+   * @param[in]  *pSrc     points to the block of input data.
+   * @param[out] *pDst     points to the block of output data
+   * @param[in]  blockSize number of samples to process.
+   * @return none.
+   */
+
+  void arm_biquad_cas_df1_32x64_q31(
+  const arm_biquad_cas_df1_32x64_ins_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @param[in,out] *S           points to an instance of the high precision Q31 Biquad cascade filter structure.
+   * @param[in]     numStages    number of 2nd order stages in the filter.
+   * @param[in]     *pCoeffs     points to the filter coefficients.
+   * @param[in]     *pState      points to the state buffer.
+   * @param[in]     postShift    shift to be applied to the output. Varies according to the coefficients format
+   * @return        none
+   */
+
+  void arm_biquad_cas_df1_32x64_init_q31(
+  arm_biquad_cas_df1_32x64_ins_q31 * S,
+  uint8_t numStages,
+  q31_t * pCoeffs,
+  q63_t * pState,
+  uint8_t postShift);
+
+
+
+  /**
+   * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+   */
+
+  typedef struct
+  {
+    uint8_t numStages;         /**< number of 2nd order stages in the filter.  Overall order is 2*numStages. */
+    float32_t *pState;         /**< points to the array of state coefficients.  The array is of length 2*numStages. */
+    float32_t *pCoeffs;        /**< points to the array of coefficients.  The array is of length 5*numStages. */
+  } arm_biquad_cascade_df2T_instance_f32;
+
+
+  /**
+   * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter.
+   * @param[in]  *S        points to an instance of the filter data structure.
+   * @param[in]  *pSrc     points to the block of input data.
+   * @param[out] *pDst     points to the block of output data
+   * @param[in]  blockSize number of samples to process.
+   * @return none.
+   */
+
+  void arm_biquad_cascade_df2T_f32(
+  const arm_biquad_cascade_df2T_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the floating-point transposed direct form II Biquad cascade filter.
+   * @param[in,out] *S           points to an instance of the filter data structure.
+   * @param[in]     numStages    number of 2nd order stages in the filter.
+   * @param[in]     *pCoeffs     points to the filter coefficients.
+   * @param[in]     *pState      points to the state buffer.
+   * @return        none
+   */
+
+  void arm_biquad_cascade_df2T_init_f32(
+  arm_biquad_cascade_df2T_instance_f32 * S,
+  uint8_t numStages,
+  float32_t * pCoeffs,
+  float32_t * pState);
+
+
+
+  /**
+   * @brief Instance structure for the Q15 FIR lattice filter.
+   */
+
+  typedef struct
+  {
+    uint16_t numStages;                          /**< number of filter stages. */
+    q15_t *pState;                               /**< points to the state variable array. The array is of length numStages. */
+    q15_t *pCoeffs;                              /**< points to the coefficient array. The array is of length numStages. */
+  } arm_fir_lattice_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 FIR lattice filter.
+   */
+
+  typedef struct
+  {
+    uint16_t numStages;                          /**< number of filter stages. */
+    q31_t *pState;                               /**< points to the state variable array. The array is of length numStages. */
+    q31_t *pCoeffs;                              /**< points to the coefficient array. The array is of length numStages. */
+  } arm_fir_lattice_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point FIR lattice filter.
+   */
+
+  typedef struct
+  {
+    uint16_t numStages;                  /**< number of filter stages. */
+    float32_t *pState;                   /**< points to the state variable array. The array is of length numStages. */
+    float32_t *pCoeffs;                  /**< points to the coefficient array. The array is of length numStages. */
+  } arm_fir_lattice_instance_f32;
+
+  /**
+   * @brief Initialization function for the Q15 FIR lattice filter.
+   * @param[in] *S points to an instance of the Q15 FIR lattice structure.
+   * @param[in] numStages  number of filter stages.
+   * @param[in] *pCoeffs points to the coefficient buffer.  The array is of length numStages.
+   * @param[in] *pState points to the state buffer.  The array is of length numStages.
+   * @return none.
+   */
+
+  void arm_fir_lattice_init_q15(
+  arm_fir_lattice_instance_q15 * S,
+  uint16_t numStages,
+  q15_t * pCoeffs,
+  q15_t * pState);
+
+
+  /**
+   * @brief Processing function for the Q15 FIR lattice filter.
+   * @param[in] *S points to an instance of the Q15 FIR lattice structure.
+   * @param[in] *pSrc points to the block of input data.
+   * @param[out] *pDst points to the block of output data.
+   * @param[in] blockSize number of samples to process.
+   * @return none.
+   */
+  void arm_fir_lattice_q15(
+  const arm_fir_lattice_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Initialization function for the Q31 FIR lattice filter.
+   * @param[in] *S points to an instance of the Q31 FIR lattice structure.
+   * @param[in] numStages  number of filter stages.
+   * @param[in] *pCoeffs points to the coefficient buffer.  The array is of length numStages.
+   * @param[in] *pState points to the state buffer.   The array is of length numStages.
+   * @return none.
+   */
+
+  void arm_fir_lattice_init_q31(
+  arm_fir_lattice_instance_q31 * S,
+  uint16_t numStages,
+  q31_t * pCoeffs,
+  q31_t * pState);
+
+
+  /**
+   * @brief Processing function for the Q31 FIR lattice filter.
+   * @param[in]  *S        points to an instance of the Q31 FIR lattice structure.
+   * @param[in]  *pSrc     points to the block of input data.
+   * @param[out] *pDst     points to the block of output data
+   * @param[in]  blockSize number of samples to process.
+   * @return none.
+   */
+
+  void arm_fir_lattice_q31(
+  const arm_fir_lattice_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+/**
+ * @brief Initialization function for the floating-point FIR lattice filter.
+ * @param[in] *S points to an instance of the floating-point FIR lattice structure.
+ * @param[in] numStages  number of filter stages.
+ * @param[in] *pCoeffs points to the coefficient buffer.  The array is of length numStages.
+ * @param[in] *pState points to the state buffer.  The array is of length numStages.
+ * @return none.
+ */
+
+  void arm_fir_lattice_init_f32(
+  arm_fir_lattice_instance_f32 * S,
+  uint16_t numStages,
+  float32_t * pCoeffs,
+  float32_t * pState);
+
+  /**
+   * @brief Processing function for the floating-point FIR lattice filter.
+   * @param[in]  *S        points to an instance of the floating-point FIR lattice structure.
+   * @param[in]  *pSrc     points to the block of input data.
+   * @param[out] *pDst     points to the block of output data
+   * @param[in]  blockSize number of samples to process.
+   * @return none.
+   */
+
+  void arm_fir_lattice_f32(
+  const arm_fir_lattice_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Instance structure for the Q15 IIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                         /**< number of stages in the filter. */
+    q15_t *pState;                              /**< points to the state variable array. The array is of length numStages+blockSize. */
+    q15_t *pkCoeffs;                            /**< points to the reflection coefficient array. The array is of length numStages. */
+    q15_t *pvCoeffs;                            /**< points to the ladder coefficient array. The array is of length numStages+1. */
+  } arm_iir_lattice_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q31 IIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                         /**< number of stages in the filter. */
+    q31_t *pState;                              /**< points to the state variable array. The array is of length numStages+blockSize. */
+    q31_t *pkCoeffs;                            /**< points to the reflection coefficient array. The array is of length numStages. */
+    q31_t *pvCoeffs;                            /**< points to the ladder coefficient array. The array is of length numStages+1. */
+  } arm_iir_lattice_instance_q31;
+
+  /**
+   * @brief Instance structure for the floating-point IIR lattice filter.
+   */
+  typedef struct
+  {
+    uint16_t numStages;                         /**< number of stages in the filter. */
+    float32_t *pState;                          /**< points to the state variable array. The array is of length numStages+blockSize. */
+    float32_t *pkCoeffs;                        /**< points to the reflection coefficient array. The array is of length numStages. */
+    float32_t *pvCoeffs;                        /**< points to the ladder coefficient array. The array is of length numStages+1. */
+  } arm_iir_lattice_instance_f32;
+
+  /**
+   * @brief Processing function for the floating-point IIR lattice filter.
+   * @param[in] *S points to an instance of the floating-point IIR lattice structure.
+   * @param[in] *pSrc points to the block of input data.
+   * @param[out] *pDst points to the block of output data.
+   * @param[in] blockSize number of samples to process.
+   * @return none.
+   */
+
+  void arm_iir_lattice_f32(
+  const arm_iir_lattice_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Initialization function for the floating-point IIR lattice filter.
+   * @param[in] *S points to an instance of the floating-point IIR lattice structure.
+   * @param[in] numStages number of stages in the filter.
+   * @param[in] *pkCoeffs points to the reflection coefficient buffer.  The array is of length numStages.
+   * @param[in] *pvCoeffs points to the ladder coefficient buffer.  The array is of length numStages+1.
+   * @param[in] *pState points to the state buffer.  The array is of length numStages+blockSize-1.
+   * @param[in] blockSize number of samples to process.
+   * @return none.
+   */
+
+  void arm_iir_lattice_init_f32(
+  arm_iir_lattice_instance_f32 * S,
+  uint16_t numStages,
+  float32_t * pkCoeffs,
+  float32_t * pvCoeffs,
+  float32_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q31 IIR lattice filter.
+   * @param[in] *S points to an instance of the Q31 IIR lattice structure.
+   * @param[in] *pSrc points to the block of input data.
+   * @param[out] *pDst points to the block of output data.
+   * @param[in] blockSize number of samples to process.
+   * @return none.
+   */
+
+  void arm_iir_lattice_q31(
+  const arm_iir_lattice_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Initialization function for the Q31 IIR lattice filter.
+   * @param[in] *S points to an instance of the Q31 IIR lattice structure.
+   * @param[in] numStages number of stages in the filter.
+   * @param[in] *pkCoeffs points to the reflection coefficient buffer.  The array is of length numStages.
+   * @param[in] *pvCoeffs points to the ladder coefficient buffer.  The array is of length numStages+1.
+   * @param[in] *pState points to the state buffer.  The array is of length numStages+blockSize.
+   * @param[in] blockSize number of samples to process.
+   * @return none.
+   */
+
+  void arm_iir_lattice_init_q31(
+  arm_iir_lattice_instance_q31 * S,
+  uint16_t numStages,
+  q31_t * pkCoeffs,
+  q31_t * pvCoeffs,
+  q31_t * pState,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Processing function for the Q15 IIR lattice filter.
+   * @param[in] *S points to an instance of the Q15 IIR lattice structure.
+   * @param[in] *pSrc points to the block of input data.
+   * @param[out] *pDst points to the block of output data.
+   * @param[in] blockSize number of samples to process.
+   * @return none.
+   */
+
+  void arm_iir_lattice_q15(
+  const arm_iir_lattice_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+/**
+ * @brief Initialization function for the Q15 IIR lattice filter.
+ * @param[in] *S points to an instance of the fixed-point Q15 IIR lattice structure.
+ * @param[in] numStages  number of stages in the filter.
+ * @param[in] *pkCoeffs points to reflection coefficient buffer.  The array is of length numStages.
+ * @param[in] *pvCoeffs points to ladder coefficient buffer.  The array is of length numStages+1.
+ * @param[in] *pState points to state buffer.  The array is of length numStages+blockSize.
+ * @param[in] blockSize number of samples to process per call.
+ * @return none.
+ */
+
+  void arm_iir_lattice_init_q15(
+  arm_iir_lattice_instance_q15 * S,
+  uint16_t numStages,
+  q15_t * pkCoeffs,
+  q15_t * pvCoeffs,
+  q15_t * pState,
+  uint32_t blockSize);
+
+  /**
+   * @brief Instance structure for the floating-point LMS filter.
+   */
+
+  typedef struct
+  {
+    uint16_t numTaps;    /**< number of coefficients in the filter. */
+    float32_t *pState;   /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    float32_t *pCoeffs;  /**< points to the coefficient array. The array is of length numTaps. */
+    float32_t mu;        /**< step size that controls filter coefficient updates. */
+  } arm_lms_instance_f32;
+
+  /**
+   * @brief Processing function for floating-point LMS filter.
+   * @param[in]  *S points to an instance of the floating-point LMS filter structure.
+   * @param[in]  *pSrc points to the block of input data.
+   * @param[in]  *pRef points to the block of reference data.
+   * @param[out] *pOut points to the block of output data.
+   * @param[out] *pErr points to the block of error data.
+   * @param[in]  blockSize number of samples to process.
+   * @return     none.
+   */
+
+  void arm_lms_f32(
+  const arm_lms_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pRef,
+  float32_t * pOut,
+  float32_t * pErr,
+  uint32_t blockSize);
+
+  /**
+   * @brief Initialization function for floating-point LMS filter.
+   * @param[in] *S points to an instance of the floating-point LMS filter structure.
+   * @param[in] numTaps  number of filter coefficients.
+   * @param[in] *pCoeffs points to the coefficient buffer.
+   * @param[in] *pState points to state buffer.
+   * @param[in] mu step size that controls filter coefficient updates.
+   * @param[in] blockSize number of samples to process.
+   * @return none.
+   */
+
+  void arm_lms_init_f32(
+  arm_lms_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  float32_t mu,
+  uint32_t blockSize);
+
+  /**
+   * @brief Instance structure for the Q15 LMS filter.
+   */
+
+  typedef struct
+  {
+    uint16_t numTaps;    /**< number of coefficients in the filter. */
+    q15_t *pState;       /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q15_t *pCoeffs;      /**< points to the coefficient array. The array is of length numTaps. */
+    q15_t mu;            /**< step size that controls filter coefficient updates. */
+    uint32_t postShift;  /**< bit shift applied to coefficients. */
+  } arm_lms_instance_q15;
+
+
+  /**
+   * @brief Initialization function for the Q15 LMS filter.
+   * @param[in] *S points to an instance of the Q15 LMS filter structure.
+   * @param[in] numTaps  number of filter coefficients.
+   * @param[in] *pCoeffs points to the coefficient buffer.
+   * @param[in] *pState points to the state buffer.
+   * @param[in] mu step size that controls filter coefficient updates.
+   * @param[in] blockSize number of samples to process.
+   * @param[in] postShift bit shift applied to coefficients.
+   * @return    none.
+   */
+
+  void arm_lms_init_q15(
+  arm_lms_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  q15_t mu,
+  uint32_t blockSize,
+  uint32_t postShift);
+
+  /**
+   * @brief Processing function for Q15 LMS filter.
+   * @param[in] *S points to an instance of the Q15 LMS filter structure.
+   * @param[in] *pSrc points to the block of input data.
+   * @param[in] *pRef points to the block of reference data.
+   * @param[out] *pOut points to the block of output data.
+   * @param[out] *pErr points to the block of error data.
+   * @param[in] blockSize number of samples to process.
+   * @return none.
+   */
+
+  void arm_lms_q15(
+  const arm_lms_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pRef,
+  q15_t * pOut,
+  q15_t * pErr,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q31 LMS filter.
+   */
+
+  typedef struct
+  {
+    uint16_t numTaps;    /**< number of coefficients in the filter. */
+    q31_t *pState;       /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q31_t *pCoeffs;      /**< points to the coefficient array. The array is of length numTaps. */
+    q31_t mu;            /**< step size that controls filter coefficient updates. */
+    uint32_t postShift;  /**< bit shift applied to coefficients. */
+
+  } arm_lms_instance_q31;
+
+  /**
+   * @brief Processing function for Q31 LMS filter.
+   * @param[in]  *S points to an instance of the Q15 LMS filter structure.
+   * @param[in]  *pSrc points to the block of input data.
+   * @param[in]  *pRef points to the block of reference data.
+   * @param[out] *pOut points to the block of output data.
+   * @param[out] *pErr points to the block of error data.
+   * @param[in]  blockSize number of samples to process.
+   * @return     none.
+   */
+
+  void arm_lms_q31(
+  const arm_lms_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pRef,
+  q31_t * pOut,
+  q31_t * pErr,
+  uint32_t blockSize);
+
+  /**
+   * @brief Initialization function for Q31 LMS filter.
+   * @param[in] *S points to an instance of the Q31 LMS filter structure.
+   * @param[in] numTaps  number of filter coefficients.
+   * @param[in] *pCoeffs points to coefficient buffer.
+   * @param[in] *pState points to state buffer.
+   * @param[in] mu step size that controls filter coefficient updates.
+   * @param[in] blockSize number of samples to process.
+   * @param[in] postShift bit shift applied to coefficients.
+   * @return none.
+   */
+
+  void arm_lms_init_q31(
+  arm_lms_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  q31_t mu,
+  uint32_t blockSize,
+  uint32_t postShift);
+
+  /**
+   * @brief Instance structure for the floating-point normalized LMS filter.
+   */
+
+  typedef struct
+  {
+    uint16_t numTaps;     /**< number of coefficients in the filter. */
+    float32_t *pState;    /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    float32_t *pCoeffs;   /**< points to the coefficient array. The array is of length numTaps. */
+    float32_t mu;        /**< step size that control filter coefficient updates. */
+    float32_t energy;    /**< saves previous frame energy. */
+    float32_t x0;        /**< saves previous input sample. */
+  } arm_lms_norm_instance_f32;
+
+  /**
+   * @brief Processing function for floating-point normalized LMS filter.
+   * @param[in] *S points to an instance of the floating-point normalized LMS filter structure.
+   * @param[in] *pSrc points to the block of input data.
+   * @param[in] *pRef points to the block of reference data.
+   * @param[out] *pOut points to the block of output data.
+   * @param[out] *pErr points to the block of error data.
+   * @param[in] blockSize number of samples to process.
+   * @return none.
+   */
+
+  void arm_lms_norm_f32(
+  arm_lms_norm_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pRef,
+  float32_t * pOut,
+  float32_t * pErr,
+  uint32_t blockSize);
+
+  /**
+   * @brief Initialization function for floating-point normalized LMS filter.
+   * @param[in] *S points to an instance of the floating-point LMS filter structure.
+   * @param[in] numTaps  number of filter coefficients.
+   * @param[in] *pCoeffs points to coefficient buffer.
+   * @param[in] *pState points to state buffer.
+   * @param[in] mu step size that controls filter coefficient updates.
+   * @param[in] blockSize number of samples to process.
+   * @return none.
+   */
+
+  void arm_lms_norm_init_f32(
+  arm_lms_norm_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  float32_t mu,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Instance structure for the Q31 normalized LMS filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;     /**< number of coefficients in the filter. */
+    q31_t *pState;        /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q31_t *pCoeffs;       /**< points to the coefficient array. The array is of length numTaps. */
+    q31_t mu;             /**< step size that controls filter coefficient updates. */
+    uint8_t postShift;    /**< bit shift applied to coefficients. */
+    q31_t *recipTable;    /**< points to the reciprocal initial value table. */
+    q31_t energy;         /**< saves previous frame energy. */
+    q31_t x0;             /**< saves previous input sample. */
+  } arm_lms_norm_instance_q31;
+
+  /**
+   * @brief Processing function for Q31 normalized LMS filter.
+   * @param[in] *S points to an instance of the Q31 normalized LMS filter structure.
+   * @param[in] *pSrc points to the block of input data.
+   * @param[in] *pRef points to the block of reference data.
+   * @param[out] *pOut points to the block of output data.
+   * @param[out] *pErr points to the block of error data.
+   * @param[in] blockSize number of samples to process.
+   * @return none.
+   */
+
+  void arm_lms_norm_q31(
+  arm_lms_norm_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pRef,
+  q31_t * pOut,
+  q31_t * pErr,
+  uint32_t blockSize);
+
+  /**
+   * @brief Initialization function for Q31 normalized LMS filter.
+   * @param[in] *S points to an instance of the Q31 normalized LMS filter structure.
+   * @param[in] numTaps  number of filter coefficients.
+   * @param[in] *pCoeffs points to coefficient buffer.
+   * @param[in] *pState points to state buffer.
+   * @param[in] mu step size that controls filter coefficient updates.
+   * @param[in] blockSize number of samples to process.
+   * @param[in] postShift bit shift applied to coefficients.
+   * @return none.
+   */
+
+  void arm_lms_norm_init_q31(
+  arm_lms_norm_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  q31_t mu,
+  uint32_t blockSize,
+  uint8_t postShift);
+
+  /**
+   * @brief Instance structure for the Q15 normalized LMS filter.
+   */
+
+  typedef struct
+  {
+    uint16_t numTaps;    /**< Number of coefficients in the filter. */
+    q15_t *pState;        /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+    q15_t *pCoeffs;       /**< points to the coefficient array. The array is of length numTaps. */
+    q15_t mu;            /**< step size that controls filter coefficient updates. */
+    uint8_t postShift;   /**< bit shift applied to coefficients. */
+    q15_t *recipTable;   /**< Points to the reciprocal initial value table. */
+    q15_t energy;        /**< saves previous frame energy. */
+    q15_t x0;            /**< saves previous input sample. */
+  } arm_lms_norm_instance_q15;
+
+  /**
+   * @brief Processing function for Q15 normalized LMS filter.
+   * @param[in] *S points to an instance of the Q15 normalized LMS filter structure.
+   * @param[in] *pSrc points to the block of input data.
+   * @param[in] *pRef points to the block of reference data.
+   * @param[out] *pOut points to the block of output data.
+   * @param[out] *pErr points to the block of error data.
+   * @param[in] blockSize number of samples to process.
+   * @return none.
+   */
+
+  void arm_lms_norm_q15(
+  arm_lms_norm_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pRef,
+  q15_t * pOut,
+  q15_t * pErr,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief Initialization function for Q15 normalized LMS filter.
+   * @param[in] *S points to an instance of the Q15 normalized LMS filter structure.
+   * @param[in] numTaps  number of filter coefficients.
+   * @param[in] *pCoeffs points to coefficient buffer.
+   * @param[in] *pState points to state buffer.
+   * @param[in] mu step size that controls filter coefficient updates.
+   * @param[in] blockSize number of samples to process.
+   * @param[in] postShift bit shift applied to coefficients.
+   * @return none.
+   */
+
+  void arm_lms_norm_init_q15(
+  arm_lms_norm_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  q15_t mu,
+  uint32_t blockSize,
+  uint8_t postShift);
+
+  /**
+   * @brief Correlation of floating-point sequences.
+   * @param[in] *pSrcA points to the first input sequence.
+   * @param[in] srcALen length of the first input sequence.
+   * @param[in] *pSrcB points to the second input sequence.
+   * @param[in] srcBLen length of the second input sequence.
+   * @param[out] *pDst points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   * @return none.
+   */
+
+  void arm_correlate_f32(
+  float32_t * pSrcA,
+  uint32_t srcALen,
+  float32_t * pSrcB,
+  uint32_t srcBLen,
+  float32_t * pDst);
+
+
+   /**
+   * @brief Correlation of Q15 sequences
+   * @param[in] *pSrcA points to the first input sequence.
+   * @param[in] srcALen length of the first input sequence.
+   * @param[in] *pSrcB points to the second input sequence.
+   * @param[in] srcBLen length of the second input sequence.
+   * @param[out] *pDst points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   * @param[in]  *pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @return none.
+   */
+  void arm_correlate_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch);
+
+
+  /**
+   * @brief Correlation of Q15 sequences.
+   * @param[in] *pSrcA points to the first input sequence.
+   * @param[in] srcALen length of the first input sequence.
+   * @param[in] *pSrcB points to the second input sequence.
+   * @param[in] srcBLen length of the second input sequence.
+   * @param[out] *pDst points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   * @return none.
+   */
+
+  void arm_correlate_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst);
+
+  /**
+   * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4.
+   * @param[in] *pSrcA points to the first input sequence.
+   * @param[in] srcALen length of the first input sequence.
+   * @param[in] *pSrcB points to the second input sequence.
+   * @param[in] srcBLen length of the second input sequence.
+   * @param[out] *pDst points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   * @return none.
+   */
+
+  void arm_correlate_fast_q15(
+			       q15_t * pSrcA,
+			      uint32_t srcALen,
+			       q15_t * pSrcB,
+			      uint32_t srcBLen,
+			      q15_t * pDst);
+
+
+
+  /**
+   * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4.
+   * @param[in] *pSrcA points to the first input sequence.
+   * @param[in] srcALen length of the first input sequence.
+   * @param[in] *pSrcB points to the second input sequence.
+   * @param[in] srcBLen length of the second input sequence.
+   * @param[out] *pDst points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   * @param[in]  *pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @return none.
+   */
+
+  void arm_correlate_fast_opt_q15(
+  q15_t * pSrcA,
+  uint32_t srcALen,
+  q15_t * pSrcB,
+  uint32_t srcBLen,
+  q15_t * pDst,
+  q15_t * pScratch);
+
+  /**
+   * @brief Correlation of Q31 sequences.
+   * @param[in] *pSrcA points to the first input sequence.
+   * @param[in] srcALen length of the first input sequence.
+   * @param[in] *pSrcB points to the second input sequence.
+   * @param[in] srcBLen length of the second input sequence.
+   * @param[out] *pDst points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   * @return none.
+   */
+
+  void arm_correlate_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+  /**
+   * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+   * @param[in] *pSrcA points to the first input sequence.
+   * @param[in] srcALen length of the first input sequence.
+   * @param[in] *pSrcB points to the second input sequence.
+   * @param[in] srcBLen length of the second input sequence.
+   * @param[out] *pDst points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   * @return none.
+   */
+
+  void arm_correlate_fast_q31(
+  q31_t * pSrcA,
+  uint32_t srcALen,
+  q31_t * pSrcB,
+  uint32_t srcBLen,
+  q31_t * pDst);
+
+
+
+ /**
+   * @brief Correlation of Q7 sequences.
+   * @param[in] *pSrcA points to the first input sequence.
+   * @param[in] srcALen length of the first input sequence.
+   * @param[in] *pSrcB points to the second input sequence.
+   * @param[in] srcBLen length of the second input sequence.
+   * @param[out] *pDst points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   * @param[in]  *pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+   * @param[in]  *pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen).
+   * @return none.
+   */
+
+  void arm_correlate_opt_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst,
+  q15_t * pScratch1,
+  q15_t * pScratch2);
+
+
+  /**
+   * @brief Correlation of Q7 sequences.
+   * @param[in] *pSrcA points to the first input sequence.
+   * @param[in] srcALen length of the first input sequence.
+   * @param[in] *pSrcB points to the second input sequence.
+   * @param[in] srcBLen length of the second input sequence.
+   * @param[out] *pDst points to the block of output data  Length 2 * max(srcALen, srcBLen) - 1.
+   * @return none.
+   */
+
+  void arm_correlate_q7(
+  q7_t * pSrcA,
+  uint32_t srcALen,
+  q7_t * pSrcB,
+  uint32_t srcBLen,
+  q7_t * pDst);
+
+
+  /**
+   * @brief Instance structure for the floating-point sparse FIR filter.
+   */
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    float32_t *pState;            /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    float32_t *pCoeffs;           /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } arm_fir_sparse_instance_f32;
+
+  /**
+   * @brief Instance structure for the Q31 sparse FIR filter.
+   */
+
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    q31_t *pState;                /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    q31_t *pCoeffs;               /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } arm_fir_sparse_instance_q31;
+
+  /**
+   * @brief Instance structure for the Q15 sparse FIR filter.
+   */
+
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    q15_t *pState;                /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    q15_t *pCoeffs;               /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } arm_fir_sparse_instance_q15;
+
+  /**
+   * @brief Instance structure for the Q7 sparse FIR filter.
+   */
+
+  typedef struct
+  {
+    uint16_t numTaps;             /**< number of coefficients in the filter. */
+    uint16_t stateIndex;          /**< state buffer index.  Points to the oldest sample in the state buffer. */
+    q7_t *pState;                 /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+    q7_t *pCoeffs;                /**< points to the coefficient array. The array is of length numTaps.*/
+    uint16_t maxDelay;            /**< maximum offset specified by the pTapDelay array. */
+    int32_t *pTapDelay;           /**< points to the array of delay values.  The array is of length numTaps. */
+  } arm_fir_sparse_instance_q7;
+
+  /**
+   * @brief Processing function for the floating-point sparse FIR filter.
+   * @param[in]  *S          points to an instance of the floating-point sparse FIR structure.
+   * @param[in]  *pSrc       points to the block of input data.
+   * @param[out] *pDst       points to the block of output data
+   * @param[in]  *pScratchIn points to a temporary buffer of size blockSize.
+   * @param[in]  blockSize   number of input samples to process per call.
+   * @return none.
+   */
+
+  void arm_fir_sparse_f32(
+  arm_fir_sparse_instance_f32 * S,
+  float32_t * pSrc,
+  float32_t * pDst,
+  float32_t * pScratchIn,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Initialization function for the floating-point sparse FIR filter.
+   * @param[in,out] *S         points to an instance of the floating-point sparse FIR structure.
+   * @param[in]     numTaps    number of nonzero coefficients in the filter.
+   * @param[in]     *pCoeffs   points to the array of filter coefficients.
+   * @param[in]     *pState    points to the state buffer.
+   * @param[in]     *pTapDelay points to the array of offset times.
+   * @param[in]     maxDelay   maximum offset time supported.
+   * @param[in]     blockSize  number of samples that will be processed per block.
+   * @return none
+   */
+
+  void arm_fir_sparse_init_f32(
+  arm_fir_sparse_instance_f32 * S,
+  uint16_t numTaps,
+  float32_t * pCoeffs,
+  float32_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+  /**
+   * @brief Processing function for the Q31 sparse FIR filter.
+   * @param[in]  *S          points to an instance of the Q31 sparse FIR structure.
+   * @param[in]  *pSrc       points to the block of input data.
+   * @param[out] *pDst       points to the block of output data
+   * @param[in]  *pScratchIn points to a temporary buffer of size blockSize.
+   * @param[in]  blockSize   number of input samples to process per call.
+   * @return none.
+   */
+
+  void arm_fir_sparse_q31(
+  arm_fir_sparse_instance_q31 * S,
+  q31_t * pSrc,
+  q31_t * pDst,
+  q31_t * pScratchIn,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Initialization function for the Q31 sparse FIR filter.
+   * @param[in,out] *S         points to an instance of the Q31 sparse FIR structure.
+   * @param[in]     numTaps    number of nonzero coefficients in the filter.
+   * @param[in]     *pCoeffs   points to the array of filter coefficients.
+   * @param[in]     *pState    points to the state buffer.
+   * @param[in]     *pTapDelay points to the array of offset times.
+   * @param[in]     maxDelay   maximum offset time supported.
+   * @param[in]     blockSize  number of samples that will be processed per block.
+   * @return none
+   */
+
+  void arm_fir_sparse_init_q31(
+  arm_fir_sparse_instance_q31 * S,
+  uint16_t numTaps,
+  q31_t * pCoeffs,
+  q31_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+  /**
+   * @brief Processing function for the Q15 sparse FIR filter.
+   * @param[in]  *S           points to an instance of the Q15 sparse FIR structure.
+   * @param[in]  *pSrc        points to the block of input data.
+   * @param[out] *pDst        points to the block of output data
+   * @param[in]  *pScratchIn  points to a temporary buffer of size blockSize.
+   * @param[in]  *pScratchOut points to a temporary buffer of size blockSize.
+   * @param[in]  blockSize    number of input samples to process per call.
+   * @return none.
+   */
+
+  void arm_fir_sparse_q15(
+  arm_fir_sparse_instance_q15 * S,
+  q15_t * pSrc,
+  q15_t * pDst,
+  q15_t * pScratchIn,
+  q31_t * pScratchOut,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Initialization function for the Q15 sparse FIR filter.
+   * @param[in,out] *S         points to an instance of the Q15 sparse FIR structure.
+   * @param[in]     numTaps    number of nonzero coefficients in the filter.
+   * @param[in]     *pCoeffs   points to the array of filter coefficients.
+   * @param[in]     *pState    points to the state buffer.
+   * @param[in]     *pTapDelay points to the array of offset times.
+   * @param[in]     maxDelay   maximum offset time supported.
+   * @param[in]     blockSize  number of samples that will be processed per block.
+   * @return none
+   */
+
+  void arm_fir_sparse_init_q15(
+  arm_fir_sparse_instance_q15 * S,
+  uint16_t numTaps,
+  q15_t * pCoeffs,
+  q15_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+  /**
+   * @brief Processing function for the Q7 sparse FIR filter.
+   * @param[in]  *S           points to an instance of the Q7 sparse FIR structure.
+   * @param[in]  *pSrc        points to the block of input data.
+   * @param[out] *pDst        points to the block of output data
+   * @param[in]  *pScratchIn  points to a temporary buffer of size blockSize.
+   * @param[in]  *pScratchOut points to a temporary buffer of size blockSize.
+   * @param[in]  blockSize    number of input samples to process per call.
+   * @return none.
+   */
+
+  void arm_fir_sparse_q7(
+  arm_fir_sparse_instance_q7 * S,
+  q7_t * pSrc,
+  q7_t * pDst,
+  q7_t * pScratchIn,
+  q31_t * pScratchOut,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Initialization function for the Q7 sparse FIR filter.
+   * @param[in,out] *S         points to an instance of the Q7 sparse FIR structure.
+   * @param[in]     numTaps    number of nonzero coefficients in the filter.
+   * @param[in]     *pCoeffs   points to the array of filter coefficients.
+   * @param[in]     *pState    points to the state buffer.
+   * @param[in]     *pTapDelay points to the array of offset times.
+   * @param[in]     maxDelay   maximum offset time supported.
+   * @param[in]     blockSize  number of samples that will be processed per block.
+   * @return none
+   */
+
+  void arm_fir_sparse_init_q7(
+  arm_fir_sparse_instance_q7 * S,
+  uint16_t numTaps,
+  q7_t * pCoeffs,
+  q7_t * pState,
+  int32_t * pTapDelay,
+  uint16_t maxDelay,
+  uint32_t blockSize);
+
+
+  /*
+   * @brief  Floating-point sin_cos function.
+   * @param[in]  theta    input value in degrees
+   * @param[out] *pSinVal points to the processed sine output.
+   * @param[out] *pCosVal points to the processed cos output.
+   * @return none.
+   */
+
+  void arm_sin_cos_f32(
+  float32_t theta,
+  float32_t * pSinVal,
+  float32_t * pCcosVal);
+
+  /*
+   * @brief  Q31 sin_cos function.
+   * @param[in]  theta    scaled input value in degrees
+   * @param[out] *pSinVal points to the processed sine output.
+   * @param[out] *pCosVal points to the processed cosine output.
+   * @return none.
+   */
+
+  void arm_sin_cos_q31(
+  q31_t theta,
+  q31_t * pSinVal,
+  q31_t * pCosVal);
+
+
+  /**
+   * @brief  Floating-point complex conjugate.
+   * @param[in]  *pSrc points to the input vector
+   * @param[out]  *pDst points to the output vector
+   * @param[in]  numSamples number of complex samples in each vector
+   * @return none.
+   */
+
+  void arm_cmplx_conj_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+  /**
+   * @brief  Q31 complex conjugate.
+   * @param[in]  *pSrc points to the input vector
+   * @param[out]  *pDst points to the output vector
+   * @param[in]  numSamples number of complex samples in each vector
+   * @return none.
+   */
+
+  void arm_cmplx_conj_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+  /**
+   * @brief  Q15 complex conjugate.
+   * @param[in]  *pSrc points to the input vector
+   * @param[out]  *pDst points to the output vector
+   * @param[in]  numSamples number of complex samples in each vector
+   * @return none.
+   */
+
+  void arm_cmplx_conj_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+
+
+  /**
+   * @brief  Floating-point complex magnitude squared
+   * @param[in]  *pSrc points to the complex input vector
+   * @param[out]  *pDst points to the real output vector
+   * @param[in]  numSamples number of complex samples in the input vector
+   * @return none.
+   */
+
+  void arm_cmplx_mag_squared_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+  /**
+   * @brief  Q31 complex magnitude squared
+   * @param[in]  *pSrc points to the complex input vector
+   * @param[out]  *pDst points to the real output vector
+   * @param[in]  numSamples number of complex samples in the input vector
+   * @return none.
+   */
+
+  void arm_cmplx_mag_squared_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+  /**
+   * @brief  Q15 complex magnitude squared
+   * @param[in]  *pSrc points to the complex input vector
+   * @param[out]  *pDst points to the real output vector
+   * @param[in]  numSamples number of complex samples in the input vector
+   * @return none.
+   */
+
+  void arm_cmplx_mag_squared_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+
+ /**
+   * @ingroup groupController
+   */
+
+  /**
+   * @defgroup PID PID Motor Control
+   *
+   * A Proportional Integral Derivative (PID) controller is a generic feedback control
+   * loop mechanism widely used in industrial control systems.
+   * A PID controller is the most commonly used type of feedback controller.
+   *
+   * This set of functions implements (PID) controllers
+   * for Q15, Q31, and floating-point data types.  The functions operate on a single sample
+   * of data and each call to the function returns a single processed value.
+   * <code>S</code> points to an instance of the PID control data structure.  <code>in</code>
+   * is the input sample value. The functions return the output value.
+   *
+   * \par Algorithm:
+   * <pre>
+   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+   *    A0 = Kp + Ki + Kd
+   *    A1 = (-Kp ) - (2 * Kd )
+   *    A2 = Kd  </pre>
+   *
+   * \par
+   * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant
+   *
+   * \par
+   * \image html PID.gif "Proportional Integral Derivative Controller"
+   *
+   * \par
+   * The PID controller calculates an "error" value as the difference between
+   * the measured output and the reference input.
+   * The controller attempts to minimize the error by adjusting the process control inputs.
+   * The proportional value determines the reaction to the current error,
+   * the integral value determines the reaction based on the sum of recent errors,
+   * and the derivative value determines the reaction based on the rate at which the error has been changing.
+   *
+   * \par Instance Structure
+   * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure.
+   * A separate instance structure must be defined for each PID Controller.
+   * There are separate instance structure declarations for each of the 3 supported data types.
+   *
+   * \par Reset Functions
+   * There is also an associated reset function for each data type which clears the state array.
+   *
+   * \par Initialization Functions
+   * There is also an associated initialization function for each data type.
+   * The initialization function performs the following operations:
+   * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains.
+   * - Zeros out the values in the state buffer.
+   *
+   * \par
+   * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function.
+   *
+   * \par Fixed-Point Behavior
+   * Care must be taken when using the fixed-point versions of the PID Controller functions.
+   * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered.
+   * Refer to the function specific documentation below for usage guidelines.
+   */
+
+  /**
+   * @addtogroup PID
+   * @{
+   */
+
+  /**
+   * @brief  Process function for the floating-point PID Control.
+   * @param[in,out] *S is an instance of the floating-point PID Control structure
+   * @param[in] in input sample to process
+   * @return out processed output sample.
+   */
+
+
+  static __INLINE float32_t arm_pid_f32(
+  arm_pid_instance_f32 * S,
+  float32_t in)
+  {
+    float32_t out;
+
+    /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]  */
+    out = (S->A0 * in) +
+      (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]);
+
+    /* Update state */
+    S->state[1] = S->state[0];
+    S->state[0] = in;
+    S->state[2] = out;
+
+    /* return to application */
+    return (out);
+
+  }
+
+  /**
+   * @brief  Process function for the Q31 PID Control.
+   * @param[in,out] *S points to an instance of the Q31 PID Control structure
+   * @param[in] in input sample to process
+   * @return out processed output sample.
+   *
+   * <b>Scaling and Overflow Behavior:</b>
+   * \par
+   * The function is implemented using an internal 64-bit accumulator.
+   * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit.
+   * Thus, if the accumulator result overflows it wraps around rather than clip.
+   * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions.
+   * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format.
+   */
+
+  static __INLINE q31_t arm_pid_q31(
+  arm_pid_instance_q31 * S,
+  q31_t in)
+  {
+    q63_t acc;
+    q31_t out;
+
+    /* acc = A0 * x[n]  */
+    acc = (q63_t) S->A0 * in;
+
+    /* acc += A1 * x[n-1] */
+    acc += (q63_t) S->A1 * S->state[0];
+
+    /* acc += A2 * x[n-2]  */
+    acc += (q63_t) S->A2 * S->state[1];
+
+    /* convert output to 1.31 format to add y[n-1] */
+    out = (q31_t) (acc >> 31u);
+
+    /* out += y[n-1] */
+    out += S->state[2];
+
+    /* Update state */
+    S->state[1] = S->state[0];
+    S->state[0] = in;
+    S->state[2] = out;
+
+    /* return to application */
+    return (out);
+
+  }
+
+  /**
+   * @brief  Process function for the Q15 PID Control.
+   * @param[in,out] *S points to an instance of the Q15 PID Control structure
+   * @param[in] in input sample to process
+   * @return out processed output sample.
+   *
+   * <b>Scaling and Overflow Behavior:</b>
+   * \par
+   * The function is implemented using a 64-bit internal accumulator.
+   * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result.
+   * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format.
+   * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved.
+   * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits.
+   * Lastly, the accumulator is saturated to yield a result in 1.15 format.
+   */
+
+  static __INLINE q15_t arm_pid_q15(
+  arm_pid_instance_q15 * S,
+  q15_t in)
+  {
+    q63_t acc;
+    q15_t out;
+
+#ifndef ARM_MATH_CM0_FAMILY
+    __SIMD32_TYPE *vstate;
+
+    /* Implementation of PID controller */
+
+    /* acc = A0 * x[n]  */
+    acc = (q31_t) __SMUAD(S->A0, in);
+
+    /* acc += A1 * x[n-1] + A2 * x[n-2]  */
+    vstate = __SIMD32_CONST(S->state);
+    acc = __SMLALD(S->A1, (q31_t) *vstate, acc);
+
+#else
+    /* acc = A0 * x[n]  */
+    acc = ((q31_t) S->A0) * in;
+
+    /* acc += A1 * x[n-1] + A2 * x[n-2]  */
+    acc += (q31_t) S->A1 * S->state[0];
+    acc += (q31_t) S->A2 * S->state[1];
+
+#endif
+
+    /* acc += y[n-1] */
+    acc += (q31_t) S->state[2] << 15;
+
+    /* saturate the output */
+    out = (q15_t) (__SSAT((acc >> 15), 16));
+
+    /* Update state */
+    S->state[1] = S->state[0];
+    S->state[0] = in;
+    S->state[2] = out;
+
+    /* return to application */
+    return (out);
+
+  }
+
+  /**
+   * @} end of PID group
+   */
+
+
+  /**
+   * @brief Floating-point matrix inverse.
+   * @param[in]  *src points to the instance of the input floating-point matrix structure.
+   * @param[out] *dst points to the instance of the output floating-point matrix structure.
+   * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match.
+   * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR.
+   */
+
+  arm_status arm_mat_inverse_f32(
+  const arm_matrix_instance_f32 * src,
+  arm_matrix_instance_f32 * dst);
+
+
+
+  /**
+   * @ingroup groupController
+   */
+
+
+  /**
+   * @defgroup clarke Vector Clarke Transform
+   * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector.
+   * Generally the Clarke transform uses three-phase currents <code>Ia, Ib and Ic</code> to calculate currents
+   * in the two-phase orthogonal stator axis <code>Ialpha</code> and <code>Ibeta</code>.
+   * When <code>Ialpha</code> is superposed with <code>Ia</code> as shown in the figure below
+   * \image html clarke.gif Stator current space vector and its components in (a,b).
+   * and <code>Ia + Ib + Ic = 0</code>, in this condition <code>Ialpha</code> and <code>Ibeta</code>
+   * can be calculated using only <code>Ia</code> and <code>Ib</code>.
+   *
+   * The function operates on a single sample of data and each call to the function returns the processed output.
+   * The library provides separate functions for Q31 and floating-point data types.
+   * \par Algorithm
+   * \image html clarkeFormula.gif
+   * where <code>Ia</code> and <code>Ib</code> are the instantaneous stator phases and
+   * <code>pIalpha</code> and <code>pIbeta</code> are the two coordinates of time invariant vector.
+   * \par Fixed-Point Behavior
+   * Care must be taken when using the Q31 version of the Clarke transform.
+   * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+   * Refer to the function specific documentation below for usage guidelines.
+   */
+
+  /**
+   * @addtogroup clarke
+   * @{
+   */
+
+  /**
+   *
+   * @brief  Floating-point Clarke transform
+   * @param[in]       Ia       input three-phase coordinate <code>a</code>
+   * @param[in]       Ib       input three-phase coordinate <code>b</code>
+   * @param[out]      *pIalpha points to output two-phase orthogonal vector axis alpha
+   * @param[out]      *pIbeta  points to output two-phase orthogonal vector axis beta
+   * @return none.
+   */
+
+  static __INLINE void arm_clarke_f32(
+  float32_t Ia,
+  float32_t Ib,
+  float32_t * pIalpha,
+  float32_t * pIbeta)
+  {
+    /* Calculate pIalpha using the equation, pIalpha = Ia */
+    *pIalpha = Ia;
+
+    /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */
+    *pIbeta =
+      ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib);
+
+  }
+
+  /**
+   * @brief  Clarke transform for Q31 version
+   * @param[in]       Ia       input three-phase coordinate <code>a</code>
+   * @param[in]       Ib       input three-phase coordinate <code>b</code>
+   * @param[out]      *pIalpha points to output two-phase orthogonal vector axis alpha
+   * @param[out]      *pIbeta  points to output two-phase orthogonal vector axis beta
+   * @return none.
+   *
+   * <b>Scaling and Overflow Behavior:</b>
+   * \par
+   * The function is implemented using an internal 32-bit accumulator.
+   * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+   * There is saturation on the addition, hence there is no risk of overflow.
+   */
+
+  static __INLINE void arm_clarke_q31(
+  q31_t Ia,
+  q31_t Ib,
+  q31_t * pIalpha,
+  q31_t * pIbeta)
+  {
+    q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
+
+    /* Calculating pIalpha from Ia by equation pIalpha = Ia */
+    *pIalpha = Ia;
+
+    /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */
+    product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30);
+
+    /* Intermediate product is calculated by (2/sqrt(3) * Ib) */
+    product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30);
+
+    /* pIbeta is calculated by adding the intermediate products */
+    *pIbeta = __QADD(product1, product2);
+  }
+
+  /**
+   * @} end of clarke group
+   */
+
+  /**
+   * @brief  Converts the elements of the Q7 vector to Q31 vector.
+   * @param[in]  *pSrc     input pointer
+   * @param[out]  *pDst    output pointer
+   * @param[in]  blockSize number of samples to process
+   * @return none.
+   */
+  void arm_q7_to_q31(
+  q7_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+
+
+  /**
+   * @ingroup groupController
+   */
+
+  /**
+   * @defgroup inv_clarke Vector Inverse Clarke Transform
+   * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases.
+   *
+   * The function operates on a single sample of data and each call to the function returns the processed output.
+   * The library provides separate functions for Q31 and floating-point data types.
+   * \par Algorithm
+   * \image html clarkeInvFormula.gif
+   * where <code>pIa</code> and <code>pIb</code> are the instantaneous stator phases and
+   * <code>Ialpha</code> and <code>Ibeta</code> are the two coordinates of time invariant vector.
+   * \par Fixed-Point Behavior
+   * Care must be taken when using the Q31 version of the Clarke transform.
+   * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+   * Refer to the function specific documentation below for usage guidelines.
+   */
+
+  /**
+   * @addtogroup inv_clarke
+   * @{
+   */
+
+   /**
+   * @brief  Floating-point Inverse Clarke transform
+   * @param[in]       Ialpha  input two-phase orthogonal vector axis alpha
+   * @param[in]       Ibeta   input two-phase orthogonal vector axis beta
+   * @param[out]      *pIa    points to output three-phase coordinate <code>a</code>
+   * @param[out]      *pIb    points to output three-phase coordinate <code>b</code>
+   * @return none.
+   */
+
+
+  static __INLINE void arm_inv_clarke_f32(
+  float32_t Ialpha,
+  float32_t Ibeta,
+  float32_t * pIa,
+  float32_t * pIb)
+  {
+    /* Calculating pIa from Ialpha by equation pIa = Ialpha */
+    *pIa = Ialpha;
+
+    /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */
+    *pIb = -0.5 * Ialpha + (float32_t) 0.8660254039 *Ibeta;
+
+  }
+
+  /**
+   * @brief  Inverse Clarke transform for Q31 version
+   * @param[in]       Ialpha  input two-phase orthogonal vector axis alpha
+   * @param[in]       Ibeta   input two-phase orthogonal vector axis beta
+   * @param[out]      *pIa    points to output three-phase coordinate <code>a</code>
+   * @param[out]      *pIb    points to output three-phase coordinate <code>b</code>
+   * @return none.
+   *
+   * <b>Scaling and Overflow Behavior:</b>
+   * \par
+   * The function is implemented using an internal 32-bit accumulator.
+   * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+   * There is saturation on the subtraction, hence there is no risk of overflow.
+   */
+
+  static __INLINE void arm_inv_clarke_q31(
+  q31_t Ialpha,
+  q31_t Ibeta,
+  q31_t * pIa,
+  q31_t * pIb)
+  {
+    q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
+
+    /* Calculating pIa from Ialpha by equation pIa = Ialpha */
+    *pIa = Ialpha;
+
+    /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */
+    product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31);
+
+    /* Intermediate product is calculated by (1/sqrt(3) * pIb) */
+    product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31);
+
+    /* pIb is calculated by subtracting the products */
+    *pIb = __QSUB(product2, product1);
+
+  }
+
+  /**
+   * @} end of inv_clarke group
+   */
+
+  /**
+   * @brief  Converts the elements of the Q7 vector to Q15 vector.
+   * @param[in]  *pSrc     input pointer
+   * @param[out] *pDst     output pointer
+   * @param[in]  blockSize number of samples to process
+   * @return none.
+   */
+  void arm_q7_to_q15(
+  q7_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+
+
+  /**
+   * @ingroup groupController
+   */
+
+  /**
+   * @defgroup park Vector Park Transform
+   *
+   * Forward Park transform converts the input two-coordinate vector to flux and torque components.
+   * The Park transform can be used to realize the transformation of the <code>Ialpha</code> and the <code>Ibeta</code> currents
+   * from the stationary to the moving reference frame and control the spatial relationship between
+   * the stator vector current and rotor flux vector.
+   * If we consider the d axis aligned with the rotor flux, the diagram below shows the
+   * current vector and the relationship from the two reference frames:
+   * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame"
+   *
+   * The function operates on a single sample of data and each call to the function returns the processed output.
+   * The library provides separate functions for Q31 and floating-point data types.
+   * \par Algorithm
+   * \image html parkFormula.gif
+   * where <code>Ialpha</code> and <code>Ibeta</code> are the stator vector components,
+   * <code>pId</code> and <code>pIq</code> are rotor vector components and <code>cosVal</code> and <code>sinVal</code> are the
+   * cosine and sine values of theta (rotor flux position).
+   * \par Fixed-Point Behavior
+   * Care must be taken when using the Q31 version of the Park transform.
+   * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+   * Refer to the function specific documentation below for usage guidelines.
+   */
+
+  /**
+   * @addtogroup park
+   * @{
+   */
+
+  /**
+   * @brief Floating-point Park transform
+   * @param[in]       Ialpha input two-phase vector coordinate alpha
+   * @param[in]       Ibeta  input two-phase vector coordinate beta
+   * @param[out]      *pId   points to output	rotor reference frame d
+   * @param[out]      *pIq   points to output	rotor reference frame q
+   * @param[in]       sinVal sine value of rotation angle theta
+   * @param[in]       cosVal cosine value of rotation angle theta
+   * @return none.
+   *
+   * The function implements the forward Park transform.
+   *
+   */
+
+  static __INLINE void arm_park_f32(
+  float32_t Ialpha,
+  float32_t Ibeta,
+  float32_t * pId,
+  float32_t * pIq,
+  float32_t sinVal,
+  float32_t cosVal)
+  {
+    /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */
+    *pId = Ialpha * cosVal + Ibeta * sinVal;
+
+    /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */
+    *pIq = -Ialpha * sinVal + Ibeta * cosVal;
+
+  }
+
+  /**
+   * @brief  Park transform for Q31 version
+   * @param[in]       Ialpha input two-phase vector coordinate alpha
+   * @param[in]       Ibeta  input two-phase vector coordinate beta
+   * @param[out]      *pId   points to output rotor reference frame d
+   * @param[out]      *pIq   points to output rotor reference frame q
+   * @param[in]       sinVal sine value of rotation angle theta
+   * @param[in]       cosVal cosine value of rotation angle theta
+   * @return none.
+   *
+   * <b>Scaling and Overflow Behavior:</b>
+   * \par
+   * The function is implemented using an internal 32-bit accumulator.
+   * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+   * There is saturation on the addition and subtraction, hence there is no risk of overflow.
+   */
+
+
+  static __INLINE void arm_park_q31(
+  q31_t Ialpha,
+  q31_t Ibeta,
+  q31_t * pId,
+  q31_t * pIq,
+  q31_t sinVal,
+  q31_t cosVal)
+  {
+    q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
+    q31_t product3, product4;                    /* Temporary variables used to store intermediate results */
+
+    /* Intermediate product is calculated by (Ialpha * cosVal) */
+    product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31);
+
+    /* Intermediate product is calculated by (Ibeta * sinVal) */
+    product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31);
+
+
+    /* Intermediate product is calculated by (Ialpha * sinVal) */
+    product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31);
+
+    /* Intermediate product is calculated by (Ibeta * cosVal) */
+    product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31);
+
+    /* Calculate pId by adding the two intermediate products 1 and 2 */
+    *pId = __QADD(product1, product2);
+
+    /* Calculate pIq by subtracting the two intermediate products 3 from 4 */
+    *pIq = __QSUB(product4, product3);
+  }
+
+  /**
+   * @} end of park group
+   */
+
+  /**
+   * @brief  Converts the elements of the Q7 vector to floating-point vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[out]  *pDst is output pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @return none.
+   */
+  void arm_q7_to_float(
+  q7_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @ingroup groupController
+   */
+
+  /**
+   * @defgroup inv_park Vector Inverse Park transform
+   * Inverse Park transform converts the input flux and torque components to two-coordinate vector.
+   *
+   * The function operates on a single sample of data and each call to the function returns the processed output.
+   * The library provides separate functions for Q31 and floating-point data types.
+   * \par Algorithm
+   * \image html parkInvFormula.gif
+   * where <code>pIalpha</code> and <code>pIbeta</code> are the stator vector components,
+   * <code>Id</code> and <code>Iq</code> are rotor vector components and <code>cosVal</code> and <code>sinVal</code> are the
+   * cosine and sine values of theta (rotor flux position).
+   * \par Fixed-Point Behavior
+   * Care must be taken when using the Q31 version of the Park transform.
+   * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+   * Refer to the function specific documentation below for usage guidelines.
+   */
+
+  /**
+   * @addtogroup inv_park
+   * @{
+   */
+
+   /**
+   * @brief  Floating-point Inverse Park transform
+   * @param[in]       Id        input coordinate of rotor reference frame d
+   * @param[in]       Iq        input coordinate of rotor reference frame q
+   * @param[out]      *pIalpha  points to output two-phase orthogonal vector axis alpha
+   * @param[out]      *pIbeta   points to output two-phase orthogonal vector axis beta
+   * @param[in]       sinVal    sine value of rotation angle theta
+   * @param[in]       cosVal    cosine value of rotation angle theta
+   * @return none.
+   */
+
+  static __INLINE void arm_inv_park_f32(
+  float32_t Id,
+  float32_t Iq,
+  float32_t * pIalpha,
+  float32_t * pIbeta,
+  float32_t sinVal,
+  float32_t cosVal)
+  {
+    /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */
+    *pIalpha = Id * cosVal - Iq * sinVal;
+
+    /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */
+    *pIbeta = Id * sinVal + Iq * cosVal;
+
+  }
+
+
+  /**
+   * @brief  Inverse Park transform for	Q31 version
+   * @param[in]       Id        input coordinate of rotor reference frame d
+   * @param[in]       Iq        input coordinate of rotor reference frame q
+   * @param[out]      *pIalpha  points to output two-phase orthogonal vector axis alpha
+   * @param[out]      *pIbeta   points to output two-phase orthogonal vector axis beta
+   * @param[in]       sinVal    sine value of rotation angle theta
+   * @param[in]       cosVal    cosine value of rotation angle theta
+   * @return none.
+   *
+   * <b>Scaling and Overflow Behavior:</b>
+   * \par
+   * The function is implemented using an internal 32-bit accumulator.
+   * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+   * There is saturation on the addition, hence there is no risk of overflow.
+   */
+
+
+  static __INLINE void arm_inv_park_q31(
+  q31_t Id,
+  q31_t Iq,
+  q31_t * pIalpha,
+  q31_t * pIbeta,
+  q31_t sinVal,
+  q31_t cosVal)
+  {
+    q31_t product1, product2;                    /* Temporary variables used to store intermediate results */
+    q31_t product3, product4;                    /* Temporary variables used to store intermediate results */
+
+    /* Intermediate product is calculated by (Id * cosVal) */
+    product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31);
+
+    /* Intermediate product is calculated by (Iq * sinVal) */
+    product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31);
+
+
+    /* Intermediate product is calculated by (Id * sinVal) */
+    product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31);
+
+    /* Intermediate product is calculated by (Iq * cosVal) */
+    product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31);
+
+    /* Calculate pIalpha by using the two intermediate products 1 and 2 */
+    *pIalpha = __QSUB(product1, product2);
+
+    /* Calculate pIbeta by using the two intermediate products 3 and 4 */
+    *pIbeta = __QADD(product4, product3);
+
+  }
+
+  /**
+   * @} end of Inverse park group
+   */
+
+
+  /**
+   * @brief  Converts the elements of the Q31 vector to floating-point vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[out]  *pDst is output pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @return none.
+   */
+  void arm_q31_to_float(
+  q31_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @ingroup groupInterpolation
+   */
+
+  /**
+   * @defgroup LinearInterpolate Linear Interpolation
+   *
+   * Linear interpolation is a method of curve fitting using linear polynomials.
+   * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line
+   *
+   * \par
+   * \image html LinearInterp.gif "Linear interpolation"
+   *
+   * \par
+   * A  Linear Interpolate function calculates an output value(y), for the input(x)
+   * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values)
+   *
+   * \par Algorithm:
+   * <pre>
+   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+   *       where x0, x1 are nearest values of input x
+   *             y0, y1 are nearest values to output y
+   * </pre>
+   *
+   * \par
+   * This set of functions implements Linear interpolation process
+   * for Q7, Q15, Q31, and floating-point data types.  The functions operate on a single
+   * sample of data and each call to the function returns a single processed value.
+   * <code>S</code> points to an instance of the Linear Interpolate function data structure.
+   * <code>x</code> is the input sample value. The functions returns the output value.
+   *
+   * \par
+   * if x is outside of the table boundary, Linear interpolation returns first value of the table
+   * if x is below input range and returns last value of table if x is above range.
+   */
+
+  /**
+   * @addtogroup LinearInterpolate
+   * @{
+   */
+
+  /**
+   * @brief  Process function for the floating-point Linear Interpolation Function.
+   * @param[in,out] *S is an instance of the floating-point Linear Interpolation structure
+   * @param[in] x input sample to process
+   * @return y processed output sample.
+   *
+   */
+
+  static __INLINE float32_t arm_linear_interp_f32(
+  arm_linear_interp_instance_f32 * S,
+  float32_t x)
+  {
+
+    float32_t y;
+    float32_t x0, x1;                            /* Nearest input values */
+    float32_t y0, y1;                            /* Nearest output values */
+    float32_t xSpacing = S->xSpacing;            /* spacing between input values */
+    int32_t i;                                   /* Index variable */
+    float32_t *pYData = S->pYData;               /* pointer to output table */
+
+    /* Calculation of index */
+    i = (int32_t) ((x - S->x1) / xSpacing);
+
+    if(i < 0)
+    {
+      /* Iniatilize output for below specified range as least output value of table */
+      y = pYData[0];
+    }
+    else if((uint32_t)i >= S->nValues)
+    {
+      /* Iniatilize output for above specified range as last output value of table */
+      y = pYData[S->nValues - 1];
+    }
+    else
+    {
+      /* Calculation of nearest input values */
+      x0 = S->x1 + i * xSpacing;
+      x1 = S->x1 + (i + 1) * xSpacing;
+
+      /* Read of nearest output values */
+      y0 = pYData[i];
+      y1 = pYData[i + 1];
+
+      /* Calculation of output */
+      y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0));
+
+    }
+
+    /* returns output value */
+    return (y);
+  }
+
+   /**
+   *
+   * @brief  Process function for the Q31 Linear Interpolation Function.
+   * @param[in] *pYData  pointer to Q31 Linear Interpolation table
+   * @param[in] x input sample to process
+   * @param[in] nValues number of table values
+   * @return y processed output sample.
+   *
+   * \par
+   * Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+   * This function can support maximum of table size 2^12.
+   *
+   */
+
+
+  static __INLINE q31_t arm_linear_interp_q31(
+  q31_t * pYData,
+  q31_t x,
+  uint32_t nValues)
+  {
+    q31_t y;                                     /* output */
+    q31_t y0, y1;                                /* Nearest output values */
+    q31_t fract;                                 /* fractional part */
+    int32_t index;                               /* Index to read nearest output values */
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    index = ((x & 0xFFF00000) >> 20);
+
+    if(index >= (int32_t)(nValues - 1))
+    {
+      return (pYData[nValues - 1]);
+    }
+    else if(index < 0)
+    {
+      return (pYData[0]);
+    }
+    else
+    {
+
+      /* 20 bits for the fractional part */
+      /* shift left by 11 to keep fract in 1.31 format */
+      fract = (x & 0x000FFFFF) << 11;
+
+      /* Read two nearest output values from the index in 1.31(q31) format */
+      y0 = pYData[index];
+      y1 = pYData[index + 1u];
+
+      /* Calculation of y0 * (1-fract) and y is in 2.30 format */
+      y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32));
+
+      /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */
+      y += ((q31_t) (((q63_t) y1 * fract) >> 32));
+
+      /* Convert y to 1.31 format */
+      return (y << 1u);
+
+    }
+
+  }
+
+  /**
+   *
+   * @brief  Process function for the Q15 Linear Interpolation Function.
+   * @param[in] *pYData  pointer to Q15 Linear Interpolation table
+   * @param[in] x input sample to process
+   * @param[in] nValues number of table values
+   * @return y processed output sample.
+   *
+   * \par
+   * Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+   * This function can support maximum of table size 2^12.
+   *
+   */
+
+
+  static __INLINE q15_t arm_linear_interp_q15(
+  q15_t * pYData,
+  q31_t x,
+  uint32_t nValues)
+  {
+    q63_t y;                                     /* output */
+    q15_t y0, y1;                                /* Nearest output values */
+    q31_t fract;                                 /* fractional part */
+    int32_t index;                               /* Index to read nearest output values */
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    index = ((x & 0xFFF00000) >> 20u);
+
+    if(index >= (int32_t)(nValues - 1))
+    {
+      return (pYData[nValues - 1]);
+    }
+    else if(index < 0)
+    {
+      return (pYData[0]);
+    }
+    else
+    {
+      /* 20 bits for the fractional part */
+      /* fract is in 12.20 format */
+      fract = (x & 0x000FFFFF);
+
+      /* Read two nearest output values from the index */
+      y0 = pYData[index];
+      y1 = pYData[index + 1u];
+
+      /* Calculation of y0 * (1-fract) and y is in 13.35 format */
+      y = ((q63_t) y0 * (0xFFFFF - fract));
+
+      /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */
+      y += ((q63_t) y1 * (fract));
+
+      /* convert y to 1.15 format */
+      return (y >> 20);
+    }
+
+
+  }
+
+  /**
+   *
+   * @brief  Process function for the Q7 Linear Interpolation Function.
+   * @param[in] *pYData  pointer to Q7 Linear Interpolation table
+   * @param[in] x input sample to process
+   * @param[in] nValues number of table values
+   * @return y processed output sample.
+   *
+   * \par
+   * Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+   * This function can support maximum of table size 2^12.
+   */
+
+
+  static __INLINE q7_t arm_linear_interp_q7(
+  q7_t * pYData,
+  q31_t x,
+  uint32_t nValues)
+  {
+    q31_t y;                                     /* output */
+    q7_t y0, y1;                                 /* Nearest output values */
+    q31_t fract;                                 /* fractional part */
+    uint32_t index;                              /* Index to read nearest output values */
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    if (x < 0)
+    {
+      return (pYData[0]);
+    }
+    index = (x >> 20) & 0xfff;
+
+
+    if(index >= (nValues - 1))
+    {
+      return (pYData[nValues - 1]);
+    }
+    else
+    {
+
+      /* 20 bits for the fractional part */
+      /* fract is in 12.20 format */
+      fract = (x & 0x000FFFFF);
+
+      /* Read two nearest output values from the index and are in 1.7(q7) format */
+      y0 = pYData[index];
+      y1 = pYData[index + 1u];
+
+      /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */
+      y = ((y0 * (0xFFFFF - fract)));
+
+      /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */
+      y += (y1 * fract);
+
+      /* convert y to 1.7(q7) format */
+      return (y >> 20u);
+
+    }
+
+  }
+  /**
+   * @} end of LinearInterpolate group
+   */
+
+  /**
+   * @brief  Fast approximation to the trigonometric sine function for floating-point data.
+   * @param[in] x input value in radians.
+   * @return  sin(x).
+   */
+
+  float32_t arm_sin_f32(
+  float32_t x);
+
+  /**
+   * @brief  Fast approximation to the trigonometric sine function for Q31 data.
+   * @param[in] x Scaled input value in radians.
+   * @return  sin(x).
+   */
+
+  q31_t arm_sin_q31(
+  q31_t x);
+
+  /**
+   * @brief  Fast approximation to the trigonometric sine function for Q15 data.
+   * @param[in] x Scaled input value in radians.
+   * @return  sin(x).
+   */
+
+  q15_t arm_sin_q15(
+  q15_t x);
+
+  /**
+   * @brief  Fast approximation to the trigonometric cosine function for floating-point data.
+   * @param[in] x input value in radians.
+   * @return  cos(x).
+   */
+
+  float32_t arm_cos_f32(
+  float32_t x);
+
+  /**
+   * @brief Fast approximation to the trigonometric cosine function for Q31 data.
+   * @param[in] x Scaled input value in radians.
+   * @return  cos(x).
+   */
+
+  q31_t arm_cos_q31(
+  q31_t x);
+
+  /**
+   * @brief  Fast approximation to the trigonometric cosine function for Q15 data.
+   * @param[in] x Scaled input value in radians.
+   * @return  cos(x).
+   */
+
+  q15_t arm_cos_q15(
+  q15_t x);
+
+
+  /**
+   * @ingroup groupFastMath
+   */
+
+
+  /**
+   * @defgroup SQRT Square Root
+   *
+   * Computes the square root of a number.
+   * There are separate functions for Q15, Q31, and floating-point data types.
+   * The square root function is computed using the Newton-Raphson algorithm.
+   * This is an iterative algorithm of the form:
+   * <pre>
+   *      x1 = x0 - f(x0)/f'(x0)
+   * </pre>
+   * where <code>x1</code> is the current estimate,
+   * <code>x0</code> is the previous estimate, and
+   * <code>f'(x0)</code> is the derivative of <code>f()</code> evaluated at <code>x0</code>.
+   * For the square root function, the algorithm reduces to:
+   * <pre>
+   *     x0 = in/2                         [initial guess]
+   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
+   * </pre>
+   */
+
+
+  /**
+   * @addtogroup SQRT
+   * @{
+   */
+
+  /**
+   * @brief  Floating-point square root function.
+   * @param[in]  in     input value.
+   * @param[out] *pOut  square root of input value.
+   * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if
+   * <code>in</code> is negative value and returns zero output for negative values.
+   */
+
+  static __INLINE arm_status arm_sqrt_f32(
+  float32_t in,
+  float32_t * pOut)
+  {
+    if(in > 0)
+    {
+
+//      #if __FPU_USED
+#if (__FPU_USED == 1) && defined ( __CC_ARM   )
+      *pOut = __sqrtf(in);
+#else
+      *pOut = sqrtf(in);
+#endif
+
+      return (ARM_MATH_SUCCESS);
+    }
+    else
+    {
+      *pOut = 0.0f;
+      return (ARM_MATH_ARGUMENT_ERROR);
+    }
+
+  }
+
+
+  /**
+   * @brief Q31 square root function.
+   * @param[in]   in    input value.  The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF.
+   * @param[out]  *pOut square root of input value.
+   * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if
+   * <code>in</code> is negative value and returns zero output for negative values.
+   */
+  arm_status arm_sqrt_q31(
+  q31_t in,
+  q31_t * pOut);
+
+  /**
+   * @brief  Q15 square root function.
+   * @param[in]   in     input value.  The range of the input value is [0 +1) or 0x0000 to 0x7FFF.
+   * @param[out]  *pOut  square root of input value.
+   * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if
+   * <code>in</code> is negative value and returns zero output for negative values.
+   */
+  arm_status arm_sqrt_q15(
+  q15_t in,
+  q15_t * pOut);
+
+  /**
+   * @} end of SQRT group
+   */
+
+
+
+
+
+
+  /**
+   * @brief floating-point Circular write function.
+   */
+
+  static __INLINE void arm_circularWrite_f32(
+  int32_t * circBuffer,
+  int32_t L,
+  uint16_t * writeOffset,
+  int32_t bufferInc,
+  const int32_t * src,
+  int32_t srcInc,
+  uint32_t blockSize)
+  {
+    uint32_t i = 0u;
+    int32_t wOffset;
+
+    /* Copy the value of Index pointer that points
+     * to the current location where the input samples to be copied */
+    wOffset = *writeOffset;
+
+    /* Loop over the blockSize */
+    i = blockSize;
+
+    while(i > 0u)
+    {
+      /* copy the input sample to the circular buffer */
+      circBuffer[wOffset] = *src;
+
+      /* Update the input pointer */
+      src += srcInc;
+
+      /* Circularly update wOffset.  Watch out for positive and negative value */
+      wOffset += bufferInc;
+      if(wOffset >= L)
+        wOffset -= L;
+
+      /* Decrement the loop counter */
+      i--;
+    }
+
+    /* Update the index pointer */
+    *writeOffset = wOffset;
+  }
+
+
+
+  /**
+   * @brief floating-point Circular Read function.
+   */
+  static __INLINE void arm_circularRead_f32(
+  int32_t * circBuffer,
+  int32_t L,
+  int32_t * readOffset,
+  int32_t bufferInc,
+  int32_t * dst,
+  int32_t * dst_base,
+  int32_t dst_length,
+  int32_t dstInc,
+  uint32_t blockSize)
+  {
+    uint32_t i = 0u;
+    int32_t rOffset, dst_end;
+
+    /* Copy the value of Index pointer that points
+     * to the current location from where the input samples to be read */
+    rOffset = *readOffset;
+    dst_end = (int32_t) (dst_base + dst_length);
+
+    /* Loop over the blockSize */
+    i = blockSize;
+
+    while(i > 0u)
+    {
+      /* copy the sample from the circular buffer to the destination buffer */
+      *dst = circBuffer[rOffset];
+
+      /* Update the input pointer */
+      dst += dstInc;
+
+      if(dst == (int32_t *) dst_end)
+      {
+        dst = dst_base;
+      }
+
+      /* Circularly update rOffset.  Watch out for positive and negative value  */
+      rOffset += bufferInc;
+
+      if(rOffset >= L)
+      {
+        rOffset -= L;
+      }
+
+      /* Decrement the loop counter */
+      i--;
+    }
+
+    /* Update the index pointer */
+    *readOffset = rOffset;
+  }
+
+  /**
+   * @brief Q15 Circular write function.
+   */
+
+  static __INLINE void arm_circularWrite_q15(
+  q15_t * circBuffer,
+  int32_t L,
+  uint16_t * writeOffset,
+  int32_t bufferInc,
+  const q15_t * src,
+  int32_t srcInc,
+  uint32_t blockSize)
+  {
+    uint32_t i = 0u;
+    int32_t wOffset;
+
+    /* Copy the value of Index pointer that points
+     * to the current location where the input samples to be copied */
+    wOffset = *writeOffset;
+
+    /* Loop over the blockSize */
+    i = blockSize;
+
+    while(i > 0u)
+    {
+      /* copy the input sample to the circular buffer */
+      circBuffer[wOffset] = *src;
+
+      /* Update the input pointer */
+      src += srcInc;
+
+      /* Circularly update wOffset.  Watch out for positive and negative value */
+      wOffset += bufferInc;
+      if(wOffset >= L)
+        wOffset -= L;
+
+      /* Decrement the loop counter */
+      i--;
+    }
+
+    /* Update the index pointer */
+    *writeOffset = wOffset;
+  }
+
+
+
+  /**
+   * @brief Q15 Circular Read function.
+   */
+  static __INLINE void arm_circularRead_q15(
+  q15_t * circBuffer,
+  int32_t L,
+  int32_t * readOffset,
+  int32_t bufferInc,
+  q15_t * dst,
+  q15_t * dst_base,
+  int32_t dst_length,
+  int32_t dstInc,
+  uint32_t blockSize)
+  {
+    uint32_t i = 0;
+    int32_t rOffset, dst_end;
+
+    /* Copy the value of Index pointer that points
+     * to the current location from where the input samples to be read */
+    rOffset = *readOffset;
+
+    dst_end = (int32_t) (dst_base + dst_length);
+
+    /* Loop over the blockSize */
+    i = blockSize;
+
+    while(i > 0u)
+    {
+      /* copy the sample from the circular buffer to the destination buffer */
+      *dst = circBuffer[rOffset];
+
+      /* Update the input pointer */
+      dst += dstInc;
+
+      if(dst == (q15_t *) dst_end)
+      {
+        dst = dst_base;
+      }
+
+      /* Circularly update wOffset.  Watch out for positive and negative value */
+      rOffset += bufferInc;
+
+      if(rOffset >= L)
+      {
+        rOffset -= L;
+      }
+
+      /* Decrement the loop counter */
+      i--;
+    }
+
+    /* Update the index pointer */
+    *readOffset = rOffset;
+  }
+
+
+  /**
+   * @brief Q7 Circular write function.
+   */
+
+  static __INLINE void arm_circularWrite_q7(
+  q7_t * circBuffer,
+  int32_t L,
+  uint16_t * writeOffset,
+  int32_t bufferInc,
+  const q7_t * src,
+  int32_t srcInc,
+  uint32_t blockSize)
+  {
+    uint32_t i = 0u;
+    int32_t wOffset;
+
+    /* Copy the value of Index pointer that points
+     * to the current location where the input samples to be copied */
+    wOffset = *writeOffset;
+
+    /* Loop over the blockSize */
+    i = blockSize;
+
+    while(i > 0u)
+    {
+      /* copy the input sample to the circular buffer */
+      circBuffer[wOffset] = *src;
+
+      /* Update the input pointer */
+      src += srcInc;
+
+      /* Circularly update wOffset.  Watch out for positive and negative value */
+      wOffset += bufferInc;
+      if(wOffset >= L)
+        wOffset -= L;
+
+      /* Decrement the loop counter */
+      i--;
+    }
+
+    /* Update the index pointer */
+    *writeOffset = wOffset;
+  }
+
+
+
+  /**
+   * @brief Q7 Circular Read function.
+   */
+  static __INLINE void arm_circularRead_q7(
+  q7_t * circBuffer,
+  int32_t L,
+  int32_t * readOffset,
+  int32_t bufferInc,
+  q7_t * dst,
+  q7_t * dst_base,
+  int32_t dst_length,
+  int32_t dstInc,
+  uint32_t blockSize)
+  {
+    uint32_t i = 0;
+    int32_t rOffset, dst_end;
+
+    /* Copy the value of Index pointer that points
+     * to the current location from where the input samples to be read */
+    rOffset = *readOffset;
+
+    dst_end = (int32_t) (dst_base + dst_length);
+
+    /* Loop over the blockSize */
+    i = blockSize;
+
+    while(i > 0u)
+    {
+      /* copy the sample from the circular buffer to the destination buffer */
+      *dst = circBuffer[rOffset];
+
+      /* Update the input pointer */
+      dst += dstInc;
+
+      if(dst == (q7_t *) dst_end)
+      {
+        dst = dst_base;
+      }
+
+      /* Circularly update rOffset.  Watch out for positive and negative value */
+      rOffset += bufferInc;
+
+      if(rOffset >= L)
+      {
+        rOffset -= L;
+      }
+
+      /* Decrement the loop counter */
+      i--;
+    }
+
+    /* Update the index pointer */
+    *readOffset = rOffset;
+  }
+
+
+  /**
+   * @brief  Sum of the squares of the elements of a Q31 vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output value.
+   * @return none.
+   */
+
+  void arm_power_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q63_t * pResult);
+
+  /**
+   * @brief  Sum of the squares of the elements of a floating-point vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output value.
+   * @return none.
+   */
+
+  void arm_power_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+  /**
+   * @brief  Sum of the squares of the elements of a Q15 vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output value.
+   * @return none.
+   */
+
+  void arm_power_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q63_t * pResult);
+
+  /**
+   * @brief  Sum of the squares of the elements of a Q7 vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output value.
+   * @return none.
+   */
+
+  void arm_power_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+  /**
+   * @brief  Mean value of a Q7 vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output value.
+   * @return none.
+   */
+
+  void arm_mean_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q7_t * pResult);
+
+  /**
+   * @brief  Mean value of a Q15 vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output value.
+   * @return none.
+   */
+  void arm_mean_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult);
+
+  /**
+   * @brief  Mean value of a Q31 vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output value.
+   * @return none.
+   */
+  void arm_mean_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+  /**
+   * @brief  Mean value of a floating-point vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output value.
+   * @return none.
+   */
+  void arm_mean_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+  /**
+   * @brief  Variance of the elements of a floating-point vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output value.
+   * @return none.
+   */
+
+  void arm_var_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+  /**
+   * @brief  Variance of the elements of a Q31 vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output value.
+   * @return none.
+   */
+
+  void arm_var_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q63_t * pResult);
+
+  /**
+   * @brief  Variance of the elements of a Q15 vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output value.
+   * @return none.
+   */
+
+  void arm_var_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+  /**
+   * @brief  Root Mean Square of the elements of a floating-point vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output value.
+   * @return none.
+   */
+
+  void arm_rms_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+  /**
+   * @brief  Root Mean Square of the elements of a Q31 vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output value.
+   * @return none.
+   */
+
+  void arm_rms_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+  /**
+   * @brief  Root Mean Square of the elements of a Q15 vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output value.
+   * @return none.
+   */
+
+  void arm_rms_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult);
+
+  /**
+   * @brief  Standard deviation of the elements of a floating-point vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output value.
+   * @return none.
+   */
+
+  void arm_std_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult);
+
+  /**
+   * @brief  Standard deviation of the elements of a Q31 vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output value.
+   * @return none.
+   */
+
+  void arm_std_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult);
+
+  /**
+   * @brief  Standard deviation of the elements of a Q15 vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output value.
+   * @return none.
+   */
+
+  void arm_std_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult);
+
+  /**
+   * @brief  Floating-point complex magnitude
+   * @param[in]  *pSrc points to the complex input vector
+   * @param[out]  *pDst points to the real output vector
+   * @param[in]  numSamples number of complex samples in the input vector
+   * @return none.
+   */
+
+  void arm_cmplx_mag_f32(
+  float32_t * pSrc,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+  /**
+   * @brief  Q31 complex magnitude
+   * @param[in]  *pSrc points to the complex input vector
+   * @param[out]  *pDst points to the real output vector
+   * @param[in]  numSamples number of complex samples in the input vector
+   * @return none.
+   */
+
+  void arm_cmplx_mag_q31(
+  q31_t * pSrc,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+  /**
+   * @brief  Q15 complex magnitude
+   * @param[in]  *pSrc points to the complex input vector
+   * @param[out]  *pDst points to the real output vector
+   * @param[in]  numSamples number of complex samples in the input vector
+   * @return none.
+   */
+
+  void arm_cmplx_mag_q15(
+  q15_t * pSrc,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+  /**
+   * @brief  Q15 complex dot product
+   * @param[in]  *pSrcA points to the first input vector
+   * @param[in]  *pSrcB points to the second input vector
+   * @param[in]  numSamples number of complex samples in each vector
+   * @param[out]  *realResult real part of the result returned here
+   * @param[out]  *imagResult imaginary part of the result returned here
+   * @return none.
+   */
+
+  void arm_cmplx_dot_prod_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  uint32_t numSamples,
+  q31_t * realResult,
+  q31_t * imagResult);
+
+  /**
+   * @brief  Q31 complex dot product
+   * @param[in]  *pSrcA points to the first input vector
+   * @param[in]  *pSrcB points to the second input vector
+   * @param[in]  numSamples number of complex samples in each vector
+   * @param[out]  *realResult real part of the result returned here
+   * @param[out]  *imagResult imaginary part of the result returned here
+   * @return none.
+   */
+
+  void arm_cmplx_dot_prod_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  uint32_t numSamples,
+  q63_t * realResult,
+  q63_t * imagResult);
+
+  /**
+   * @brief  Floating-point complex dot product
+   * @param[in]  *pSrcA points to the first input vector
+   * @param[in]  *pSrcB points to the second input vector
+   * @param[in]  numSamples number of complex samples in each vector
+   * @param[out]  *realResult real part of the result returned here
+   * @param[out]  *imagResult imaginary part of the result returned here
+   * @return none.
+   */
+
+  void arm_cmplx_dot_prod_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  uint32_t numSamples,
+  float32_t * realResult,
+  float32_t * imagResult);
+
+  /**
+   * @brief  Q15 complex-by-real multiplication
+   * @param[in]  *pSrcCmplx points to the complex input vector
+   * @param[in]  *pSrcReal points to the real input vector
+   * @param[out]  *pCmplxDst points to the complex output vector
+   * @param[in]  numSamples number of samples in each vector
+   * @return none.
+   */
+
+  void arm_cmplx_mult_real_q15(
+  q15_t * pSrcCmplx,
+  q15_t * pSrcReal,
+  q15_t * pCmplxDst,
+  uint32_t numSamples);
+
+  /**
+   * @brief  Q31 complex-by-real multiplication
+   * @param[in]  *pSrcCmplx points to the complex input vector
+   * @param[in]  *pSrcReal points to the real input vector
+   * @param[out]  *pCmplxDst points to the complex output vector
+   * @param[in]  numSamples number of samples in each vector
+   * @return none.
+   */
+
+  void arm_cmplx_mult_real_q31(
+  q31_t * pSrcCmplx,
+  q31_t * pSrcReal,
+  q31_t * pCmplxDst,
+  uint32_t numSamples);
+
+  /**
+   * @brief  Floating-point complex-by-real multiplication
+   * @param[in]  *pSrcCmplx points to the complex input vector
+   * @param[in]  *pSrcReal points to the real input vector
+   * @param[out]  *pCmplxDst points to the complex output vector
+   * @param[in]  numSamples number of samples in each vector
+   * @return none.
+   */
+
+  void arm_cmplx_mult_real_f32(
+  float32_t * pSrcCmplx,
+  float32_t * pSrcReal,
+  float32_t * pCmplxDst,
+  uint32_t numSamples);
+
+  /**
+   * @brief  Minimum value of a Q7 vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *result is output pointer
+   * @param[in]  index is the array index of the minimum value in the input buffer.
+   * @return none.
+   */
+
+  void arm_min_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q7_t * result,
+  uint32_t * index);
+
+  /**
+   * @brief  Minimum value of a Q15 vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output pointer
+   * @param[in]  *pIndex is the array index of the minimum value in the input buffer.
+   * @return none.
+   */
+
+  void arm_min_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult,
+  uint32_t * pIndex);
+
+  /**
+   * @brief  Minimum value of a Q31 vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output pointer
+   * @param[out]  *pIndex is the array index of the minimum value in the input buffer.
+   * @return none.
+   */
+  void arm_min_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult,
+  uint32_t * pIndex);
+
+  /**
+   * @brief  Minimum value of a floating-point vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @param[out]  *pResult is output pointer
+   * @param[out]  *pIndex is the array index of the minimum value in the input buffer.
+   * @return none.
+   */
+
+  void arm_min_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult,
+  uint32_t * pIndex);
+
+/**
+ * @brief Maximum value of a Q7 vector.
+ * @param[in]       *pSrc points to the input buffer
+ * @param[in]       blockSize length of the input vector
+ * @param[out]      *pResult maximum value returned here
+ * @param[out]      *pIndex index of maximum value returned here
+ * @return none.
+ */
+
+  void arm_max_q7(
+  q7_t * pSrc,
+  uint32_t blockSize,
+  q7_t * pResult,
+  uint32_t * pIndex);
+
+/**
+ * @brief Maximum value of a Q15 vector.
+ * @param[in]       *pSrc points to the input buffer
+ * @param[in]       blockSize length of the input vector
+ * @param[out]      *pResult maximum value returned here
+ * @param[out]      *pIndex index of maximum value returned here
+ * @return none.
+ */
+
+  void arm_max_q15(
+  q15_t * pSrc,
+  uint32_t blockSize,
+  q15_t * pResult,
+  uint32_t * pIndex);
+
+/**
+ * @brief Maximum value of a Q31 vector.
+ * @param[in]       *pSrc points to the input buffer
+ * @param[in]       blockSize length of the input vector
+ * @param[out]      *pResult maximum value returned here
+ * @param[out]      *pIndex index of maximum value returned here
+ * @return none.
+ */
+
+  void arm_max_q31(
+  q31_t * pSrc,
+  uint32_t blockSize,
+  q31_t * pResult,
+  uint32_t * pIndex);
+
+/**
+ * @brief Maximum value of a floating-point vector.
+ * @param[in]       *pSrc points to the input buffer
+ * @param[in]       blockSize length of the input vector
+ * @param[out]      *pResult maximum value returned here
+ * @param[out]      *pIndex index of maximum value returned here
+ * @return none.
+ */
+
+  void arm_max_f32(
+  float32_t * pSrc,
+  uint32_t blockSize,
+  float32_t * pResult,
+  uint32_t * pIndex);
+
+  /**
+   * @brief  Q15 complex-by-complex multiplication
+   * @param[in]  *pSrcA points to the first input vector
+   * @param[in]  *pSrcB points to the second input vector
+   * @param[out]  *pDst  points to the output vector
+   * @param[in]  numSamples number of complex samples in each vector
+   * @return none.
+   */
+
+  void arm_cmplx_mult_cmplx_q15(
+  q15_t * pSrcA,
+  q15_t * pSrcB,
+  q15_t * pDst,
+  uint32_t numSamples);
+
+  /**
+   * @brief  Q31 complex-by-complex multiplication
+   * @param[in]  *pSrcA points to the first input vector
+   * @param[in]  *pSrcB points to the second input vector
+   * @param[out]  *pDst  points to the output vector
+   * @param[in]  numSamples number of complex samples in each vector
+   * @return none.
+   */
+
+  void arm_cmplx_mult_cmplx_q31(
+  q31_t * pSrcA,
+  q31_t * pSrcB,
+  q31_t * pDst,
+  uint32_t numSamples);
+
+  /**
+   * @brief  Floating-point complex-by-complex multiplication
+   * @param[in]  *pSrcA points to the first input vector
+   * @param[in]  *pSrcB points to the second input vector
+   * @param[out]  *pDst  points to the output vector
+   * @param[in]  numSamples number of complex samples in each vector
+   * @return none.
+   */
+
+  void arm_cmplx_mult_cmplx_f32(
+  float32_t * pSrcA,
+  float32_t * pSrcB,
+  float32_t * pDst,
+  uint32_t numSamples);
+
+  /**
+   * @brief Converts the elements of the floating-point vector to Q31 vector.
+   * @param[in]       *pSrc points to the floating-point input vector
+   * @param[out]      *pDst points to the Q31 output vector
+   * @param[in]       blockSize length of the input vector
+   * @return none.
+   */
+  void arm_float_to_q31(
+  float32_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Converts the elements of the floating-point vector to Q15 vector.
+   * @param[in]       *pSrc points to the floating-point input vector
+   * @param[out]      *pDst points to the Q15 output vector
+   * @param[in]       blockSize length of the input vector
+   * @return          none
+   */
+  void arm_float_to_q15(
+  float32_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief Converts the elements of the floating-point vector to Q7 vector.
+   * @param[in]       *pSrc points to the floating-point input vector
+   * @param[out]      *pDst points to the Q7 output vector
+   * @param[in]       blockSize length of the input vector
+   * @return          none
+   */
+  void arm_float_to_q7(
+  float32_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Converts the elements of the Q31 vector to Q15 vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[out]  *pDst is output pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @return none.
+   */
+  void arm_q31_to_q15(
+  q31_t * pSrc,
+  q15_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Converts the elements of the Q31 vector to Q7 vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[out]  *pDst is output pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @return none.
+   */
+  void arm_q31_to_q7(
+  q31_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+  /**
+   * @brief  Converts the elements of the Q15 vector to floating-point vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[out]  *pDst is output pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @return none.
+   */
+  void arm_q15_to_float(
+  q15_t * pSrc,
+  float32_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Converts the elements of the Q15 vector to Q31 vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[out]  *pDst is output pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @return none.
+   */
+  void arm_q15_to_q31(
+  q15_t * pSrc,
+  q31_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @brief  Converts the elements of the Q15 vector to Q7 vector.
+   * @param[in]  *pSrc is input pointer
+   * @param[out]  *pDst is output pointer
+   * @param[in]  blockSize is the number of samples to process
+   * @return none.
+   */
+  void arm_q15_to_q7(
+  q15_t * pSrc,
+  q7_t * pDst,
+  uint32_t blockSize);
+
+
+  /**
+   * @ingroup groupInterpolation
+   */
+
+  /**
+   * @defgroup BilinearInterpolate Bilinear Interpolation
+   *
+   * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid.
+   * The underlying function <code>f(x, y)</code> is sampled on a regular grid and the interpolation process
+   * determines values between the grid points.
+   * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension.
+   * Bilinear interpolation is often used in image processing to rescale images.
+   * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types.
+   *
+   * <b>Algorithm</b>
+   * \par
+   * The instance structure used by the bilinear interpolation functions describes a two dimensional data table.
+   * For floating-point, the instance structure is defined as:
+   * <pre>
+   *   typedef struct
+   *   {
+   *     uint16_t numRows;
+   *     uint16_t numCols;
+   *     float32_t *pData;
+   * } arm_bilinear_interp_instance_f32;
+   * </pre>
+   *
+   * \par
+   * where <code>numRows</code> specifies the number of rows in the table;
+   * <code>numCols</code> specifies the number of columns in the table;
+   * and <code>pData</code> points to an array of size <code>numRows*numCols</code> values.
+   * The data table <code>pTable</code> is organized in row order and the supplied data values fall on integer indexes.
+   * That is, table element (x,y) is located at <code>pTable[x + y*numCols]</code> where x and y are integers.
+   *
+   * \par
+   * Let <code>(x, y)</code> specify the desired interpolation point.  Then define:
+   * <pre>
+   *     XF = floor(x)
+   *     YF = floor(y)
+   * </pre>
+   * \par
+   * The interpolated output point is computed as:
+   * <pre>
+   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
+   * </pre>
+   * Note that the coordinates (x, y) contain integer and fractional components.
+   * The integer components specify which portion of the table to use while the
+   * fractional components control the interpolation processor.
+   *
+   * \par
+   * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output.
+   */
+
+  /**
+   * @addtogroup BilinearInterpolate
+   * @{
+   */
+
+  /**
+  *
+  * @brief  Floating-point bilinear interpolation.
+  * @param[in,out] *S points to an instance of the interpolation structure.
+  * @param[in] X interpolation coordinate.
+  * @param[in] Y interpolation coordinate.
+  * @return out interpolated value.
+  */
+
+
+  static __INLINE float32_t arm_bilinear_interp_f32(
+  const arm_bilinear_interp_instance_f32 * S,
+  float32_t X,
+  float32_t Y)
+  {
+    float32_t out;
+    float32_t f00, f01, f10, f11;
+    float32_t *pData = S->pData;
+    int32_t xIndex, yIndex, index;
+    float32_t xdiff, ydiff;
+    float32_t b1, b2, b3, b4;
+
+    xIndex = (int32_t) X;
+    yIndex = (int32_t) Y;
+
+    /* Care taken for table outside boundary */
+    /* Returns zero output when values are outside table boundary */
+    if(xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0
+       || yIndex > (S->numCols - 1))
+    {
+      return (0);
+    }
+
+    /* Calculation of index for two nearest points in X-direction */
+    index = (xIndex - 1) + (yIndex - 1) * S->numCols;
+
+
+    /* Read two nearest points in X-direction */
+    f00 = pData[index];
+    f01 = pData[index + 1];
+
+    /* Calculation of index for two nearest points in Y-direction */
+    index = (xIndex - 1) + (yIndex) * S->numCols;
+
+
+    /* Read two nearest points in Y-direction */
+    f10 = pData[index];
+    f11 = pData[index + 1];
+
+    /* Calculation of intermediate values */
+    b1 = f00;
+    b2 = f01 - f00;
+    b3 = f10 - f00;
+    b4 = f00 - f01 - f10 + f11;
+
+    /* Calculation of fractional part in X */
+    xdiff = X - xIndex;
+
+    /* Calculation of fractional part in Y */
+    ydiff = Y - yIndex;
+
+    /* Calculation of bi-linear interpolated output */
+    out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff;
+
+    /* return to application */
+    return (out);
+
+  }
+
+  /**
+  *
+  * @brief  Q31 bilinear interpolation.
+  * @param[in,out] *S points to an instance of the interpolation structure.
+  * @param[in] X interpolation coordinate in 12.20 format.
+  * @param[in] Y interpolation coordinate in 12.20 format.
+  * @return out interpolated value.
+  */
+
+  static __INLINE q31_t arm_bilinear_interp_q31(
+  arm_bilinear_interp_instance_q31 * S,
+  q31_t X,
+  q31_t Y)
+  {
+    q31_t out;                                   /* Temporary output */
+    q31_t acc = 0;                               /* output */
+    q31_t xfract, yfract;                        /* X, Y fractional parts */
+    q31_t x1, x2, y1, y2;                        /* Nearest output values */
+    int32_t rI, cI;                              /* Row and column indices */
+    q31_t *pYData = S->pData;                    /* pointer to output table values */
+    uint32_t nCols = S->numCols;                 /* num of rows */
+
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    rI = ((X & 0xFFF00000) >> 20u);
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    cI = ((Y & 0xFFF00000) >> 20u);
+
+    /* Care taken for table outside boundary */
+    /* Returns zero output when values are outside table boundary */
+    if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
+    {
+      return (0);
+    }
+
+    /* 20 bits for the fractional part */
+    /* shift left xfract by 11 to keep 1.31 format */
+    xfract = (X & 0x000FFFFF) << 11u;
+
+    /* Read two nearest output values from the index */
+    x1 = pYData[(rI) + nCols * (cI)];
+    x2 = pYData[(rI) + nCols * (cI) + 1u];
+
+    /* 20 bits for the fractional part */
+    /* shift left yfract by 11 to keep 1.31 format */
+    yfract = (Y & 0x000FFFFF) << 11u;
+
+    /* Read two nearest output values from the index */
+    y1 = pYData[(rI) + nCols * (cI + 1)];
+    y2 = pYData[(rI) + nCols * (cI + 1) + 1u];
+
+    /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */
+    out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32));
+    acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32));
+
+    /* x2 * (xfract) * (1-yfract)  in 3.29(q29) and adding to acc */
+    out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32));
+    acc += ((q31_t) ((q63_t) out * (xfract) >> 32));
+
+    /* y1 * (1 - xfract) * (yfract)  in 3.29(q29) and adding to acc */
+    out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32));
+    acc += ((q31_t) ((q63_t) out * (yfract) >> 32));
+
+    /* y2 * (xfract) * (yfract)  in 3.29(q29) and adding to acc */
+    out = ((q31_t) ((q63_t) y2 * (xfract) >> 32));
+    acc += ((q31_t) ((q63_t) out * (yfract) >> 32));
+
+    /* Convert acc to 1.31(q31) format */
+    return (acc << 2u);
+
+  }
+
+  /**
+  * @brief  Q15 bilinear interpolation.
+  * @param[in,out] *S points to an instance of the interpolation structure.
+  * @param[in] X interpolation coordinate in 12.20 format.
+  * @param[in] Y interpolation coordinate in 12.20 format.
+  * @return out interpolated value.
+  */
+
+  static __INLINE q15_t arm_bilinear_interp_q15(
+  arm_bilinear_interp_instance_q15 * S,
+  q31_t X,
+  q31_t Y)
+  {
+    q63_t acc = 0;                               /* output */
+    q31_t out;                                   /* Temporary output */
+    q15_t x1, x2, y1, y2;                        /* Nearest output values */
+    q31_t xfract, yfract;                        /* X, Y fractional parts */
+    int32_t rI, cI;                              /* Row and column indices */
+    q15_t *pYData = S->pData;                    /* pointer to output table values */
+    uint32_t nCols = S->numCols;                 /* num of rows */
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    rI = ((X & 0xFFF00000) >> 20);
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    cI = ((Y & 0xFFF00000) >> 20);
+
+    /* Care taken for table outside boundary */
+    /* Returns zero output when values are outside table boundary */
+    if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
+    {
+      return (0);
+    }
+
+    /* 20 bits for the fractional part */
+    /* xfract should be in 12.20 format */
+    xfract = (X & 0x000FFFFF);
+
+    /* Read two nearest output values from the index */
+    x1 = pYData[(rI) + nCols * (cI)];
+    x2 = pYData[(rI) + nCols * (cI) + 1u];
+
+
+    /* 20 bits for the fractional part */
+    /* yfract should be in 12.20 format */
+    yfract = (Y & 0x000FFFFF);
+
+    /* Read two nearest output values from the index */
+    y1 = pYData[(rI) + nCols * (cI + 1)];
+    y2 = pYData[(rI) + nCols * (cI + 1) + 1u];
+
+    /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */
+
+    /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */
+    /* convert 13.35 to 13.31 by right shifting  and out is in 1.31 */
+    out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u);
+    acc = ((q63_t) out * (0xFFFFF - yfract));
+
+    /* x2 * (xfract) * (1-yfract)  in 1.51 and adding to acc */
+    out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u);
+    acc += ((q63_t) out * (xfract));
+
+    /* y1 * (1 - xfract) * (yfract)  in 1.51 and adding to acc */
+    out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u);
+    acc += ((q63_t) out * (yfract));
+
+    /* y2 * (xfract) * (yfract)  in 1.51 and adding to acc */
+    out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u);
+    acc += ((q63_t) out * (yfract));
+
+    /* acc is in 13.51 format and down shift acc by 36 times */
+    /* Convert out to 1.15 format */
+    return (acc >> 36);
+
+  }
+
+  /**
+  * @brief  Q7 bilinear interpolation.
+  * @param[in,out] *S points to an instance of the interpolation structure.
+  * @param[in] X interpolation coordinate in 12.20 format.
+  * @param[in] Y interpolation coordinate in 12.20 format.
+  * @return out interpolated value.
+  */
+
+  static __INLINE q7_t arm_bilinear_interp_q7(
+  arm_bilinear_interp_instance_q7 * S,
+  q31_t X,
+  q31_t Y)
+  {
+    q63_t acc = 0;                               /* output */
+    q31_t out;                                   /* Temporary output */
+    q31_t xfract, yfract;                        /* X, Y fractional parts */
+    q7_t x1, x2, y1, y2;                         /* Nearest output values */
+    int32_t rI, cI;                              /* Row and column indices */
+    q7_t *pYData = S->pData;                     /* pointer to output table values */
+    uint32_t nCols = S->numCols;                 /* num of rows */
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    rI = ((X & 0xFFF00000) >> 20);
+
+    /* Input is in 12.20 format */
+    /* 12 bits for the table index */
+    /* Index value calculation */
+    cI = ((Y & 0xFFF00000) >> 20);
+
+    /* Care taken for table outside boundary */
+    /* Returns zero output when values are outside table boundary */
+    if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
+    {
+      return (0);
+    }
+
+    /* 20 bits for the fractional part */
+    /* xfract should be in 12.20 format */
+    xfract = (X & 0x000FFFFF);
+
+    /* Read two nearest output values from the index */
+    x1 = pYData[(rI) + nCols * (cI)];
+    x2 = pYData[(rI) + nCols * (cI) + 1u];
+
+
+    /* 20 bits for the fractional part */
+    /* yfract should be in 12.20 format */
+    yfract = (Y & 0x000FFFFF);
+
+    /* Read two nearest output values from the index */
+    y1 = pYData[(rI) + nCols * (cI + 1)];
+    y2 = pYData[(rI) + nCols * (cI + 1) + 1u];
+
+    /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */
+    out = ((x1 * (0xFFFFF - xfract)));
+    acc = (((q63_t) out * (0xFFFFF - yfract)));
+
+    /* x2 * (xfract) * (1-yfract)  in 2.22 and adding to acc */
+    out = ((x2 * (0xFFFFF - yfract)));
+    acc += (((q63_t) out * (xfract)));
+
+    /* y1 * (1 - xfract) * (yfract)  in 2.22 and adding to acc */
+    out = ((y1 * (0xFFFFF - xfract)));
+    acc += (((q63_t) out * (yfract)));
+
+    /* y2 * (xfract) * (yfract)  in 2.22 and adding to acc */
+    out = ((y2 * (yfract)));
+    acc += (((q63_t) out * (xfract)));
+
+    /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */
+    return (acc >> 40);
+
+  }
+
+  /**
+   * @} end of BilinearInterpolate group
+   */
+
+
+#if   defined ( __CC_ARM ) //Keil
+//SMMLAR
+  #define multAcc_32x32_keep32_R(a, x, y) \
+  a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32)
+
+//SMMLSR
+  #define multSub_32x32_keep32_R(a, x, y) \
+  a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32)
+
+//SMMULR
+  #define mult_32x32_keep32_R(a, x, y) \
+  a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32)
+
+//Enter low optimization region - place directly above function definition
+  #define LOW_OPTIMIZATION_ENTER \
+     _Pragma ("push")         \
+     _Pragma ("O1")
+
+//Exit low optimization region - place directly after end of function definition
+  #define LOW_OPTIMIZATION_EXIT \
+     _Pragma ("pop")
+
+//Enter low optimization region - place directly above function definition
+  #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+
+//Exit low optimization region - place directly after end of function definition
+  #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__ICCARM__) //IAR
+ //SMMLA
+  #define multAcc_32x32_keep32_R(a, x, y) \
+  a += (q31_t) (((q63_t) x * y) >> 32)
+
+ //SMMLS
+  #define multSub_32x32_keep32_R(a, x, y) \
+  a -= (q31_t) (((q63_t) x * y) >> 32)
+
+//SMMUL
+  #define mult_32x32_keep32_R(a, x, y) \
+  a = (q31_t) (((q63_t) x * y ) >> 32)
+
+//Enter low optimization region - place directly above function definition
+  #define LOW_OPTIMIZATION_ENTER \
+     _Pragma ("optimize=low")
+
+//Exit low optimization region - place directly after end of function definition
+  #define LOW_OPTIMIZATION_EXIT
+
+//Enter low optimization region - place directly above function definition
+  #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \
+     _Pragma ("optimize=low")
+
+//Exit low optimization region - place directly after end of function definition
+  #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__GNUC__)
+ //SMMLA
+  #define multAcc_32x32_keep32_R(a, x, y) \
+  a += (q31_t) (((q63_t) x * y) >> 32)
+
+ //SMMLS
+  #define multSub_32x32_keep32_R(a, x, y) \
+  a -= (q31_t) (((q63_t) x * y) >> 32)
+
+//SMMUL
+  #define mult_32x32_keep32_R(a, x, y) \
+  a = (q31_t) (((q63_t) x * y ) >> 32)
+
+  #define LOW_OPTIMIZATION_ENTER __attribute__(( optimize("-O1") ))
+
+  #define LOW_OPTIMIZATION_EXIT
+
+  #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+
+  #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#endif
+
+
+
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+
+#endif /* _ARM_MATH_H */
+
+
+/**
+ *
+ * End of file.
+ */
diff --git a/reform2-lpc-fw/cmsis/cmsis_os.h b/reform2-lpc-fw/cmsis/cmsis_os.h
new file mode 100644
index 0000000000000000000000000000000000000000..ea4d77cb6a5254a98981e719b67d38dbe3b619c9
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/cmsis_os.h
@@ -0,0 +1,805 @@
+/* ----------------------------------------------------------------------
+ * $Date:        5. February 2013
+ * $Revision:    V1.02
+ *
+ * Project:      CMSIS-RTOS API
+ * Title:        cmsis_os.h RTX header file
+ *
+ * Version 0.02
+ *    Initial Proposal Phase
+ * Version 0.03
+ *    osKernelStart added, optional feature: main started as thread
+ *    osSemaphores have standard behavior
+ *    osTimerCreate does not start the timer, added osTimerStart
+ *    osThreadPass is renamed to osThreadYield
+ * Version 1.01
+ *    Support for C++ interface
+ *     - const attribute removed from the osXxxxDef_t typedef's
+ *     - const attribute added to the osXxxxDef macros
+ *    Added: osTimerDelete, osMutexDelete, osSemaphoreDelete
+ *    Added: osKernelInitialize
+ * Version 1.02
+ *    Control functions for short timeouts in microsecond resolution:
+ *    Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec
+ *    Removed: osSignalGet 
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 2013 ARM LIMITED
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+/**
+\page cmsis_os_h Header File Template: cmsis_os.h
+
+The file \b cmsis_os.h is a template header file for a CMSIS-RTOS compliant Real-Time Operating System (RTOS).
+Each RTOS that is compliant with CMSIS-RTOS shall provide a specific \b cmsis_os.h header file that represents
+its implementation.
+
+The file cmsis_os.h contains:
+ - CMSIS-RTOS API function definitions
+ - struct definitions for parameters and return types
+ - status and priority values used by CMSIS-RTOS API functions
+ - macros for defining threads and other kernel objects
+
+
+<b>Name conventions and header file modifications</b>
+
+All definitions are prefixed with \b os to give an unique name space for CMSIS-RTOS functions.
+Definitions that are prefixed \b os_ are not used in the application code but local to this header file.
+All definitions and functions that belong to a module are grouped and have a common prefix, i.e. \b osThread.
+
+Definitions that are marked with <b>CAN BE CHANGED</b> can be adapted towards the needs of the actual CMSIS-RTOS implementation.
+These definitions can be specific to the underlying RTOS kernel.
+
+Definitions that are marked with <b>MUST REMAIN UNCHANGED</b> cannot be altered. Otherwise the CMSIS-RTOS implementation is no longer
+compliant to the standard. Note that some functions are optional and need not to be provided by every CMSIS-RTOS implementation.
+
+
+<b>Function calls from interrupt service routines</b>
+
+The following CMSIS-RTOS functions can be called from threads and interrupt service routines (ISR):
+  - \ref osSignalSet
+  - \ref osSemaphoreRelease
+  - \ref osPoolAlloc, \ref osPoolCAlloc, \ref osPoolFree
+  - \ref osMessagePut, \ref osMessageGet
+  - \ref osMailAlloc, \ref osMailCAlloc, \ref osMailGet, \ref osMailPut, \ref osMailFree
+
+Functions that cannot be called from an ISR are verifying the interrupt status and return in case that they are called
+from an ISR context the status code \b osErrorISR. In some implementations this condition might be caught using the HARD FAULT vector.
+
+Some CMSIS-RTOS implementations support CMSIS-RTOS function calls from multiple ISR at the same time.
+If this is impossible, the CMSIS-RTOS rejects calls by nested ISR functions with the status code \b osErrorISRRecursive.
+
+
+<b>Define and reference object definitions</b>
+
+With <b>\#define osObjectsExternal</b> objects are defined as external symbols. This allows to create a consistent header file
+that is used throughout a project as shown below:
+
+<i>Header File</i>
+\code
+#include <cmsis_os.h>                                         // CMSIS RTOS header file
+
+// Thread definition
+extern void thread_sample (void const *argument);             // function prototype
+osThreadDef (thread_sample, osPriorityBelowNormal, 1, 100);
+
+// Pool definition
+osPoolDef(MyPool, 10, long);
+\endcode
+
+
+This header file defines all objects when included in a C/C++ source file. When <b>\#define osObjectsExternal</b> is
+present before the header file, the objects are defined as external symbols. A single consistent header file can therefore be
+used throughout the whole project.
+
+<i>Example</i>
+\code
+#include "osObjects.h"     // Definition of the CMSIS-RTOS objects
+\endcode
+
+\code
+#define osObjectExternal   // Objects will be defined as external symbols
+#include "osObjects.h"     // Reference to the CMSIS-RTOS objects
+\endcode
+
+*/
+
+#ifndef _CMSIS_OS_H
+#define _CMSIS_OS_H
+
+/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version.
+#define osCMSIS           0x10002      ///< API version (main [31:16] .sub [15:0])
+
+/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number.
+#define osCMSIS_RTX     ((4<<16)|70)   ///< RTOS identification and version (main [31:16] .sub [15:0])
+
+/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS.
+#define osKernelSystemId "RTX V4.70"   ///< RTOS identification string
+
+
+/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS.
+#define osFeature_MainThread   1       ///< main thread      1=main can be thread, 0=not available
+#define osFeature_Pool         1       ///< Memory Pools:    1=available, 0=not available
+#define osFeature_MailQ        1       ///< Mail Queues:     1=available, 0=not available
+#define osFeature_MessageQ     1       ///< Message Queues:  1=available, 0=not available
+#define osFeature_Signals      16      ///< maximum number of Signal Flags available per thread
+#define osFeature_Semaphore    65535   ///< maximum count for \ref osSemaphoreCreate function
+#define osFeature_Wait         0       ///< osWait function: 1=available, 0=not available
+#define osFeature_SysTick      1       ///< osKernelSysTick functions: 1=available, 0=not available
+
+#if defined (__CC_ARM)
+#define os_InRegs __value_in_regs      // Compiler specific: force struct in registers
+#else
+#define os_InRegs
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+
+#ifdef  __cplusplus
+extern "C"
+{
+#endif
+
+
+// ==== Enumeration, structures, defines ====
+
+/// Priority used for thread control.
+/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS.
+typedef enum  {
+  osPriorityIdle          = -3,          ///< priority: idle (lowest)
+  osPriorityLow           = -2,          ///< priority: low
+  osPriorityBelowNormal   = -1,          ///< priority: below normal
+  osPriorityNormal        =  0,          ///< priority: normal (default)
+  osPriorityAboveNormal   = +1,          ///< priority: above normal
+  osPriorityHigh          = +2,          ///< priority: high
+  osPriorityRealtime      = +3,          ///< priority: realtime (highest)
+  osPriorityError         =  0x84        ///< system cannot determine priority or thread has illegal priority
+} osPriority;
+
+/// Timeout value.
+/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS.
+#define osWaitForever     0xFFFFFFFF     ///< wait forever timeout value
+
+/// Status code values returned by CMSIS-RTOS functions.
+/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS.
+typedef enum  {
+  osOK                    =     0,       ///< function completed; no error or event occurred.
+  osEventSignal           =  0x08,       ///< function completed; signal event occurred.
+  osEventMessage          =  0x10,       ///< function completed; message event occurred.
+  osEventMail             =  0x20,       ///< function completed; mail event occurred.
+  osEventTimeout          =  0x40,       ///< function completed; timeout occurred.
+  osErrorParameter        =  0x80,       ///< parameter error: a mandatory parameter was missing or specified an incorrect object.
+  osErrorResource         =  0x81,       ///< resource not available: a specified resource was not available.
+  osErrorTimeoutResource  =  0xC1,       ///< resource not available within given time: a specified resource was not available within the timeout period.
+  osErrorISR              =  0x82,       ///< not allowed in ISR context: the function cannot be called from interrupt service routines.
+  osErrorISRRecursive     =  0x83,       ///< function called multiple times from ISR with same object.
+  osErrorPriority         =  0x84,       ///< system cannot determine priority or thread has illegal priority.
+  osErrorNoMemory         =  0x85,       ///< system is out of memory: it was impossible to allocate or reserve memory for the operation.
+  osErrorValue            =  0x86,       ///< value of a parameter is out of range.
+  osErrorOS               =  0xFF,       ///< unspecified RTOS error: run-time error but no other error message fits.
+  os_status_reserved      =  0x7FFFFFFF  ///< prevent from enum down-size compiler optimization.
+} osStatus;
+
+
+/// Timer type value for the timer definition.
+/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS.
+typedef enum  {
+  osTimerOnce             =     0,       ///< one-shot timer
+  osTimerPeriodic         =     1        ///< repeating timer
+} os_timer_type;
+
+/// Entry point of a thread.
+/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS.
+typedef void (*os_pthread) (void const *argument);
+
+/// Entry point of a timer call back function.
+/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS.
+typedef void (*os_ptimer) (void const *argument);
+
+// >>> the following data type definitions may shall adapted towards a specific RTOS
+
+/// Thread ID identifies the thread (pointer to a thread control block).
+/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS.
+typedef struct os_thread_cb *osThreadId;
+
+/// Timer ID identifies the timer (pointer to a timer control block).
+/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS.
+typedef struct os_timer_cb *osTimerId;
+
+/// Mutex ID identifies the mutex (pointer to a mutex control block).
+/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS.
+typedef struct os_mutex_cb *osMutexId;
+
+/// Semaphore ID identifies the semaphore (pointer to a semaphore control block).
+/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS.
+typedef struct os_semaphore_cb *osSemaphoreId;
+
+/// Pool ID identifies the memory pool (pointer to a memory pool control block).
+/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS.
+typedef struct os_pool_cb *osPoolId;
+
+/// Message ID identifies the message queue (pointer to a message queue control block).
+/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS.
+typedef struct os_messageQ_cb *osMessageQId;
+
+/// Mail ID identifies the mail queue (pointer to a mail queue control block).
+/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS.
+typedef struct os_mailQ_cb *osMailQId;
+
+
+/// Thread Definition structure contains startup information of a thread.
+/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_thread_def  {
+  os_pthread               pthread;    ///< start address of thread function
+  osPriority             tpriority;    ///< initial thread priority
+  uint32_t               instances;    ///< maximum number of instances of that thread function
+  uint32_t               stacksize;    ///< stack size requirements in bytes; 0 is default stack size
+} osThreadDef_t;
+
+/// Timer Definition structure contains timer parameters.
+/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_timer_def  {
+  os_ptimer                 ptimer;    ///< start address of a timer function
+  void                      *timer;    ///< pointer to internal data
+} osTimerDef_t;
+
+/// Mutex Definition structure contains setup information for a mutex.
+/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_mutex_def  {
+  void                      *mutex;    ///< pointer to internal data
+} osMutexDef_t;
+
+/// Semaphore Definition structure contains setup information for a semaphore.
+/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_semaphore_def  {
+  void                  *semaphore;    ///< pointer to internal data
+} osSemaphoreDef_t;
+
+/// Definition structure for memory block allocation.
+/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_pool_def  {
+  uint32_t                 pool_sz;    ///< number of items (elements) in the pool
+  uint32_t                 item_sz;    ///< size of an item
+  void                       *pool;    ///< pointer to memory for pool
+} osPoolDef_t;
+
+/// Definition structure for message queue.
+/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_messageQ_def  {
+  uint32_t                queue_sz;    ///< number of elements in the queue
+  void                       *pool;    ///< memory array for messages
+} osMessageQDef_t;
+
+/// Definition structure for mail queue.
+/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS.
+typedef struct os_mailQ_def  {
+  uint32_t                queue_sz;    ///< number of elements in the queue
+  uint32_t                 item_sz;    ///< size of an item
+  void                       *pool;    ///< memory array for mail
+} osMailQDef_t;
+
+/// Event structure contains detailed information about an event.
+/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS.
+///       However the struct may be extended at the end.
+typedef struct  {
+  osStatus                 status;     ///< status code: event or error information
+  union  {
+    uint32_t                    v;     ///< message as 32-bit value
+    void                       *p;     ///< message or mail as void pointer
+    int32_t               signals;     ///< signal flags
+  } value;                             ///< event value
+  union  {
+    osMailQId             mail_id;     ///< mail id obtained by \ref osMailCreate
+    osMessageQId       message_id;     ///< message id obtained by \ref osMessageCreate
+  } def;                               ///< event definition
+} osEvent;
+
+
+//  ==== Kernel Control Functions ====
+
+/// Initialize the RTOS Kernel for creating objects.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS.
+osStatus osKernelInitialize (void);
+
+/// Start the RTOS Kernel.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS.
+osStatus osKernelStart (void);
+
+/// Check if the RTOS kernel is already started.
+/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS.
+/// \return 0 RTOS is not started, 1 RTOS is started.
+int32_t osKernelRunning(void);
+
+#if (defined (osFeature_SysTick)  &&  (osFeature_SysTick != 0))     // System Timer available
+
+extern uint32_t const os_tickfreq;
+extern uint16_t const os_tickus_i;
+extern uint16_t const os_tickus_f;
+
+/// Get the RTOS kernel system timer counter.
+/// \note MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS.
+/// \return RTOS kernel system timer as 32-bit value 
+uint32_t osKernelSysTick (void);
+
+/// The RTOS kernel system timer frequency in Hz.
+/// \note Reflects the system timer setting and is typically defined in a configuration file.
+#define osKernelSysTickFrequency os_tickfreq
+
+/// Convert a microseconds value to a RTOS kernel system timer value.
+/// \param         microsec     time value in microseconds.
+/// \return time value normalized to the \ref osKernelSysTickFrequency
+/*
+#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000)
+*/
+#define osKernelSysTickMicroSec(microsec) ((microsec * os_tickus_i) + ((microsec * os_tickus_f) >> 16))
+
+#endif    // System Timer available
+
+//  ==== Thread Management ====
+
+/// Create a Thread Definition with function, priority, and stack requirements.
+/// \param         name         name of the thread function.
+/// \param         priority     initial priority of the thread function.
+/// \param         instances    number of possible thread instances.
+/// \param         stacksz      stack size (in bytes) requirements for the thread function.
+/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osThreadDef(name, priority, instances, stacksz)  \
+extern const osThreadDef_t os_thread_def_##name
+#else                            // define the object
+#define osThreadDef(name, priority, instances, stacksz)  \
+const osThreadDef_t os_thread_def_##name = \
+{ (name), (priority), (instances), (stacksz)  }
+#endif
+
+/// Access a Thread definition.
+/// \param         name          name of the thread definition object.
+/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osThread(name)  \
+&os_thread_def_##name
+
+/// Create a thread and add it to Active Threads and set it to state READY.
+/// \param[in]     thread_def    thread definition referenced with \ref osThread.
+/// \param[in]     argument      pointer that is passed to the thread function as start argument.
+/// \return thread ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS.
+osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument);
+
+/// Return the thread ID of the current running thread.
+/// \return thread ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS.
+osThreadId osThreadGetId (void);
+
+/// Terminate execution of a thread and remove it from Active Threads.
+/// \param[in]     thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS.
+osStatus osThreadTerminate (osThreadId thread_id);
+
+/// Pass control to next thread that is in state \b READY.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS.
+osStatus osThreadYield (void);
+
+/// Change priority of an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in]     priority      new priority value for the thread function.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS.
+osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority);
+
+/// Get current priority of an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \return current priority value of the thread function.
+/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS.
+osPriority osThreadGetPriority (osThreadId thread_id);
+
+
+//  ==== Generic Wait Functions ====
+
+/// Wait for Timeout (Time Delay).
+/// \param[in]     millisec      time delay value
+/// \return status code that indicates the execution status of the function.
+osStatus osDelay (uint32_t millisec);
+
+#if (defined (osFeature_Wait)  &&  (osFeature_Wait != 0))     // Generic Wait available
+
+/// Wait for Signal, Message, Mail, or Timeout.
+/// \param[in] millisec          timeout value or 0 in case of no time-out
+/// \return event that contains signal, message, or mail information or error code.
+/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS.
+os_InRegs osEvent osWait (uint32_t millisec);
+
+#endif  // Generic Wait available
+
+
+//  ==== Timer Management Functions ====
+/// Define a Timer object.
+/// \param         name          name of the timer object.
+/// \param         function      name of the timer call back function.
+/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osTimerDef(name, function)  \
+extern const osTimerDef_t os_timer_def_##name
+#else                            // define the object
+#define osTimerDef(name, function)  \
+uint32_t os_timer_cb_##name[5]; \
+const osTimerDef_t os_timer_def_##name = \
+{ (function), (os_timer_cb_##name) }
+#endif
+
+/// Access a Timer definition.
+/// \param         name          name of the timer object.
+/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osTimer(name) \
+&os_timer_def_##name
+
+/// Create a timer.
+/// \param[in]     timer_def     timer object referenced with \ref osTimer.
+/// \param[in]     type          osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
+/// \param[in]     argument      argument to the timer call back function.
+/// \return timer ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS.
+osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument);
+
+/// Start or restart a timer.
+/// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate.
+/// \param[in]     millisec      time delay value of the timer.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS.
+osStatus osTimerStart (osTimerId timer_id, uint32_t millisec);
+
+/// Stop the timer.
+/// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS.
+osStatus osTimerStop (osTimerId timer_id);
+
+/// Delete a timer that was created by \ref osTimerCreate.
+/// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS.
+osStatus osTimerDelete (osTimerId timer_id);
+
+
+//  ==== Signal Management ====
+
+/// Set the specified Signal Flags of an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in]     signals       specifies the signal flags of the thread that should be set.
+/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
+/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS.
+int32_t osSignalSet (osThreadId thread_id, int32_t signals);
+
+/// Clear the specified Signal Flags of an active thread.
+/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
+/// \param[in]     signals       specifies the signal flags of the thread that shall be cleared.
+/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
+/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS.
+int32_t osSignalClear (osThreadId thread_id, int32_t signals);
+
+/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread.
+/// \param[in]     signals       wait until all specified signal flags set or 0 for any single signal flag.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out.
+/// \return event flag information or error code.
+/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS.
+os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec);
+
+
+//  ==== Mutex Management ====
+
+/// Define a Mutex.
+/// \param         name          name of the mutex object.
+/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osMutexDef(name)  \
+extern const osMutexDef_t os_mutex_def_##name
+#else                            // define the object
+#define osMutexDef(name)  \
+uint32_t os_mutex_cb_##name[3]; \
+const osMutexDef_t os_mutex_def_##name = { (os_mutex_cb_##name) }
+#endif
+
+/// Access a Mutex definition.
+/// \param         name          name of the mutex object.
+/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osMutex(name)  \
+&os_mutex_def_##name
+
+/// Create and Initialize a Mutex object.
+/// \param[in]     mutex_def     mutex definition referenced with \ref osMutex.
+/// \return mutex ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS.
+osMutexId osMutexCreate (const osMutexDef_t *mutex_def);
+
+/// Wait until a Mutex becomes available.
+/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexCreate.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS.
+osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec);
+
+/// Release a Mutex that was obtained by \ref osMutexWait.
+/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS.
+osStatus osMutexRelease (osMutexId mutex_id);
+
+/// Delete a Mutex that was created by \ref osMutexCreate.
+/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS.
+osStatus osMutexDelete (osMutexId mutex_id);
+
+
+//  ==== Semaphore Management Functions ====
+
+#if (defined (osFeature_Semaphore)  &&  (osFeature_Semaphore != 0))     // Semaphore available
+
+/// Define a Semaphore object.
+/// \param         name          name of the semaphore object.
+/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osSemaphoreDef(name)  \
+extern const osSemaphoreDef_t os_semaphore_def_##name
+#else                            // define the object
+#define osSemaphoreDef(name)  \
+uint32_t os_semaphore_cb_##name[2]; \
+const osSemaphoreDef_t os_semaphore_def_##name = { (os_semaphore_cb_##name) }
+#endif
+
+/// Access a Semaphore definition.
+/// \param         name          name of the semaphore object.
+/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osSemaphore(name)  \
+&os_semaphore_def_##name
+
+/// Create and Initialize a Semaphore object used for managing resources.
+/// \param[in]     semaphore_def semaphore definition referenced with \ref osSemaphore.
+/// \param[in]     count         number of available resources.
+/// \return semaphore ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS.
+osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count);
+
+/// Wait until a Semaphore token becomes available.
+/// \param[in]     semaphore_id  semaphore object referenced with \ref osSemaphoreCreate.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out.
+/// \return number of available tokens, or -1 in case of incorrect parameters.
+/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS.
+int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec);
+
+/// Release a Semaphore token.
+/// \param[in]     semaphore_id  semaphore object referenced with \ref osSemaphoreCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS.
+osStatus osSemaphoreRelease (osSemaphoreId semaphore_id);
+
+/// Delete a Semaphore that was created by \ref osSemaphoreCreate.
+/// \param[in]     semaphore_id  semaphore object referenced with \ref osSemaphoreCreate.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS.
+osStatus osSemaphoreDelete (osSemaphoreId semaphore_id);
+
+#endif     // Semaphore available
+
+
+//  ==== Memory Pool Management Functions ====
+
+#if (defined (osFeature_Pool)  &&  (osFeature_Pool != 0))  // Memory Pool Management available
+
+/// \brief Define a Memory Pool.
+/// \param         name          name of the memory pool.
+/// \param         no            maximum number of blocks (objects) in the memory pool.
+/// \param         type          data type of a single block (object).
+/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osPoolDef(name, no, type)   \
+extern const osPoolDef_t os_pool_def_##name
+#else                            // define the object
+#define osPoolDef(name, no, type)   \
+uint32_t os_pool_m_##name[3+((sizeof(type)+3)/4)*(no)]; \
+const osPoolDef_t os_pool_def_##name = \
+{ (no), sizeof(type), (os_pool_m_##name) }
+#endif
+
+/// \brief Access a Memory Pool definition.
+/// \param         name          name of the memory pool
+/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osPool(name) \
+&os_pool_def_##name
+
+/// Create and Initialize a memory pool.
+/// \param[in]     pool_def      memory pool definition referenced with \ref osPool.
+/// \return memory pool ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS.
+osPoolId osPoolCreate (const osPoolDef_t *pool_def);
+
+/// Allocate a memory block from a memory pool.
+/// \param[in]     pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+/// \return address of the allocated memory block or NULL in case of no memory available.
+/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS.
+void *osPoolAlloc (osPoolId pool_id);
+
+/// Allocate a memory block from a memory pool and set memory block to zero.
+/// \param[in]     pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+/// \return address of the allocated memory block or NULL in case of no memory available.
+/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS.
+void *osPoolCAlloc (osPoolId pool_id);
+
+/// Return an allocated memory block back to a specific memory pool.
+/// \param[in]     pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
+/// \param[in]     block         address of the allocated memory block that is returned to the memory pool.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS.
+osStatus osPoolFree (osPoolId pool_id, void *block);
+
+#endif   // Memory Pool Management available
+
+
+//  ==== Message Queue Management Functions ====
+
+#if (defined (osFeature_MessageQ)  &&  (osFeature_MessageQ != 0))     // Message Queues available
+
+/// \brief Create a Message Queue Definition.
+/// \param         name          name of the queue.
+/// \param         queue_sz      maximum number of messages in the queue.
+/// \param         type          data type of a single message element (for debugger).
+/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osMessageQDef(name, queue_sz, type)   \
+extern const osMessageQDef_t os_messageQ_def_##name
+#else                            // define the object
+#define osMessageQDef(name, queue_sz, type)   \
+uint32_t os_messageQ_q_##name[4+(queue_sz)]; \
+const osMessageQDef_t os_messageQ_def_##name = \
+{ (queue_sz), (os_messageQ_q_##name) }
+#endif
+
+/// \brief Access a Message Queue Definition.
+/// \param         name          name of the queue
+/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osMessageQ(name) \
+&os_messageQ_def_##name
+
+/// Create and Initialize a Message Queue.
+/// \param[in]     queue_def     queue definition referenced with \ref osMessageQ.
+/// \param[in]     thread_id     thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
+/// \return message queue ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS.
+osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id);
+
+/// Put a Message to a Queue.
+/// \param[in]     queue_id      message queue ID obtained with \ref osMessageCreate.
+/// \param[in]     info          message information.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS.
+osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec);
+
+/// Get a Message or Wait for a Message from a Queue.
+/// \param[in]     queue_id      message queue ID obtained with \ref osMessageCreate.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out.
+/// \return event information that includes status code.
+/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS.
+os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec);
+
+#endif     // Message Queues available
+
+
+//  ==== Mail Queue Management Functions ====
+
+#if (defined (osFeature_MailQ)  &&  (osFeature_MailQ != 0))     // Mail Queues available
+
+/// \brief Create a Mail Queue Definition.
+/// \param         name          name of the queue
+/// \param         queue_sz      maximum number of messages in queue
+/// \param         type          data type of a single message element
+/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#if defined (osObjectsExternal)  // object is external
+#define osMailQDef(name, queue_sz, type) \
+extern const osMailQDef_t os_mailQ_def_##name
+#else                            // define the object
+#define osMailQDef(name, queue_sz, type) \
+uint32_t os_mailQ_q_##name[4+(queue_sz)]; \
+uint32_t os_mailQ_m_##name[3+((sizeof(type)+3)/4)*(queue_sz)]; \
+void *   os_mailQ_p_##name[2] = { (os_mailQ_q_##name), os_mailQ_m_##name }; \
+const osMailQDef_t os_mailQ_def_##name =  \
+{ (queue_sz), sizeof(type), (os_mailQ_p_##name) }
+#endif
+
+/// \brief Access a Mail Queue Definition.
+/// \param         name          name of the queue
+/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the
+///       macro body is implementation specific in every CMSIS-RTOS.
+#define osMailQ(name)  \
+&os_mailQ_def_##name
+
+/// Create and Initialize mail queue.
+/// \param[in]     queue_def     reference to the mail queue definition obtain with \ref osMailQ
+/// \param[in]     thread_id     thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
+/// \return mail queue ID for reference by other functions or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS.
+osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id);
+
+/// Allocate a memory block from a mail.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out
+/// \return pointer to memory block that can be filled with mail or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS.
+void *osMailAlloc (osMailQId queue_id, uint32_t millisec);
+
+/// Allocate a memory block from a mail and set memory block to zero.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out
+/// \return pointer to memory block that can be filled with mail or NULL in case of error.
+/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS.
+void *osMailCAlloc (osMailQId queue_id, uint32_t millisec);
+
+/// Put a mail to a queue.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     mail          memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS.
+osStatus osMailPut (osMailQId queue_id, void *mail);
+
+/// Get a mail from a queue.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     millisec      timeout value or 0 in case of no time-out
+/// \return event that contains mail information or error code.
+/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS.
+os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec);
+
+/// Free a memory block from a mail.
+/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
+/// \param[in]     mail          pointer to the memory block that was obtained with \ref osMailGet.
+/// \return status code that indicates the execution status of the function.
+/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS.
+osStatus osMailFree (osMailQId queue_id, void *mail);
+
+#endif  // Mail Queues available
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif  // _CMSIS_OS_H
diff --git a/reform2-lpc-fw/cmsis/core_cm0.h b/reform2-lpc-fw/cmsis/core_cm0.h
new file mode 100644
index 0000000000000000000000000000000000000000..ab31de0ee87f9cb566cef040364c80c1f09bbf86
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/core_cm0.h
@@ -0,0 +1,682 @@
+/**************************************************************************//**
+ * @file     core_cm0.h
+ * @brief    CMSIS Cortex-M0 Core Peripheral Access Layer Header File
+ * @version  V3.20
+ * @date     25. February 2013
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2013 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include  /* treat file as system include file for MISRA check */
+#endif
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef __CORE_CM0_H_GENERIC
+#define __CORE_CM0_H_GENERIC
+
+/** \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/** \ingroup Cortex_M0
+  @{
+ */
+
+/*  CMSIS CM0 definitions */
+#define __CM0_CMSIS_VERSION_MAIN  (0x03)                                   /*!< [31:16] CMSIS HAL main version   */
+#define __CM0_CMSIS_VERSION_SUB   (0x20)                                   /*!< [15:0]  CMSIS HAL sub version    */
+#define __CM0_CMSIS_VERSION       ((__CM0_CMSIS_VERSION_MAIN << 16) | \
+                                    __CM0_CMSIS_VERSION_SUB          )     /*!< CMSIS HAL version number         */
+
+#define __CORTEX_M                (0x00)                                   /*!< Cortex-M Core                    */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler          */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler       */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler      */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler   */
+  #define __STATIC_INLINE  static inline
+
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all
+*/
+#define __FPU_USED       0
+
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+#endif
+
+#include <stdint.h>                      /* standard types definitions                      */
+#include <core_cmInstr.h>                /* Core Instruction Access                         */
+#include <core_cmFunc.h>                 /* Core Function Access                            */
+
+#endif /* __CORE_CM0_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM0_H_DEPENDANT
+#define __CORE_CM0_H_DEPENDANT
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM0_REV
+    #define __CM0_REV               0x0000
+    #warning "__CM0_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          2
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions                 */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions                 */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions                */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions              */
+
+/*@} end of group Cortex_M0 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+ ******************************************************************************/
+/** \defgroup CMSIS_core_register Defines and Type Definitions
+    \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_CORE  Status and Control Registers
+    \brief  Core Register type definitions.
+  @{
+ */
+
+/** \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+#if (__CORTEX_M != 0x04)
+    uint32_t _reserved0:27;              /*!< bit:  0..26  Reserved                           */
+#else
+    uint32_t _reserved0:16;              /*!< bit:  0..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:7;               /*!< bit: 20..26  Reserved                           */
+#endif
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} APSR_Type;
+
+
+/** \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} IPSR_Type;
+
+
+/** \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+#if (__CORTEX_M != 0x04)
+    uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved                           */
+#else
+    uint32_t _reserved0:7;               /*!< bit:  9..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:4;               /*!< bit: 20..23  Reserved                           */
+#endif
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0)          */
+    uint32_t IT:2;                       /*!< bit: 25..26  saved IT state   (read 0)          */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} xPSR_Type;
+
+
+/** \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used                   */
+    uint32_t FPCA:1;                     /*!< bit:      2  FP extension active flag           */
+    uint32_t _reserved0:29;              /*!< bit:  3..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} CONTROL_Type;
+
+/*@} end of group CMSIS_CORE */
+
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+    \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/** \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IO uint32_t ISER[1];                 /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register           */
+       uint32_t RESERVED0[31];
+  __IO uint32_t ICER[1];                 /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register          */
+       uint32_t RSERVED1[31];
+  __IO uint32_t ISPR[1];                 /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register           */
+       uint32_t RESERVED2[31];
+  __IO uint32_t ICPR[1];                 /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register         */
+       uint32_t RESERVED3[31];
+       uint32_t RESERVED4[64];
+  __IO uint32_t IP[8];                   /*!< Offset: 0x300 (R/W)  Interrupt Priority Register              */
+}  NVIC_Type;
+
+/*@} end of group CMSIS_NVIC */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SCB     System Control Block (SCB)
+    \brief      Type definitions for the System Control Block Registers
+  @{
+ */
+
+/** \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __I  uint32_t CPUID;                   /*!< Offset: 0x000 (R/ )  CPUID Base Register                                   */
+  __IO uint32_t ICSR;                    /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register                  */
+       uint32_t RESERVED0;
+  __IO uint32_t AIRCR;                   /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register      */
+  __IO uint32_t SCR;                     /*!< Offset: 0x010 (R/W)  System Control Register                               */
+  __IO uint32_t CCR;                     /*!< Offset: 0x014 (R/W)  Configuration Control Register                        */
+       uint32_t RESERVED1;
+  __IO uint32_t SHP[2];                  /*!< Offset: 0x01C (R/W)  System Handlers Priority Registers. [0] is RESERVED   */
+  __IO uint32_t SHCSR;                   /*!< Offset: 0x024 (R/W)  System Handler Control and State Register             */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24                                             /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20                                             /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16                                             /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4                                             /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0                                             /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL << SCB_CPUID_REVISION_Pos)              /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31                                             /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28                                             /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27                                             /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26                                             /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25                                             /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23                                             /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22                                             /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12                                             /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0                                             /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos)           /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16                                             /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16                                             /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15                                             /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2                                             /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1                                             /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4                                             /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2                                             /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1                                             /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9                                             /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3                                             /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_SVCALLPENDED_Pos         15                                             /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+    \brief      Type definitions for the System Timer Registers.
+  @{
+ */
+
+/** \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IO uint32_t CTRL;                    /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IO uint32_t LOAD;                    /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register       */
+  __IO uint32_t VAL;                     /*!< Offset: 0x008 (R/W)  SysTick Current Value Register      */
+  __I  uint32_t CALIB;                   /*!< Offset: 0x00C (R/ )  SysTick Calibration Register        */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16                                             /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1                                             /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0                                             /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL << SysTick_CTRL_ENABLE_Pos)               /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0                                             /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos)        /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0                                             /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos)        /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31                                             /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30                                             /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0                                             /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos)        /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+    \brief      Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR)
+                are only accessible over DAP and not via processor. Therefore
+                they are not covered by the Cortex-M0 header file.
+  @{
+ */
+/*@} end of group CMSIS_CoreDebug */
+
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_core_base     Core Definitions
+    \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M0 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address              */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address                 */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address */
+
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct           */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct       */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct          */
+
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+    \brief      Functions that manage interrupts and exceptions via the NVIC.
+    @{
+ */
+
+/* Interrupt Priorities are WORD accessible only under ARMv6M                   */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn)         (  (((uint32_t)(IRQn)       )    &  0x03) * 8 )
+#define _SHP_IDX(IRQn)           ( ((((uint32_t)(IRQn) & 0x0F)-8) >>    2)     )
+#define _IP_IDX(IRQn)            (   ((uint32_t)(IRQn)            >>    2)     )
+
+
+/** \brief  Enable External Interrupt
+
+    The function enables a device-specific interrupt in the NVIC interrupt controller.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
+}
+
+
+/** \brief  Disable External Interrupt
+
+    The function disables a device-specific interrupt in the NVIC interrupt controller.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
+}
+
+
+/** \brief  Get Pending Interrupt
+
+    The function reads the pending register in the NVIC and returns the pending bit
+    for the specified interrupt.
+
+    \param [in]      IRQn  Interrupt number.
+
+    \return             0  Interrupt status is not pending.
+    \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
+}
+
+
+/** \brief  Set Pending Interrupt
+
+    The function sets the pending bit of an external interrupt.
+
+    \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
+}
+
+
+/** \brief  Clear Pending Interrupt
+
+    The function clears the pending bit of an external interrupt.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
+}
+
+
+/** \brief  Set Interrupt Priority
+
+    The function sets the priority of an interrupt.
+
+    \note The priority cannot be set for every core interrupt.
+
+    \param [in]      IRQn  Interrupt number.
+    \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if(IRQn < 0) {
+    SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
+        (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
+  else {
+    NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
+        (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
+}
+
+
+/** \brief  Get Interrupt Priority
+
+    The function reads the priority of an interrupt. The interrupt
+    number can be positive to specify an external (device specific)
+    interrupt, or negative to specify an internal (core) interrupt.
+
+
+    \param [in]   IRQn  Interrupt number.
+    \return             Interrupt Priority. Value is aligned automatically to the implemented
+                        priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if(IRQn < 0) {
+    return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for Cortex-M0 system interrupts */
+  else {
+    return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for device specific interrupts  */
+}
+
+
+/** \brief  System Reset
+
+    The function initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                     /* Ensure all outstanding memory accesses included
+                                                                  buffered write are completed before reset */
+  SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      |
+                 SCB_AIRCR_SYSRESETREQ_Msk);
+  __DSB();                                                     /* Ensure completion of memory access */
+  while(1);                                                    /* wait until reset */
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+    \brief      Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0)
+
+/** \brief  System Tick Configuration
+
+    The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
+    Counter is in free running mode to generate periodic interrupts.
+
+    \param [in]  ticks  Number of ticks between two interrupts.
+
+    \return          0  Function succeeded.
+    \return          1  Function failed.
+
+    \note     When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+    function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+    must contain a vendor-specific implementation of this function.
+
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk)  return (1);      /* Reload value impossible */
+
+  SysTick->LOAD  = ticks - 1;                                  /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
+  return (0);                                                  /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+
+#endif /* __CORE_CM0_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/reform2-lpc-fw/cmsis/core_cm3.h b/reform2-lpc-fw/cmsis/core_cm3.h
new file mode 100644
index 0000000000000000000000000000000000000000..122c9aa4a8fd6832d39545a26636a662c7ff317c
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/core_cm3.h
@@ -0,0 +1,1627 @@
+/**************************************************************************//**
+ * @file     core_cm3.h
+ * @brief    CMSIS Cortex-M3 Core Peripheral Access Layer Header File
+ * @version  V3.20
+ * @date     25. February 2013
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2013 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include  /* treat file as system include file for MISRA check */
+#endif
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef __CORE_CM3_H_GENERIC
+#define __CORE_CM3_H_GENERIC
+
+/** \page CMSIS_MISRA_Exceptions  MISRA-C:2004 Compliance Exceptions
+  CMSIS violates the following MISRA-C:2004 rules:
+
+   \li Required Rule 8.5, object/function definition in header file.<br>
+     Function definitions in header files are used to allow 'inlining'.
+
+   \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+     Unions are used for effective representation of core registers.
+
+   \li Advisory Rule 19.7, Function-like macro defined.<br>
+     Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ *                 CMSIS definitions
+ ******************************************************************************/
+/** \ingroup Cortex_M3
+  @{
+ */
+
+/*  CMSIS CM3 definitions */
+#define __CM3_CMSIS_VERSION_MAIN  (0x03)                                   /*!< [31:16] CMSIS HAL main version   */
+#define __CM3_CMSIS_VERSION_SUB   (0x20)                                   /*!< [15:0]  CMSIS HAL sub version    */
+#define __CM3_CMSIS_VERSION       ((__CM3_CMSIS_VERSION_MAIN << 16) | \
+                                    __CM3_CMSIS_VERSION_SUB          )     /*!< CMSIS HAL version number         */
+
+#define __CORTEX_M                (0x03)                                   /*!< Cortex-M Core                    */
+
+
+#if   defined ( __CC_ARM )
+  #define __ASM            __asm                                      /*!< asm keyword for ARM Compiler          */
+  #define __INLINE         __inline                                   /*!< inline keyword for ARM Compiler       */
+  #define __STATIC_INLINE  static __inline
+
+#elif defined ( __ICCARM__ )
+  #define __ASM            __asm                                      /*!< asm keyword for IAR Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TMS470__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TI CCS Compiler       */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __GNUC__ )
+  #define __ASM            __asm                                      /*!< asm keyword for GNU Compiler          */
+  #define __INLINE         inline                                     /*!< inline keyword for GNU Compiler       */
+  #define __STATIC_INLINE  static inline
+
+#elif defined ( __TASKING__ )
+  #define __ASM            __asm                                      /*!< asm keyword for TASKING Compiler      */
+  #define __INLINE         inline                                     /*!< inline keyword for TASKING Compiler   */
+  #define __STATIC_INLINE  static inline
+
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all
+*/
+#define __FPU_USED       0
+
+#if defined ( __CC_ARM )
+  #if defined __TARGET_FPU_VFP
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __ICCARM__ )
+  #if defined __ARMVFP__
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TMS470__ )
+  #if defined __TI__VFP_SUPPORT____
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __GNUC__ )
+  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+
+#elif defined ( __TASKING__ )
+  #if defined __FPU_VFP__
+    #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+  #endif
+#endif
+
+#include <stdint.h>                      /* standard types definitions                      */
+#include <core_cmInstr.h>                /* Core Instruction Access                         */
+#include <core_cmFunc.h>                 /* Core Function Access                            */
+
+#endif /* __CORE_CM3_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM3_H_DEPENDANT
+#define __CORE_CM3_H_DEPENDANT
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+  #ifndef __CM3_REV
+    #define __CM3_REV               0x0200
+    #warning "__CM3_REV not defined in device header file; using default!"
+  #endif
+
+  #ifndef __MPU_PRESENT
+    #define __MPU_PRESENT             0
+    #warning "__MPU_PRESENT not defined in device header file; using default!"
+  #endif
+
+  #ifndef __NVIC_PRIO_BITS
+    #define __NVIC_PRIO_BITS          4
+    #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+  #endif
+
+  #ifndef __Vendor_SysTickConfig
+    #define __Vendor_SysTickConfig    0
+    #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+  #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+    \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+    <strong>IO Type Qualifiers</strong> are used
+    \li to specify the access to peripheral variables.
+    \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+  #define   __I     volatile             /*!< Defines 'read only' permissions                 */
+#else
+  #define   __I     volatile const       /*!< Defines 'read only' permissions                 */
+#endif
+#define     __O     volatile             /*!< Defines 'write only' permissions                */
+#define     __IO    volatile             /*!< Defines 'read / write' permissions              */
+
+/*@} end of group Cortex_M3 */
+
+
+
+/*******************************************************************************
+ *                 Register Abstraction
+  Core Register contain:
+  - Core Register
+  - Core NVIC Register
+  - Core SCB Register
+  - Core SysTick Register
+  - Core Debug Register
+  - Core MPU Register
+ ******************************************************************************/
+/** \defgroup CMSIS_core_register Defines and Type Definitions
+    \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_CORE  Status and Control Registers
+    \brief  Core Register type definitions.
+  @{
+ */
+
+/** \brief  Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+  struct
+  {
+#if (__CORTEX_M != 0x04)
+    uint32_t _reserved0:27;              /*!< bit:  0..26  Reserved                           */
+#else
+    uint32_t _reserved0:16;              /*!< bit:  0..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:7;               /*!< bit: 20..26  Reserved                           */
+#endif
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} APSR_Type;
+
+
+/** \brief  Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+    uint32_t _reserved0:23;              /*!< bit:  9..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} IPSR_Type;
+
+
+/** \brief  Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t ISR:9;                      /*!< bit:  0.. 8  Exception number                   */
+#if (__CORTEX_M != 0x04)
+    uint32_t _reserved0:15;              /*!< bit:  9..23  Reserved                           */
+#else
+    uint32_t _reserved0:7;               /*!< bit:  9..15  Reserved                           */
+    uint32_t GE:4;                       /*!< bit: 16..19  Greater than or Equal flags        */
+    uint32_t _reserved1:4;               /*!< bit: 20..23  Reserved                           */
+#endif
+    uint32_t T:1;                        /*!< bit:     24  Thumb bit        (read 0)          */
+    uint32_t IT:2;                       /*!< bit: 25..26  saved IT state   (read 0)          */
+    uint32_t Q:1;                        /*!< bit:     27  Saturation condition flag          */
+    uint32_t V:1;                        /*!< bit:     28  Overflow condition code flag       */
+    uint32_t C:1;                        /*!< bit:     29  Carry condition code flag          */
+    uint32_t Z:1;                        /*!< bit:     30  Zero condition code flag           */
+    uint32_t N:1;                        /*!< bit:     31  Negative condition code flag       */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} xPSR_Type;
+
+
+/** \brief  Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+  struct
+  {
+    uint32_t nPRIV:1;                    /*!< bit:      0  Execution privilege in Thread mode */
+    uint32_t SPSEL:1;                    /*!< bit:      1  Stack to be used                   */
+    uint32_t FPCA:1;                     /*!< bit:      2  FP extension active flag           */
+    uint32_t _reserved0:29;              /*!< bit:  3..31  Reserved                           */
+  } b;                                   /*!< Structure used for bit  access                  */
+  uint32_t w;                            /*!< Type      used for word access                  */
+} CONTROL_Type;
+
+/*@} end of group CMSIS_CORE */
+
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_NVIC  Nested Vectored Interrupt Controller (NVIC)
+    \brief      Type definitions for the NVIC Registers
+  @{
+ */
+
+/** \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+  __IO uint32_t ISER[8];                 /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register           */
+       uint32_t RESERVED0[24];
+  __IO uint32_t ICER[8];                 /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register         */
+       uint32_t RSERVED1[24];
+  __IO uint32_t ISPR[8];                 /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register          */
+       uint32_t RESERVED2[24];
+  __IO uint32_t ICPR[8];                 /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register        */
+       uint32_t RESERVED3[24];
+  __IO uint32_t IABR[8];                 /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register           */
+       uint32_t RESERVED4[56];
+  __IO uint8_t  IP[240];                 /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
+       uint32_t RESERVED5[644];
+  __O  uint32_t STIR;                    /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register     */
+}  NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos                 0                                          /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk                (0x1FFUL << NVIC_STIR_INTID_Pos)            /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SCB     System Control Block (SCB)
+    \brief      Type definitions for the System Control Block Registers
+  @{
+ */
+
+/** \brief  Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+  __I  uint32_t CPUID;                   /*!< Offset: 0x000 (R/ )  CPUID Base Register                                   */
+  __IO uint32_t ICSR;                    /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register                  */
+  __IO uint32_t VTOR;                    /*!< Offset: 0x008 (R/W)  Vector Table Offset Register                          */
+  __IO uint32_t AIRCR;                   /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register      */
+  __IO uint32_t SCR;                     /*!< Offset: 0x010 (R/W)  System Control Register                               */
+  __IO uint32_t CCR;                     /*!< Offset: 0x014 (R/W)  Configuration Control Register                        */
+  __IO uint8_t  SHP[12];                 /*!< Offset: 0x018 (R/W)  System Handlers Priority Registers (4-7, 8-11, 12-15) */
+  __IO uint32_t SHCSR;                   /*!< Offset: 0x024 (R/W)  System Handler Control and State Register             */
+  __IO uint32_t CFSR;                    /*!< Offset: 0x028 (R/W)  Configurable Fault Status Register                    */
+  __IO uint32_t HFSR;                    /*!< Offset: 0x02C (R/W)  HardFault Status Register                             */
+  __IO uint32_t DFSR;                    /*!< Offset: 0x030 (R/W)  Debug Fault Status Register                           */
+  __IO uint32_t MMFAR;                   /*!< Offset: 0x034 (R/W)  MemManage Fault Address Register                      */
+  __IO uint32_t BFAR;                    /*!< Offset: 0x038 (R/W)  BusFault Address Register                             */
+  __IO uint32_t AFSR;                    /*!< Offset: 0x03C (R/W)  Auxiliary Fault Status Register                       */
+  __I  uint32_t PFR[2];                  /*!< Offset: 0x040 (R/ )  Processor Feature Register                            */
+  __I  uint32_t DFR;                     /*!< Offset: 0x048 (R/ )  Debug Feature Register                                */
+  __I  uint32_t ADR;                     /*!< Offset: 0x04C (R/ )  Auxiliary Feature Register                            */
+  __I  uint32_t MMFR[4];                 /*!< Offset: 0x050 (R/ )  Memory Model Feature Register                         */
+  __I  uint32_t ISAR[5];                 /*!< Offset: 0x060 (R/ )  Instruction Set Attributes Register                   */
+       uint32_t RESERVED0[5];
+  __IO uint32_t CPACR;                   /*!< Offset: 0x088 (R/W)  Coprocessor Access Control Register                   */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos          24                                             /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos)          /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos              20                                             /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk              (0xFUL << SCB_CPUID_VARIANT_Pos)               /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos         16                                             /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk         (0xFUL << SCB_CPUID_ARCHITECTURE_Pos)          /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos                4                                             /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk               (0xFFFUL << SCB_CPUID_PARTNO_Pos)              /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos              0                                             /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk             (0xFUL << SCB_CPUID_REVISION_Pos)              /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos            31                                             /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk            (1UL << SCB_ICSR_NMIPENDSET_Pos)               /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos             28                                             /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk             (1UL << SCB_ICSR_PENDSVSET_Pos)                /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos             27                                             /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk             (1UL << SCB_ICSR_PENDSVCLR_Pos)                /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos             26                                             /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk             (1UL << SCB_ICSR_PENDSTSET_Pos)                /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos             25                                             /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk             (1UL << SCB_ICSR_PENDSTCLR_Pos)                /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos            23                                             /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk            (1UL << SCB_ICSR_ISRPREEMPT_Pos)               /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos            22                                             /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk            (1UL << SCB_ICSR_ISRPENDING_Pos)               /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos           12                                             /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk           (0x1FFUL << SCB_ICSR_VECTPENDING_Pos)          /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos             11                                             /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk             (1UL << SCB_ICSR_RETTOBASE_Pos)                /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos             0                                             /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos)           /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#if (__CM3_REV < 0x0201)                   /* core r2p1 */
+#define SCB_VTOR_TBLBASE_Pos               29                                             /*!< SCB VTOR: TBLBASE Position */
+#define SCB_VTOR_TBLBASE_Msk               (1UL << SCB_VTOR_TBLBASE_Pos)                  /*!< SCB VTOR: TBLBASE Mask */
+
+#define SCB_VTOR_TBLOFF_Pos                 7                                             /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos)            /*!< SCB VTOR: TBLOFF Mask */
+#else
+#define SCB_VTOR_TBLOFF_Pos                 7                                             /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk                (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos)           /*!< SCB VTOR: TBLOFF Mask */
+#endif
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos              16                                             /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos)            /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos          16                                             /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos)        /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos            15                                             /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk            (1UL << SCB_AIRCR_ENDIANESS_Pos)               /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos              8                                             /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk             (7UL << SCB_AIRCR_PRIGROUP_Pos)                /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos           2                                             /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk          (1UL << SCB_AIRCR_SYSRESETREQ_Pos)             /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos         1                                             /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos)           /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos             0                                             /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk            (1UL << SCB_AIRCR_VECTRESET_Pos)               /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos               4                                             /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk              (1UL << SCB_SCR_SEVONPEND_Pos)                 /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos               2                                             /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk              (1UL << SCB_SCR_SLEEPDEEP_Pos)                 /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos             1                                             /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk            (1UL << SCB_SCR_SLEEPONEXIT_Pos)               /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos                9                                             /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk               (1UL << SCB_CCR_STKALIGN_Pos)                  /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos               8                                             /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk              (1UL << SCB_CCR_BFHFNMIGN_Pos)                 /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos               4                                             /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk              (1UL << SCB_CCR_DIV_0_TRP_Pos)                 /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos             3                                             /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk            (1UL << SCB_CCR_UNALIGN_TRP_Pos)               /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos            1                                             /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk           (1UL << SCB_CCR_USERSETMPEND_Pos)              /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos          0                                             /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk         (1UL << SCB_CCR_NONBASETHRDENA_Pos)            /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos          18                                             /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk          (1UL << SCB_SHCSR_USGFAULTENA_Pos)             /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos          17                                             /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk          (1UL << SCB_SHCSR_BUSFAULTENA_Pos)             /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos          16                                             /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk          (1UL << SCB_SHCSR_MEMFAULTENA_Pos)             /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos         15                                             /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk         (1UL << SCB_SHCSR_SVCALLPENDED_Pos)            /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos       14                                             /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk       (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos)          /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos       13                                             /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk       (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos)          /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos       12                                             /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk       (1UL << SCB_SHCSR_USGFAULTPENDED_Pos)          /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos           11                                             /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk           (1UL << SCB_SHCSR_SYSTICKACT_Pos)              /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos            10                                             /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk            (1UL << SCB_SHCSR_PENDSVACT_Pos)               /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos            8                                             /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk           (1UL << SCB_SHCSR_MONITORACT_Pos)              /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos             7                                             /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk            (1UL << SCB_SHCSR_SVCALLACT_Pos)               /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos           3                                             /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk          (1UL << SCB_SHCSR_USGFAULTACT_Pos)             /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos           1                                             /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk          (1UL << SCB_SHCSR_BUSFAULTACT_Pos)             /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos           0                                             /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk          (1UL << SCB_SHCSR_MEMFAULTACT_Pos)             /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Registers Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos            16                                             /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk            (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos)          /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos             8                                             /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk            (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos)            /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos             0                                             /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk            (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos)            /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Registers Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos              31                                             /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk              (1UL << SCB_HFSR_DEBUGEVT_Pos)                 /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos                30                                             /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk                (1UL << SCB_HFSR_FORCED_Pos)                   /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos                1                                             /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk               (1UL << SCB_HFSR_VECTTBL_Pos)                  /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos               4                                             /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk              (1UL << SCB_DFSR_EXTERNAL_Pos)                 /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos                 3                                             /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk                (1UL << SCB_DFSR_VCATCH_Pos)                   /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos                2                                             /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk               (1UL << SCB_DFSR_DWTTRAP_Pos)                  /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos                   1                                             /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk                  (1UL << SCB_DFSR_BKPT_Pos)                     /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos                 0                                             /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk                (1UL << SCB_DFSR_HALTED_Pos)                   /*!< SCB DFSR: HALTED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+    \brief      Type definitions for the System Control and ID Register not in the SCB
+  @{
+ */
+
+/** \brief  Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+       uint32_t RESERVED0[1];
+  __I  uint32_t ICTR;                    /*!< Offset: 0x004 (R/ )  Interrupt Controller Type Register      */
+#if ((defined __CM3_REV) && (__CM3_REV >= 0x200))
+  __IO uint32_t ACTLR;                   /*!< Offset: 0x008 (R/W)  Auxiliary Control Register      */
+#else
+       uint32_t RESERVED1[1];
+#endif
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos         0                                          /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk        (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos)      /*!< ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+
+#define SCnSCB_ACTLR_DISFOLD_Pos            2                                          /*!< ACTLR: DISFOLD Position */
+#define SCnSCB_ACTLR_DISFOLD_Msk           (1UL << SCnSCB_ACTLR_DISFOLD_Pos)           /*!< ACTLR: DISFOLD Mask */
+
+#define SCnSCB_ACTLR_DISDEFWBUF_Pos         1                                          /*!< ACTLR: DISDEFWBUF Position */
+#define SCnSCB_ACTLR_DISDEFWBUF_Msk        (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos)        /*!< ACTLR: DISDEFWBUF Mask */
+
+#define SCnSCB_ACTLR_DISMCYCINT_Pos         0                                          /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk        (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos)        /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_SysTick     System Tick Timer (SysTick)
+    \brief      Type definitions for the System Timer Registers.
+  @{
+ */
+
+/** \brief  Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+  __IO uint32_t CTRL;                    /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
+  __IO uint32_t LOAD;                    /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register       */
+  __IO uint32_t VAL;                     /*!< Offset: 0x008 (R/W)  SysTick Current Value Register      */
+  __I  uint32_t CALIB;                   /*!< Offset: 0x00C (R/ )  SysTick Calibration Register        */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos         16                                             /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk         (1UL << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk         (1UL << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos            1                                             /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk           (1UL << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos             0                                             /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk            (1UL << SysTick_CTRL_ENABLE_Pos)               /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos             0                                             /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos)        /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos             0                                             /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos)        /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos            31                                             /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk            (1UL << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos             30                                             /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk             (1UL << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos             0                                             /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos)        /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_ITM     Instrumentation Trace Macrocell (ITM)
+    \brief      Type definitions for the Instrumentation Trace Macrocell (ITM)
+  @{
+ */
+
+/** \brief  Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+  __O  union
+  {
+    __O  uint8_t    u8;                  /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 8-bit                   */
+    __O  uint16_t   u16;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 16-bit                  */
+    __O  uint32_t   u32;                 /*!< Offset: 0x000 ( /W)  ITM Stimulus Port 32-bit                  */
+  }  PORT [32];                          /*!< Offset: 0x000 ( /W)  ITM Stimulus Port Registers               */
+       uint32_t RESERVED0[864];
+  __IO uint32_t TER;                     /*!< Offset: 0xE00 (R/W)  ITM Trace Enable Register                 */
+       uint32_t RESERVED1[15];
+  __IO uint32_t TPR;                     /*!< Offset: 0xE40 (R/W)  ITM Trace Privilege Register              */
+       uint32_t RESERVED2[15];
+  __IO uint32_t TCR;                     /*!< Offset: 0xE80 (R/W)  ITM Trace Control Register                */
+       uint32_t RESERVED3[29];
+  __O  uint32_t IWR;                     /*!< Offset: 0xEF8 ( /W)  ITM Integration Write Register            */
+  __I  uint32_t IRR;                     /*!< Offset: 0xEFC (R/ )  ITM Integration Read Register             */
+  __IO uint32_t IMCR;                    /*!< Offset: 0xF00 (R/W)  ITM Integration Mode Control Register     */
+       uint32_t RESERVED4[43];
+  __O  uint32_t LAR;                     /*!< Offset: 0xFB0 ( /W)  ITM Lock Access Register                  */
+  __I  uint32_t LSR;                     /*!< Offset: 0xFB4 (R/ )  ITM Lock Status Register                  */
+       uint32_t RESERVED5[6];
+  __I  uint32_t PID4;                    /*!< Offset: 0xFD0 (R/ )  ITM Peripheral Identification Register #4 */
+  __I  uint32_t PID5;                    /*!< Offset: 0xFD4 (R/ )  ITM Peripheral Identification Register #5 */
+  __I  uint32_t PID6;                    /*!< Offset: 0xFD8 (R/ )  ITM Peripheral Identification Register #6 */
+  __I  uint32_t PID7;                    /*!< Offset: 0xFDC (R/ )  ITM Peripheral Identification Register #7 */
+  __I  uint32_t PID0;                    /*!< Offset: 0xFE0 (R/ )  ITM Peripheral Identification Register #0 */
+  __I  uint32_t PID1;                    /*!< Offset: 0xFE4 (R/ )  ITM Peripheral Identification Register #1 */
+  __I  uint32_t PID2;                    /*!< Offset: 0xFE8 (R/ )  ITM Peripheral Identification Register #2 */
+  __I  uint32_t PID3;                    /*!< Offset: 0xFEC (R/ )  ITM Peripheral Identification Register #3 */
+  __I  uint32_t CID0;                    /*!< Offset: 0xFF0 (R/ )  ITM Component  Identification Register #0 */
+  __I  uint32_t CID1;                    /*!< Offset: 0xFF4 (R/ )  ITM Component  Identification Register #1 */
+  __I  uint32_t CID2;                    /*!< Offset: 0xFF8 (R/ )  ITM Component  Identification Register #2 */
+  __I  uint32_t CID3;                    /*!< Offset: 0xFFC (R/ )  ITM Component  Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos                0                                             /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk               (0xFUL << ITM_TPR_PRIVMASK_Pos)                /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos                   23                                             /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk                   (1UL << ITM_TCR_BUSY_Pos)                      /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos             16                                             /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk             (0x7FUL << ITM_TCR_TraceBusID_Pos)             /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos                10                                             /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk                (3UL << ITM_TCR_GTSFREQ_Pos)                   /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos              8                                             /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk             (3UL << ITM_TCR_TSPrescale_Pos)                /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos                  4                                             /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk                 (1UL << ITM_TCR_SWOENA_Pos)                    /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos                  3                                             /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk                 (1UL << ITM_TCR_DWTENA_Pos)                    /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos                 2                                             /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk                (1UL << ITM_TCR_SYNCENA_Pos)                   /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos                   1                                             /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk                  (1UL << ITM_TCR_TSENA_Pos)                     /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos                  0                                             /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk                 (1UL << ITM_TCR_ITMENA_Pos)                    /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos                0                                             /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk               (1UL << ITM_IWR_ATVALIDM_Pos)                  /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos                0                                             /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk               (1UL << ITM_IRR_ATREADYM_Pos)                  /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos            0                                             /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk           (1UL << ITM_IMCR_INTEGRATION_Pos)              /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos                 2                                             /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk                (1UL << ITM_LSR_ByteAcc_Pos)                   /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos                  1                                             /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk                 (1UL << ITM_LSR_Access_Pos)                    /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos                 0                                             /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk                (1UL << ITM_LSR_Present_Pos)                   /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_DWT     Data Watchpoint and Trace (DWT)
+    \brief      Type definitions for the Data Watchpoint and Trace (DWT)
+  @{
+ */
+
+/** \brief  Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+  __IO uint32_t CTRL;                    /*!< Offset: 0x000 (R/W)  Control Register                          */
+  __IO uint32_t CYCCNT;                  /*!< Offset: 0x004 (R/W)  Cycle Count Register                      */
+  __IO uint32_t CPICNT;                  /*!< Offset: 0x008 (R/W)  CPI Count Register                        */
+  __IO uint32_t EXCCNT;                  /*!< Offset: 0x00C (R/W)  Exception Overhead Count Register         */
+  __IO uint32_t SLEEPCNT;                /*!< Offset: 0x010 (R/W)  Sleep Count Register                      */
+  __IO uint32_t LSUCNT;                  /*!< Offset: 0x014 (R/W)  LSU Count Register                        */
+  __IO uint32_t FOLDCNT;                 /*!< Offset: 0x018 (R/W)  Folded-instruction Count Register         */
+  __I  uint32_t PCSR;                    /*!< Offset: 0x01C (R/ )  Program Counter Sample Register           */
+  __IO uint32_t COMP0;                   /*!< Offset: 0x020 (R/W)  Comparator Register 0                     */
+  __IO uint32_t MASK0;                   /*!< Offset: 0x024 (R/W)  Mask Register 0                           */
+  __IO uint32_t FUNCTION0;               /*!< Offset: 0x028 (R/W)  Function Register 0                       */
+       uint32_t RESERVED0[1];
+  __IO uint32_t COMP1;                   /*!< Offset: 0x030 (R/W)  Comparator Register 1                     */
+  __IO uint32_t MASK1;                   /*!< Offset: 0x034 (R/W)  Mask Register 1                           */
+  __IO uint32_t FUNCTION1;               /*!< Offset: 0x038 (R/W)  Function Register 1                       */
+       uint32_t RESERVED1[1];
+  __IO uint32_t COMP2;                   /*!< Offset: 0x040 (R/W)  Comparator Register 2                     */
+  __IO uint32_t MASK2;                   /*!< Offset: 0x044 (R/W)  Mask Register 2                           */
+  __IO uint32_t FUNCTION2;               /*!< Offset: 0x048 (R/W)  Function Register 2                       */
+       uint32_t RESERVED2[1];
+  __IO uint32_t COMP3;                   /*!< Offset: 0x050 (R/W)  Comparator Register 3                     */
+  __IO uint32_t MASK3;                   /*!< Offset: 0x054 (R/W)  Mask Register 3                           */
+  __IO uint32_t FUNCTION3;               /*!< Offset: 0x058 (R/W)  Function Register 3                       */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos               28                                          /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk               (0xFUL << DWT_CTRL_NUMCOMP_Pos)             /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos              27                                          /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk              (0x1UL << DWT_CTRL_NOTRCPKT_Pos)            /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos             26                                          /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk             (0x1UL << DWT_CTRL_NOEXTTRIG_Pos)           /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos              25                                          /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk              (0x1UL << DWT_CTRL_NOCYCCNT_Pos)            /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos              24                                          /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk              (0x1UL << DWT_CTRL_NOPRFCNT_Pos)            /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos             22                                          /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk             (0x1UL << DWT_CTRL_CYCEVTENA_Pos)           /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos            21                                          /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk            (0x1UL << DWT_CTRL_FOLDEVTENA_Pos)          /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos             20                                          /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk             (0x1UL << DWT_CTRL_LSUEVTENA_Pos)           /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos           19                                          /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk           (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos)         /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos             18                                          /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk             (0x1UL << DWT_CTRL_EXCEVTENA_Pos)           /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos             17                                          /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk             (0x1UL << DWT_CTRL_CPIEVTENA_Pos)           /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos             16                                          /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk             (0x1UL << DWT_CTRL_EXCTRCENA_Pos)           /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos            12                                          /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk            (0x1UL << DWT_CTRL_PCSAMPLENA_Pos)          /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos               10                                          /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk               (0x3UL << DWT_CTRL_SYNCTAP_Pos)             /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos                 9                                          /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk                (0x1UL << DWT_CTRL_CYCTAP_Pos)              /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos               5                                          /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk              (0xFUL << DWT_CTRL_POSTINIT_Pos)            /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos             1                                          /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk            (0xFUL << DWT_CTRL_POSTPRESET_Pos)          /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos              0                                          /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk             (0x1UL << DWT_CTRL_CYCCNTENA_Pos)           /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos               0                                          /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk              (0xFFUL << DWT_CPICNT_CPICNT_Pos)           /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos               0                                          /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk              (0xFFUL << DWT_EXCCNT_EXCCNT_Pos)           /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos           0                                          /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk          (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos)       /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos               0                                          /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk              (0xFFUL << DWT_LSUCNT_LSUCNT_Pos)           /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos             0                                          /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk            (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos)         /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos                   0                                          /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk                  (0x1FUL << DWT_MASK_MASK_Pos)               /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos           24                                          /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk           (0x1UL << DWT_FUNCTION_MATCHED_Pos)         /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos        16                                          /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos)      /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos        12                                          /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk        (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos)      /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos         10                                          /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk         (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos)       /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos            9                                          /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk           (0x1UL << DWT_FUNCTION_LNK1ENA_Pos)         /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos         8                                          /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk        (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos)      /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos           7                                          /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk          (0x1UL << DWT_FUNCTION_CYCMATCH_Pos)        /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos          5                                          /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk         (0x1UL << DWT_FUNCTION_EMITRANGE_Pos)       /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos           0                                          /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk          (0xFUL << DWT_FUNCTION_FUNCTION_Pos)        /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_TPI     Trace Port Interface (TPI)
+    \brief      Type definitions for the Trace Port Interface (TPI)
+  @{
+ */
+
+/** \brief  Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+  __IO uint32_t SSPSR;                   /*!< Offset: 0x000 (R/ )  Supported Parallel Port Size Register     */
+  __IO uint32_t CSPSR;                   /*!< Offset: 0x004 (R/W)  Current Parallel Port Size Register */
+       uint32_t RESERVED0[2];
+  __IO uint32_t ACPR;                    /*!< Offset: 0x010 (R/W)  Asynchronous Clock Prescaler Register */
+       uint32_t RESERVED1[55];
+  __IO uint32_t SPPR;                    /*!< Offset: 0x0F0 (R/W)  Selected Pin Protocol Register */
+       uint32_t RESERVED2[131];
+  __I  uint32_t FFSR;                    /*!< Offset: 0x300 (R/ )  Formatter and Flush Status Register */
+  __IO uint32_t FFCR;                    /*!< Offset: 0x304 (R/W)  Formatter and Flush Control Register */
+  __I  uint32_t FSCR;                    /*!< Offset: 0x308 (R/ )  Formatter Synchronization Counter Register */
+       uint32_t RESERVED3[759];
+  __I  uint32_t TRIGGER;                 /*!< Offset: 0xEE8 (R/ )  TRIGGER */
+  __I  uint32_t FIFO0;                   /*!< Offset: 0xEEC (R/ )  Integration ETM Data */
+  __I  uint32_t ITATBCTR2;               /*!< Offset: 0xEF0 (R/ )  ITATBCTR2 */
+       uint32_t RESERVED4[1];
+  __I  uint32_t ITATBCTR0;               /*!< Offset: 0xEF8 (R/ )  ITATBCTR0 */
+  __I  uint32_t FIFO1;                   /*!< Offset: 0xEFC (R/ )  Integration ITM Data */
+  __IO uint32_t ITCTRL;                  /*!< Offset: 0xF00 (R/W)  Integration Mode Control */
+       uint32_t RESERVED5[39];
+  __IO uint32_t CLAIMSET;                /*!< Offset: 0xFA0 (R/W)  Claim tag set */
+  __IO uint32_t CLAIMCLR;                /*!< Offset: 0xFA4 (R/W)  Claim tag clear */
+       uint32_t RESERVED7[8];
+  __I  uint32_t DEVID;                   /*!< Offset: 0xFC8 (R/ )  TPIU_DEVID */
+  __I  uint32_t DEVTYPE;                 /*!< Offset: 0xFCC (R/ )  TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos              0                                          /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk             (0x1FFFUL << TPI_ACPR_PRESCALER_Pos)        /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos                 0                                          /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk                (0x3UL << TPI_SPPR_TXMODE_Pos)              /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos              3                                          /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk             (0x1UL << TPI_FFSR_FtNonStop_Pos)           /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos              2                                          /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk             (0x1UL << TPI_FFSR_TCPresent_Pos)           /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos              1                                          /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk             (0x1UL << TPI_FFSR_FtStopped_Pos)           /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos               0                                          /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk              (0x1UL << TPI_FFSR_FlInProg_Pos)            /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos                 8                                          /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk                (0x1UL << TPI_FFCR_TrigIn_Pos)              /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos                1                                          /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk               (0x1UL << TPI_FFCR_EnFCont_Pos)             /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos             0                                          /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk            (0x1UL << TPI_TRIGGER_TRIGGER_Pos)          /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos          29                                          /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos)        /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos        27                                          /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk        (0x3UL << TPI_FIFO0_ITM_bytecount_Pos)      /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos          26                                          /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos)        /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos        24                                          /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk        (0x3UL << TPI_FIFO0_ETM_bytecount_Pos)      /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos                 16                                          /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk                 (0xFFUL << TPI_FIFO0_ETM2_Pos)              /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos                  8                                          /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk                 (0xFFUL << TPI_FIFO0_ETM1_Pos)              /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos                  0                                          /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk                 (0xFFUL << TPI_FIFO0_ETM0_Pos)              /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY_Pos           0                                          /*!< TPI ITATBCTR2: ATREADY Position */
+#define TPI_ITATBCTR2_ATREADY_Msk          (0x1UL << TPI_ITATBCTR2_ATREADY_Pos)        /*!< TPI ITATBCTR2: ATREADY Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos          29                                          /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos)        /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos        27                                          /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk        (0x3UL << TPI_FIFO1_ITM_bytecount_Pos)      /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos          26                                          /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk          (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos)        /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos        24                                          /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk        (0x3UL << TPI_FIFO1_ETM_bytecount_Pos)      /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos                 16                                          /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk                 (0xFFUL << TPI_FIFO1_ITM2_Pos)              /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos                  8                                          /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk                 (0xFFUL << TPI_FIFO1_ITM1_Pos)              /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos                  0                                          /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk                 (0xFFUL << TPI_FIFO1_ITM0_Pos)              /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY_Pos           0                                          /*!< TPI ITATBCTR0: ATREADY Position */
+#define TPI_ITATBCTR0_ATREADY_Msk          (0x1UL << TPI_ITATBCTR0_ATREADY_Pos)        /*!< TPI ITATBCTR0: ATREADY Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos                 0                                          /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk                (0x1UL << TPI_ITCTRL_Mode_Pos)              /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos             11                                          /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk             (0x1UL << TPI_DEVID_NRZVALID_Pos)           /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos            10                                          /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk            (0x1UL << TPI_DEVID_MANCVALID_Pos)          /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos             9                                          /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk            (0x1UL << TPI_DEVID_PTINVALID_Pos)          /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos              6                                          /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk             (0x7UL << TPI_DEVID_MinBufSz_Pos)           /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos             5                                          /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk            (0x1UL << TPI_DEVID_AsynClkIn_Pos)          /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos          0                                          /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk         (0x1FUL << TPI_DEVID_NrTraceInput_Pos)      /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_SubType_Pos             0                                          /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk            (0xFUL << TPI_DEVTYPE_SubType_Pos)          /*!< TPI DEVTYPE: SubType Mask */
+
+#define TPI_DEVTYPE_MajorType_Pos           4                                          /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk          (0xFUL << TPI_DEVTYPE_MajorType_Pos)        /*!< TPI DEVTYPE: MajorType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if (__MPU_PRESENT == 1)
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_MPU     Memory Protection Unit (MPU)
+    \brief      Type definitions for the Memory Protection Unit (MPU)
+  @{
+ */
+
+/** \brief  Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+  __I  uint32_t TYPE;                    /*!< Offset: 0x000 (R/ )  MPU Type Register                              */
+  __IO uint32_t CTRL;                    /*!< Offset: 0x004 (R/W)  MPU Control Register                           */
+  __IO uint32_t RNR;                     /*!< Offset: 0x008 (R/W)  MPU Region RNRber Register                     */
+  __IO uint32_t RBAR;                    /*!< Offset: 0x00C (R/W)  MPU Region Base Address Register               */
+  __IO uint32_t RASR;                    /*!< Offset: 0x010 (R/W)  MPU Region Attribute and Size Register         */
+  __IO uint32_t RBAR_A1;                 /*!< Offset: 0x014 (R/W)  MPU Alias 1 Region Base Address Register       */
+  __IO uint32_t RASR_A1;                 /*!< Offset: 0x018 (R/W)  MPU Alias 1 Region Attribute and Size Register */
+  __IO uint32_t RBAR_A2;                 /*!< Offset: 0x01C (R/W)  MPU Alias 2 Region Base Address Register       */
+  __IO uint32_t RASR_A2;                 /*!< Offset: 0x020 (R/W)  MPU Alias 2 Region Attribute and Size Register */
+  __IO uint32_t RBAR_A3;                 /*!< Offset: 0x024 (R/W)  MPU Alias 3 Region Base Address Register       */
+  __IO uint32_t RASR_A3;                 /*!< Offset: 0x028 (R/W)  MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register */
+#define MPU_TYPE_IREGION_Pos               16                                             /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk               (0xFFUL << MPU_TYPE_IREGION_Pos)               /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos                8                                             /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk               (0xFFUL << MPU_TYPE_DREGION_Pos)               /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos               0                                             /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk              (1UL << MPU_TYPE_SEPARATE_Pos)                 /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register */
+#define MPU_CTRL_PRIVDEFENA_Pos             2                                             /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk            (1UL << MPU_CTRL_PRIVDEFENA_Pos)               /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos               1                                             /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk              (1UL << MPU_CTRL_HFNMIENA_Pos)                 /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos                 0                                             /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk                (1UL << MPU_CTRL_ENABLE_Pos)                   /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register */
+#define MPU_RNR_REGION_Pos                  0                                             /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk                 (0xFFUL << MPU_RNR_REGION_Pos)                 /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register */
+#define MPU_RBAR_ADDR_Pos                   5                                             /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk                  (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos)             /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos                  4                                             /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk                 (1UL << MPU_RBAR_VALID_Pos)                    /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos                 0                                             /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk                (0xFUL << MPU_RBAR_REGION_Pos)                 /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register */
+#define MPU_RASR_ATTRS_Pos                 16                                             /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos                    28                                             /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk                    (1UL << MPU_RASR_XN_Pos)                       /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos                    24                                             /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk                    (0x7UL << MPU_RASR_AP_Pos)                     /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19                                             /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk                   (0x7UL << MPU_RASR_TEX_Pos)                    /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos                     18                                             /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk                     (1UL << MPU_RASR_S_Pos)                        /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos                     17                                             /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk                     (1UL << MPU_RASR_C_Pos)                        /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos                     16                                             /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk                     (1UL << MPU_RASR_B_Pos)                        /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos                    8                                             /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos                   1                                             /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk                  (0x1FUL << MPU_RASR_SIZE_Pos)                  /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos                 0                                             /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk                (1UL << MPU_RASR_ENABLE_Pos)                   /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/** \ingroup  CMSIS_core_register
+    \defgroup CMSIS_CoreDebug       Core Debug Registers (CoreDebug)
+    \brief      Type definitions for the Core Debug Registers
+  @{
+ */
+
+/** \brief  Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+  __IO uint32_t DHCSR;                   /*!< Offset: 0x000 (R/W)  Debug Halting Control and Status Register    */
+  __O  uint32_t DCRSR;                   /*!< Offset: 0x004 ( /W)  Debug Core Register Selector Register        */
+  __IO uint32_t DCRDR;                   /*!< Offset: 0x008 (R/W)  Debug Core Register Data Register            */
+  __IO uint32_t DEMCR;                   /*!< Offset: 0x00C (R/W)  Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register */
+#define CoreDebug_DHCSR_DBGKEY_Pos         16                                             /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk         (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos)       /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos     25                                             /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk     (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos)        /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos    24                                             /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk    (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos)       /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos       19                                             /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk       (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos)          /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos        18                                             /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk        (1UL << CoreDebug_DHCSR_S_SLEEP_Pos)           /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos         17                                             /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk         (1UL << CoreDebug_DHCSR_S_HALT_Pos)            /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos       16                                             /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk       (1UL << CoreDebug_DHCSR_S_REGRDY_Pos)          /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos     5                                             /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk    (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos)       /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos      3                                             /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk     (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos)        /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos          2                                             /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk         (1UL << CoreDebug_DHCSR_C_STEP_Pos)            /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos          1                                             /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk         (1UL << CoreDebug_DHCSR_C_HALT_Pos)            /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos       0                                             /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk      (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos)         /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register */
+#define CoreDebug_DCRSR_REGWnR_Pos         16                                             /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk         (1UL << CoreDebug_DCRSR_REGWnR_Pos)            /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos          0                                             /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk         (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos)         /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register */
+#define CoreDebug_DEMCR_TRCENA_Pos         24                                             /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk         (1UL << CoreDebug_DEMCR_TRCENA_Pos)            /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos        19                                             /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk        (1UL << CoreDebug_DEMCR_MON_REQ_Pos)           /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos       18                                             /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk       (1UL << CoreDebug_DEMCR_MON_STEP_Pos)          /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos       17                                             /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk       (1UL << CoreDebug_DEMCR_MON_PEND_Pos)          /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos         16                                             /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk         (1UL << CoreDebug_DEMCR_MON_EN_Pos)            /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos     10                                             /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk     (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos)        /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos       9                                             /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk      (1UL << CoreDebug_DEMCR_VC_INTERR_Pos)         /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos       8                                             /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk      (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos)         /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos      7                                             /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk     (1UL << CoreDebug_DEMCR_VC_STATERR_Pos)        /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos       6                                             /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk      (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos)         /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos      5                                             /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk     (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos)        /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos        4                                             /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk       (1UL << CoreDebug_DEMCR_VC_MMERR_Pos)          /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos    0                                             /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk   (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos)      /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/** \ingroup    CMSIS_core_register
+    \defgroup   CMSIS_core_base     Core Definitions
+    \brief      Definitions for base addresses, unions, and structures.
+  @{
+ */
+
+/* Memory mapping of Cortex-M3 Hardware */
+#define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address  */
+#define ITM_BASE            (0xE0000000UL)                            /*!< ITM Base Address                   */
+#define DWT_BASE            (0xE0001000UL)                            /*!< DWT Base Address                   */
+#define TPI_BASE            (0xE0040000UL)                            /*!< TPI Base Address                   */
+#define CoreDebug_BASE      (0xE000EDF0UL)                            /*!< Core Debug Base Address            */
+#define SysTick_BASE        (SCS_BASE +  0x0010UL)                    /*!< SysTick Base Address               */
+#define NVIC_BASE           (SCS_BASE +  0x0100UL)                    /*!< NVIC Base Address                  */
+#define SCB_BASE            (SCS_BASE +  0x0D00UL)                    /*!< System Control Block Base Address  */
+
+#define SCnSCB              ((SCnSCB_Type    *)     SCS_BASE      )   /*!< System control Register not in SCB */
+#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct           */
+#define SysTick             ((SysTick_Type   *)     SysTick_BASE  )   /*!< SysTick configuration struct       */
+#define NVIC                ((NVIC_Type      *)     NVIC_BASE     )   /*!< NVIC configuration struct          */
+#define ITM                 ((ITM_Type       *)     ITM_BASE      )   /*!< ITM configuration struct           */
+#define DWT                 ((DWT_Type       *)     DWT_BASE      )   /*!< DWT configuration struct           */
+#define TPI                 ((TPI_Type       *)     TPI_BASE      )   /*!< TPI configuration struct           */
+#define CoreDebug           ((CoreDebug_Type *)     CoreDebug_BASE)   /*!< Core Debug configuration struct    */
+
+#if (__MPU_PRESENT == 1)
+  #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit             */
+  #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit             */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ *                Hardware Abstraction Layer
+  Core Function Interface contains:
+  - Core NVIC Functions
+  - Core SysTick Functions
+  - Core Debug Functions
+  - Core Register Access Functions
+ ******************************************************************************/
+/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ##########################   NVIC functions  #################################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+    \brief      Functions that manage interrupts and exceptions via the NVIC.
+    @{
+ */
+
+/** \brief  Set Priority Grouping
+
+  The function sets the priority grouping field using the required unlock sequence.
+  The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+  Only values from 0..7 are used.
+  In case of a conflict between priority grouping and available
+  priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+
+    \param [in]      PriorityGroup  Priority grouping field.
+ */
+__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+  uint32_t reg_value;
+  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07);               /* only values 0..7 are used          */
+
+  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
+  reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk);             /* clear bits to change               */
+  reg_value  =  (reg_value                                 |
+                ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) |
+                (PriorityGroupTmp << 8));                                     /* Insert write key and priorty group */
+  SCB->AIRCR =  reg_value;
+}
+
+
+/** \brief  Get Priority Grouping
+
+  The function reads the priority grouping field from the NVIC Interrupt Controller.
+
+    \return                Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+  return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos);   /* read priority grouping field */
+}
+
+
+/** \brief  Enable External Interrupt
+
+    The function enables a device-specific interrupt in the NVIC interrupt controller.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */
+}
+
+
+/** \brief  Disable External Interrupt
+
+    The function disables a device-specific interrupt in the NVIC interrupt controller.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */
+}
+
+
+/** \brief  Get Pending Interrupt
+
+    The function reads the pending register in the NVIC and returns the pending bit
+    for the specified interrupt.
+
+    \param [in]      IRQn  Interrupt number.
+
+    \return             0  Interrupt status is not pending.
+    \return             1  Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+  return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */
+}
+
+
+/** \brief  Set Pending Interrupt
+
+    The function sets the pending bit of an external interrupt.
+
+    \param [in]      IRQn  Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */
+}
+
+
+/** \brief  Clear Pending Interrupt
+
+    The function clears the pending bit of an external interrupt.
+
+    \param [in]      IRQn  External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+  NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
+}
+
+
+/** \brief  Get Active Interrupt
+
+    The function reads the active register in NVIC and returns the active bit.
+
+    \param [in]      IRQn  Interrupt number.
+
+    \return             0  Interrupt status is not active.
+    \return             1  Interrupt status is active.
+ */
+__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+  return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */
+}
+
+
+/** \brief  Set Interrupt Priority
+
+    The function sets the priority of an interrupt.
+
+    \note The priority cannot be set for every core interrupt.
+
+    \param [in]      IRQn  Interrupt number.
+    \param [in]  priority  Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  if(IRQn < 0) {
+    SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M  System Interrupts */
+  else {
+    NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        /* set Priority for device specific Interrupts  */
+}
+
+
+/** \brief  Get Interrupt Priority
+
+    The function reads the priority of an interrupt. The interrupt
+    number can be positive to specify an external (device specific)
+    interrupt, or negative to specify an internal (core) interrupt.
+
+
+    \param [in]   IRQn  Interrupt number.
+    \return             Interrupt Priority. Value is aligned automatically to the implemented
+                        priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+  if(IRQn < 0) {
+    return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for Cortex-M  system interrupts */
+  else {
+    return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)]           >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for device specific interrupts  */
+}
+
+
+/** \brief  Encode Priority
+
+    The function encodes the priority for an interrupt with the given priority group,
+    preemptive priority value, and subpriority value.
+    In case of a conflict between priority grouping and available
+    priority bits (__NVIC_PRIO_BITS), the samllest possible priority group is set.
+
+    \param [in]     PriorityGroup  Used priority group.
+    \param [in]   PreemptPriority  Preemptive priority value (starting from 0).
+    \param [in]       SubPriority  Subpriority value (starting from 0).
+    \return                        Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);          /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+  return (
+           ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |
+           ((SubPriority     & ((1 << (SubPriorityBits    )) - 1)))
+         );
+}
+
+
+/** \brief  Decode Priority
+
+    The function decodes an interrupt priority value with a given priority group to
+    preemptive priority value and subpriority value.
+    In case of a conflict between priority grouping and available
+    priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
+
+    \param [in]         Priority   Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+    \param [in]     PriorityGroup  Used priority group.
+    \param [out] pPreemptPriority  Preemptive priority value (starting from 0).
+    \param [out]     pSubPriority  Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)
+{
+  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);          /* only values 0..7 are used          */
+  uint32_t PreemptPriorityBits;
+  uint32_t SubPriorityBits;
+
+  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+  *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);
+  *pSubPriority     = (Priority                   ) & ((1 << (SubPriorityBits    )) - 1);
+}
+
+
+/** \brief  System Reset
+
+    The function initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+  __DSB();                                                     /* Ensure all outstanding memory accesses included
+                                                                  buffered write are completed before reset */
+  SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      |
+                 (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+                 SCB_AIRCR_SYSRESETREQ_Msk);                   /* Keep priority group unchanged */
+  __DSB();                                                     /* Ensure completion of memory access */
+  while(1);                                                    /* wait until reset */
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ##################################    SysTick function  ############################################ */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+    \brief      Functions that configure the System.
+  @{
+ */
+
+#if (__Vendor_SysTickConfig == 0)
+
+/** \brief  System Tick Configuration
+
+    The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
+    Counter is in free running mode to generate periodic interrupts.
+
+    \param [in]  ticks  Number of ticks between two interrupts.
+
+    \return          0  Function succeeded.
+    \return          1  Function failed.
+
+    \note     When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+    function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+    must contain a vendor-specific implementation of this function.
+
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+  if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk)  return (1);      /* Reload value impossible */
+
+  SysTick->LOAD  = ticks - 1;                                  /* set reload register */
+  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Systick Interrupt */
+  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
+  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
+                   SysTick_CTRL_TICKINT_Msk   |
+                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
+  return (0);                                                  /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_core_DebugFunctions ITM Functions
+    \brief   Functions that access the ITM debug interface.
+  @{
+ */
+
+extern volatile int32_t ITM_RxBuffer;                    /*!< External variable to receive characters.                         */
+#define                 ITM_RXBUFFER_EMPTY    0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/** \brief  ITM Send Character
+
+    The function transmits a character via the ITM channel 0, and
+    \li Just returns when no debugger is connected that has booked the output.
+    \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+
+    \param [in]     ch  Character to transmit.
+
+    \returns            Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+  if ((ITM->TCR & ITM_TCR_ITMENA_Msk)                  &&      /* ITM enabled */
+      (ITM->TER & (1UL << 0)        )                    )     /* ITM Port #0 enabled */
+  {
+    while (ITM->PORT[0].u32 == 0);
+    ITM->PORT[0].u8 = (uint8_t) ch;
+  }
+  return (ch);
+}
+
+
+/** \brief  ITM Receive Character
+
+    The function inputs a character via the external variable \ref ITM_RxBuffer.
+
+    \return             Received character.
+    \return         -1  No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void) {
+  int32_t ch = -1;                           /* no character available */
+
+  if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) {
+    ch = ITM_RxBuffer;
+    ITM_RxBuffer = ITM_RXBUFFER_EMPTY;       /* ready for next character */
+  }
+
+  return (ch);
+}
+
+
+/** \brief  ITM Check Character
+
+    The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+
+    \return          0  No character available.
+    \return          1  Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void) {
+
+  if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) {
+    return (0);                                 /* no character available */
+  } else {
+    return (1);                                 /*    character available */
+  }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+#endif /* __CORE_CM3_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/reform2-lpc-fw/cmsis/core_cmFunc.h b/reform2-lpc-fw/cmsis/core_cmFunc.h
new file mode 100644
index 0000000000000000000000000000000000000000..0a18fafc301e003d348edf5cae39481d8e5fe7c3
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/core_cmFunc.h
@@ -0,0 +1,636 @@
+/**************************************************************************//**
+ * @file     core_cmFunc.h
+ * @brief    CMSIS Cortex-M Core Function Access Header File
+ * @version  V3.20
+ * @date     25. February 2013
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2013 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+
+#ifndef __CORE_CMFUNC_H
+#define __CORE_CMFUNC_H
+
+
+/* ###########################  Core Function Access  ########################### */
+/** \ingroup  CMSIS_Core_FunctionInterface
+    \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+  @{
+ */
+
+#if   defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+#if (__ARMCC_VERSION < 400677)
+  #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
+#endif
+
+/* intrinsic void __enable_irq();     */
+/* intrinsic void __disable_irq();    */
+
+/** \brief  Get Control Register
+
+    This function returns the content of the Control Register.
+
+    \return               Control Register value
+ */
+__STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+  register uint32_t __regControl         __ASM("control");
+  return(__regControl);
+}
+
+
+/** \brief  Set Control Register
+
+    This function writes the given value to the Control Register.
+
+    \param [in]    control  Control Register value to set
+ */
+__STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+  register uint32_t __regControl         __ASM("control");
+  __regControl = control;
+}
+
+
+/** \brief  Get IPSR Register
+
+    This function returns the content of the IPSR Register.
+
+    \return               IPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_IPSR(void)
+{
+  register uint32_t __regIPSR          __ASM("ipsr");
+  return(__regIPSR);
+}
+
+
+/** \brief  Get APSR Register
+
+    This function returns the content of the APSR Register.
+
+    \return               APSR Register value
+ */
+__STATIC_INLINE uint32_t __get_APSR(void)
+{
+  register uint32_t __regAPSR          __ASM("apsr");
+  return(__regAPSR);
+}
+
+
+/** \brief  Get xPSR Register
+
+    This function returns the content of the xPSR Register.
+
+    \return               xPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_xPSR(void)
+{
+  register uint32_t __regXPSR          __ASM("xpsr");
+  return(__regXPSR);
+}
+
+
+/** \brief  Get Process Stack Pointer
+
+    This function returns the current value of the Process Stack Pointer (PSP).
+
+    \return               PSP Register value
+ */
+__STATIC_INLINE uint32_t __get_PSP(void)
+{
+  register uint32_t __regProcessStackPointer  __ASM("psp");
+  return(__regProcessStackPointer);
+}
+
+
+/** \brief  Set Process Stack Pointer
+
+    This function assigns the given value to the Process Stack Pointer (PSP).
+
+    \param [in]    topOfProcStack  Process Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+  register uint32_t __regProcessStackPointer  __ASM("psp");
+  __regProcessStackPointer = topOfProcStack;
+}
+
+
+/** \brief  Get Main Stack Pointer
+
+    This function returns the current value of the Main Stack Pointer (MSP).
+
+    \return               MSP Register value
+ */
+__STATIC_INLINE uint32_t __get_MSP(void)
+{
+  register uint32_t __regMainStackPointer     __ASM("msp");
+  return(__regMainStackPointer);
+}
+
+
+/** \brief  Set Main Stack Pointer
+
+    This function assigns the given value to the Main Stack Pointer (MSP).
+
+    \param [in]    topOfMainStack  Main Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+  register uint32_t __regMainStackPointer     __ASM("msp");
+  __regMainStackPointer = topOfMainStack;
+}
+
+
+/** \brief  Get Priority Mask
+
+    This function returns the current state of the priority mask bit from the Priority Mask Register.
+
+    \return               Priority Mask value
+ */
+__STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+  register uint32_t __regPriMask         __ASM("primask");
+  return(__regPriMask);
+}
+
+
+/** \brief  Set Priority Mask
+
+    This function assigns the given value to the Priority Mask Register.
+
+    \param [in]    priMask  Priority Mask
+ */
+__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+  register uint32_t __regPriMask         __ASM("primask");
+  __regPriMask = (priMask);
+}
+
+
+#if       (__CORTEX_M >= 0x03)
+
+/** \brief  Enable FIQ
+
+    This function enables FIQ interrupts by clearing the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+#define __enable_fault_irq                __enable_fiq
+
+
+/** \brief  Disable FIQ
+
+    This function disables FIQ interrupts by setting the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+#define __disable_fault_irq               __disable_fiq
+
+
+/** \brief  Get Base Priority
+
+    This function returns the current value of the Base Priority register.
+
+    \return               Base Priority register value
+ */
+__STATIC_INLINE uint32_t  __get_BASEPRI(void)
+{
+  register uint32_t __regBasePri         __ASM("basepri");
+  return(__regBasePri);
+}
+
+
+/** \brief  Set Base Priority
+
+    This function assigns the given value to the Base Priority register.
+
+    \param [in]    basePri  Base Priority value to set
+ */
+__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
+{
+  register uint32_t __regBasePri         __ASM("basepri");
+  __regBasePri = (basePri & 0xff);
+}
+
+
+/** \brief  Get Fault Mask
+
+    This function returns the current value of the Fault Mask register.
+
+    \return               Fault Mask register value
+ */
+__STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+  register uint32_t __regFaultMask       __ASM("faultmask");
+  return(__regFaultMask);
+}
+
+
+/** \brief  Set Fault Mask
+
+    This function assigns the given value to the Fault Mask register.
+
+    \param [in]    faultMask  Fault Mask value to set
+ */
+__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+  register uint32_t __regFaultMask       __ASM("faultmask");
+  __regFaultMask = (faultMask & (uint32_t)1);
+}
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+#if       (__CORTEX_M == 0x04)
+
+/** \brief  Get FPSCR
+
+    This function returns the current value of the Floating Point Status/Control register.
+
+    \return               Floating Point Status/Control register value
+ */
+__STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+  register uint32_t __regfpscr         __ASM("fpscr");
+  return(__regfpscr);
+#else
+   return(0);
+#endif
+}
+
+
+/** \brief  Set FPSCR
+
+    This function assigns the given value to the Floating Point Status/Control register.
+
+    \param [in]    fpscr  Floating Point Status/Control value to set
+ */
+__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+  register uint32_t __regfpscr         __ASM("fpscr");
+  __regfpscr = (fpscr);
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04) */
+
+
+#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+
+#include <cmsis_iar.h>
+
+
+#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
+/* TI CCS specific functions */
+
+#include <cmsis_ccs.h>
+
+
+#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+
+/** \brief  Enable IRQ Interrupts
+
+  This function enables IRQ interrupts by clearing the I-bit in the CPSR.
+  Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
+{
+  __ASM volatile ("cpsie i" : : : "memory");
+}
+
+
+/** \brief  Disable IRQ Interrupts
+
+  This function disables IRQ interrupts by setting the I-bit in the CPSR.
+  Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
+{
+  __ASM volatile ("cpsid i" : : : "memory");
+}
+
+
+/** \brief  Get Control Register
+
+    This function returns the content of the Control Register.
+
+    \return               Control Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, control" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Control Register
+
+    This function writes the given value to the Control Register.
+
+    \param [in]    control  Control Register value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+  __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
+}
+
+
+/** \brief  Get IPSR Register
+
+    This function returns the content of the IPSR Register.
+
+    \return               IPSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Get APSR Register
+
+    This function returns the content of the APSR Register.
+
+    \return               APSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, apsr" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Get xPSR Register
+
+    This function returns the content of the xPSR Register.
+
+    \return               xPSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Get Process Stack Pointer
+
+    This function returns the current value of the Process Stack Pointer (PSP).
+
+    \return               PSP Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, psp\n"  : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Process Stack Pointer
+
+    This function assigns the given value to the Process Stack Pointer (PSP).
+
+    \param [in]    topOfProcStack  Process Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+  __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
+}
+
+
+/** \brief  Get Main Stack Pointer
+
+    This function returns the current value of the Main Stack Pointer (MSP).
+
+    \return               MSP Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
+{
+  register uint32_t result;
+
+  __ASM volatile ("MRS %0, msp\n" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Main Stack Pointer
+
+    This function assigns the given value to the Main Stack Pointer (MSP).
+
+    \param [in]    topOfMainStack  Main Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+  __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
+}
+
+
+/** \brief  Get Priority Mask
+
+    This function returns the current state of the priority mask bit from the Priority Mask Register.
+
+    \return               Priority Mask value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, primask" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Priority Mask
+
+    This function assigns the given value to the Priority Mask Register.
+
+    \param [in]    priMask  Priority Mask
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+  __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
+}
+
+
+#if       (__CORTEX_M >= 0x03)
+
+/** \brief  Enable FIQ
+
+    This function enables FIQ interrupts by clearing the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
+{
+  __ASM volatile ("cpsie f" : : : "memory");
+}
+
+
+/** \brief  Disable FIQ
+
+    This function disables FIQ interrupts by setting the F-bit in the CPSR.
+    Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
+{
+  __ASM volatile ("cpsid f" : : : "memory");
+}
+
+
+/** \brief  Get Base Priority
+
+    This function returns the current value of the Base Priority register.
+
+    \return               Base Priority register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Base Priority
+
+    This function assigns the given value to the Base Priority register.
+
+    \param [in]    basePri  Base Priority value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
+{
+  __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
+}
+
+
+/** \brief  Get Fault Mask
+
+    This function returns the current value of the Fault Mask register.
+
+    \return               Fault Mask register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+  uint32_t result;
+
+  __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
+  return(result);
+}
+
+
+/** \brief  Set Fault Mask
+
+    This function assigns the given value to the Fault Mask register.
+
+    \param [in]    faultMask  Fault Mask value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+  __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
+}
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+#if       (__CORTEX_M == 0x04)
+
+/** \brief  Get FPSCR
+
+    This function returns the current value of the Floating Point Status/Control register.
+
+    \return               Floating Point Status/Control register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+  uint32_t result;
+
+  /* Empty asm statement works as a scheduling barrier */
+  __ASM volatile ("");
+  __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
+  __ASM volatile ("");
+  return(result);
+#else
+   return(0);
+#endif
+}
+
+
+/** \brief  Set FPSCR
+
+    This function assigns the given value to the Floating Point Status/Control register.
+
+    \param [in]    fpscr  Floating Point Status/Control value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+  /* Empty asm statement works as a scheduling barrier */
+  __ASM volatile ("");
+  __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
+  __ASM volatile ("");
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04) */
+
+
+#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
+/* TASKING carm specific functions */
+
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all instrinsics,
+ * Including the CMSIS ones.
+ */
+
+#endif
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+#endif /* __CORE_CMFUNC_H */
diff --git a/reform2-lpc-fw/cmsis/core_cmInstr.h b/reform2-lpc-fw/cmsis/core_cmInstr.h
new file mode 100644
index 0000000000000000000000000000000000000000..d213f0eed7ca9335e883a5b55b6de14ba9507f1e
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/core_cmInstr.h
@@ -0,0 +1,688 @@
+/**************************************************************************//**
+ * @file     core_cmInstr.h
+ * @brief    CMSIS Cortex-M Core Instruction Access Header File
+ * @version  V3.20
+ * @date     05. March 2013
+ *
+ * @note
+ *
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2013 ARM LIMITED
+
+   All rights reserved.
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+   - Neither the name of ARM nor the names of its contributors may be used
+     to endorse or promote products derived from this software without
+     specific prior written permission.
+   *
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+   ---------------------------------------------------------------------------*/
+
+
+#ifndef __CORE_CMINSTR_H
+#define __CORE_CMINSTR_H
+
+
+/* ##########################  Core Instruction Access  ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+  Access to dedicated instructions
+  @{
+*/
+
+#if   defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+#if (__ARMCC_VERSION < 400677)
+  #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
+#endif
+
+
+/** \brief  No Operation
+
+    No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+#define __NOP                             __nop
+
+
+/** \brief  Wait For Interrupt
+
+    Wait For Interrupt is a hint instruction that suspends execution
+    until one of a number of events occurs.
+ */
+#define __WFI                             __wfi
+
+
+/** \brief  Wait For Event
+
+    Wait For Event is a hint instruction that permits the processor to enter
+    a low-power state until one of a number of events occurs.
+ */
+#define __WFE                             __wfe
+
+
+/** \brief  Send Event
+
+    Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+#define __SEV                             __sev
+
+
+/** \brief  Instruction Synchronization Barrier
+
+    Instruction Synchronization Barrier flushes the pipeline in the processor,
+    so that all instructions following the ISB are fetched from cache or
+    memory, after the instruction has been completed.
+ */
+#define __ISB()                           __isb(0xF)
+
+
+/** \brief  Data Synchronization Barrier
+
+    This function acts as a special kind of Data Memory Barrier.
+    It completes when all explicit memory accesses before this instruction complete.
+ */
+#define __DSB()                           __dsb(0xF)
+
+
+/** \brief  Data Memory Barrier
+
+    This function ensures the apparent order of the explicit memory operations before
+    and after the instruction, without ensuring their completion.
+ */
+#define __DMB()                           __dmb(0xF)
+
+
+/** \brief  Reverse byte order (32 bit)
+
+    This function reverses the byte order in integer value.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+#define __REV                             __rev
+
+
+/** \brief  Reverse byte order (16 bit)
+
+    This function reverses the byte order in two unsigned short values.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
+{
+  rev16 r0, r0
+  bx lr
+}
+#endif
+
+/** \brief  Reverse byte order in signed short value
+
+    This function reverses the byte order in a signed short value with sign extension to integer.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
+{
+  revsh r0, r0
+  bx lr
+}
+#endif
+
+
+/** \brief  Rotate Right in unsigned value (32 bit)
+
+    This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+
+    \param [in]    value  Value to rotate
+    \param [in]    value  Number of Bits to rotate
+    \return               Rotated value
+ */
+#define __ROR                             __ror
+
+
+/** \brief  Breakpoint
+
+    This function causes the processor to enter Debug state.
+    Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+
+    \param [in]    value  is ignored by the processor.
+                   If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value)                       __breakpoint(value)
+
+
+#if       (__CORTEX_M >= 0x03)
+
+/** \brief  Reverse bit order of value
+
+    This function reverses the bit order of the given value.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+#define __RBIT                            __rbit
+
+
+/** \brief  LDR Exclusive (8 bit)
+
+    This function performs a exclusive LDR command for 8 bit value.
+
+    \param [in]    ptr  Pointer to data
+    \return             value of type uint8_t at (*ptr)
+ */
+#define __LDREXB(ptr)                     ((uint8_t ) __ldrex(ptr))
+
+
+/** \brief  LDR Exclusive (16 bit)
+
+    This function performs a exclusive LDR command for 16 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint16_t at (*ptr)
+ */
+#define __LDREXH(ptr)                     ((uint16_t) __ldrex(ptr))
+
+
+/** \brief  LDR Exclusive (32 bit)
+
+    This function performs a exclusive LDR command for 32 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint32_t at (*ptr)
+ */
+#define __LDREXW(ptr)                     ((uint32_t ) __ldrex(ptr))
+
+
+/** \brief  STR Exclusive (8 bit)
+
+    This function performs a exclusive STR command for 8 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+#define __STREXB(value, ptr)              __strex(value, ptr)
+
+
+/** \brief  STR Exclusive (16 bit)
+
+    This function performs a exclusive STR command for 16 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+#define __STREXH(value, ptr)              __strex(value, ptr)
+
+
+/** \brief  STR Exclusive (32 bit)
+
+    This function performs a exclusive STR command for 32 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+#define __STREXW(value, ptr)              __strex(value, ptr)
+
+
+/** \brief  Remove the exclusive lock
+
+    This function removes the exclusive lock which is created by LDREX.
+
+ */
+#define __CLREX                           __clrex
+
+
+/** \brief  Signed Saturate
+
+    This function saturates a signed value.
+
+    \param [in]  value  Value to be saturated
+    \param [in]    sat  Bit position to saturate to (1..32)
+    \return             Saturated value
+ */
+#define __SSAT                            __ssat
+
+
+/** \brief  Unsigned Saturate
+
+    This function saturates an unsigned value.
+
+    \param [in]  value  Value to be saturated
+    \param [in]    sat  Bit position to saturate to (0..31)
+    \return             Saturated value
+ */
+#define __USAT                            __usat
+
+
+/** \brief  Count leading zeros
+
+    This function counts the number of leading zeros of a data value.
+
+    \param [in]  value  Value to count the leading zeros
+    \return             number of leading zeros in value
+ */
+#define __CLZ                             __clz
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+
+#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+
+#include <cmsis_iar.h>
+
+
+#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
+/* TI CCS specific functions */
+
+#include <cmsis_ccs.h>
+
+
+#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+
+/* Define macros for porting to both thumb1 and thumb2.
+ * For thumb1, use low register (r0-r7), specified by constrant "l"
+ * Otherwise, use general registers, specified by constrant "r" */
+#if defined (__thumb__) && !defined (__thumb2__)
+#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
+#define __CMSIS_GCC_USE_REG(r) "l" (r)
+#else
+#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
+#define __CMSIS_GCC_USE_REG(r) "r" (r)
+#endif
+
+/** \brief  No Operation
+
+    No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
+{
+  __ASM volatile ("nop");
+}
+
+
+/** \brief  Wait For Interrupt
+
+    Wait For Interrupt is a hint instruction that suspends execution
+    until one of a number of events occurs.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void)
+{
+  __ASM volatile ("wfi");
+}
+
+
+/** \brief  Wait For Event
+
+    Wait For Event is a hint instruction that permits the processor to enter
+    a low-power state until one of a number of events occurs.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void)
+{
+  __ASM volatile ("wfe");
+}
+
+
+/** \brief  Send Event
+
+    Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void)
+{
+  __ASM volatile ("sev");
+}
+
+
+/** \brief  Instruction Synchronization Barrier
+
+    Instruction Synchronization Barrier flushes the pipeline in the processor,
+    so that all instructions following the ISB are fetched from cache or
+    memory, after the instruction has been completed.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void)
+{
+  __ASM volatile ("isb");
+}
+
+
+/** \brief  Data Synchronization Barrier
+
+    This function acts as a special kind of Data Memory Barrier.
+    It completes when all explicit memory accesses before this instruction complete.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void)
+{
+  __ASM volatile ("dsb");
+}
+
+
+/** \brief  Data Memory Barrier
+
+    This function ensures the apparent order of the explicit memory operations before
+    and after the instruction, without ensuring their completion.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void)
+{
+  __ASM volatile ("dmb");
+}
+
+
+/** \brief  Reverse byte order (32 bit)
+
+    This function reverses the byte order in integer value.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value)
+{
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+  return __builtin_bswap32(value);
+#else
+  uint32_t result;
+
+  __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+#endif
+}
+
+
+/** \brief  Reverse byte order (16 bit)
+
+    This function reverses the byte order in two unsigned short values.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value)
+{
+  uint32_t result;
+
+  __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+}
+
+
+/** \brief  Reverse byte order in signed short value
+
+    This function reverses the byte order in a signed short value with sign extension to integer.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value)
+{
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+  return (short)__builtin_bswap16(value);
+#else
+  uint32_t result;
+
+  __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+  return(result);
+#endif
+}
+
+
+/** \brief  Rotate Right in unsigned value (32 bit)
+
+    This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+
+    \param [in]    value  Value to rotate
+    \param [in]    value  Number of Bits to rotate
+    \return               Rotated value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
+{
+  return (op1 >> op2) | (op1 << (32 - op2)); 
+}
+
+
+/** \brief  Breakpoint
+
+    This function causes the processor to enter Debug state.
+    Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+
+    \param [in]    value  is ignored by the processor.
+                   If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value)                       __ASM volatile ("bkpt "#value)
+
+
+#if       (__CORTEX_M >= 0x03)
+
+/** \brief  Reverse bit order of value
+
+    This function reverses the bit order of the given value.
+
+    \param [in]    value  Value to reverse
+    \return               Reversed value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+  uint32_t result;
+
+   __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
+   return(result);
+}
+
+
+/** \brief  LDR Exclusive (8 bit)
+
+    This function performs a exclusive LDR command for 8 bit value.
+
+    \param [in]    ptr  Pointer to data
+    \return             value of type uint8_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
+{
+    uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+   __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+       accepted by assembler. So has to use following less efficient pattern.
+    */
+   __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+   return(result);
+}
+
+
+/** \brief  LDR Exclusive (16 bit)
+
+    This function performs a exclusive LDR command for 16 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint16_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
+{
+    uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+   __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+    /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+       accepted by assembler. So has to use following less efficient pattern.
+    */
+   __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+   return(result);
+}
+
+
+/** \brief  LDR Exclusive (32 bit)
+
+    This function performs a exclusive LDR command for 32 bit values.
+
+    \param [in]    ptr  Pointer to data
+    \return        value of type uint32_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
+{
+    uint32_t result;
+
+   __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
+   return(result);
+}
+
+
+/** \brief  STR Exclusive (8 bit)
+
+    This function performs a exclusive STR command for 8 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
+{
+   uint32_t result;
+
+   __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
+   return(result);
+}
+
+
+/** \brief  STR Exclusive (16 bit)
+
+    This function performs a exclusive STR command for 16 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
+{
+   uint32_t result;
+
+   __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
+   return(result);
+}
+
+
+/** \brief  STR Exclusive (32 bit)
+
+    This function performs a exclusive STR command for 32 bit values.
+
+    \param [in]  value  Value to store
+    \param [in]    ptr  Pointer to location
+    \return          0  Function succeeded
+    \return          1  Function failed
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
+{
+   uint32_t result;
+
+   __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
+   return(result);
+}
+
+
+/** \brief  Remove the exclusive lock
+
+    This function removes the exclusive lock which is created by LDREX.
+
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void)
+{
+  __ASM volatile ("clrex" ::: "memory");
+}
+
+
+/** \brief  Signed Saturate
+
+    This function saturates a signed value.
+
+    \param [in]  value  Value to be saturated
+    \param [in]    sat  Bit position to saturate to (1..32)
+    \return             Saturated value
+ */
+#define __SSAT(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("ssat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+
+/** \brief  Unsigned Saturate
+
+    This function saturates an unsigned value.
+
+    \param [in]  value  Value to be saturated
+    \param [in]    sat  Bit position to saturate to (0..31)
+    \return             Saturated value
+ */
+#define __USAT(ARG1,ARG2) \
+({                          \
+  uint32_t __RES, __ARG1 = (ARG1); \
+  __ASM ("usat %0, %1, %2" : "=r" (__RES) :  "I" (ARG2), "r" (__ARG1) ); \
+  __RES; \
+ })
+
+
+/** \brief  Count leading zeros
+
+    This function counts the number of leading zeros of a data value.
+
+    \param [in]  value  Value to count the leading zeros
+    \return             number of leading zeros in value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
+{
+   uint32_t result;
+
+  __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
+  return(result);
+}
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+
+
+#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
+/* TASKING carm specific functions */
+
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all intrinsics,
+ * Including the CMSIS ones.
+ */
+
+#endif
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+#endif /* __CORE_CMINSTR_H */
diff --git a/reform2-lpc-fw/cmsis/libs/libRTX_CM0.a b/reform2-lpc-fw/cmsis/libs/libRTX_CM0.a
new file mode 100644
index 0000000000000000000000000000000000000000..43a47000e38e4b8ec324a1f61643ccb2d6d14e7c
Binary files /dev/null and b/reform2-lpc-fw/cmsis/libs/libRTX_CM0.a differ
diff --git a/reform2-lpc-fw/cmsis/libs/libRTX_CM3.a b/reform2-lpc-fw/cmsis/libs/libRTX_CM3.a
new file mode 100644
index 0000000000000000000000000000000000000000..866cdf2106169d4108d246bbbfbebdd99ba7379e
Binary files /dev/null and b/reform2-lpc-fw/cmsis/libs/libRTX_CM3.a differ
diff --git a/reform2-lpc-fw/cmsis/libs/libarm_cortexM0l_math.a b/reform2-lpc-fw/cmsis/libs/libarm_cortexM0l_math.a
new file mode 100644
index 0000000000000000000000000000000000000000..f6c9fdaa0afe9315c8ee8044264cfb9d434b24c6
Binary files /dev/null and b/reform2-lpc-fw/cmsis/libs/libarm_cortexM0l_math.a differ
diff --git a/reform2-lpc-fw/cmsis/libs/libarm_cortexM3l_math.a b/reform2-lpc-fw/cmsis/libs/libarm_cortexM3l_math.a
new file mode 100644
index 0000000000000000000000000000000000000000..6898bc27d0f736c2c77bb036a208b34ffebe6811
Binary files /dev/null and b/reform2-lpc-fw/cmsis/libs/libarm_cortexM3l_math.a differ
diff --git a/reform2-lpc-fw/cmsis/lpc11u24.ld b/reform2-lpc-fw/cmsis/lpc11u24.ld
new file mode 100644
index 0000000000000000000000000000000000000000..70689ef714377d0f9c69fd818e2a77b27f39edc7
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/lpc11u24.ld
@@ -0,0 +1,90 @@
+/*
+ * LPC11u37 linker script file.
+ * This linker is intended to use with libc.
+ */
+
+MEMORY
+{
+  irom  (rx)      : ORIGIN = 0x0,         LENGTH = 0x8000  /* 32k  */
+  isram (rwx)     : ORIGIN = 0x10000000,  LENGTH = 0x2000  /* 8k   */
+  isramUsb (rwx)  : ORIGIN = 0x20004000,  LENGTH = 0x800   /* 2k   */
+}
+
+  /* Define a symbol for the top of stack */
+  /* It won't be used if user define FIXED_STACKHEAP_SIZE */
+  __StackTop = ORIGIN(isram) + LENGTH(isram);
+
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+  /* MAIN TEXT SECTION */
+  .text : ALIGN(4)
+  {
+    __text_start = .;
+    FILL(0xff)
+    /* Always keep this vector table */
+    KEEP(*(.isr_vector_table))
+    *(.after_vectors*)
+    *(.text*)
+    *(.rodata .rodata.*)
+    . = ALIGN(4);
+    __text_end = .;
+  } > irom
+
+  /*
+   * For exception handling/unwind - some Newlib functions (in common
+   * with C++ and STDC++) use this.
+   * Use KEEP so it's not discarded with --gc-sections
+   */
+  .ARM.extab : ALIGN(4)
+  {
+    KEEP(*(.ARM.extab* .gnu.linkonce.armextab.*))
+  } > irom
+  __exidx_start = .;
+
+  .ARM.exidx : ALIGN(4)
+  {
+    KEEP(*(.ARM.exidx* .gnu.linkonce.armexidx.*))
+  } > irom
+  __exidx_end = .;
+
+  /* This is used for USB RAM section */
+  .usb_ram (NOLOAD): ALIGN(4)
+  {
+    FILL(0xff)
+    *(USB_RAM)
+  } > isramUsb
+
+  /* MAIN BSS SECTION */
+  .bss 0x10000100: ALIGN(4)
+  {
+    __bss_start = .;
+    *(.bss*)
+    rt_*.o(COMMON)
+    *(COMMON)
+    bin/obj/usbd.o(COMMON)
+    *(.heap)
+    __fixed_heap_end = .;
+    *(.stack)
+    . = ALIGN(4) ;
+    __bss_end = .;
+    PROVIDE(end = .);
+  } > isram
+
+  __data_load_addr = LOADADDR (.data);
+  
+  .data : ALIGN(4)
+  {
+    FILL(0xff)
+    __data_start = .;
+    *(.data*)
+    . = ALIGN(4) ;
+    __data_end = .;
+  } > isram AT>irom
+  
+  
+  /* Define a symbol for the start of heap */
+  /* It won't be used if user defined FIXED_STACKHEAP_SIZE */
+  PROVIDE(_pvHeapStart = .);
+}
diff --git a/reform2-lpc-fw/cmsis/lpc11u37.ld b/reform2-lpc-fw/cmsis/lpc11u37.ld
new file mode 100644
index 0000000000000000000000000000000000000000..4873e07f2edf5708e68c3eb1c683efd106619fc6
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/lpc11u37.ld
@@ -0,0 +1,90 @@
+/*
+ * LPC11u37 linker script file.
+ * This linker is intended to use with libc.
+ */
+
+MEMORY
+{
+  irom  (rx)      : ORIGIN = 0x0,         LENGTH = 0x20000 /* 128k */
+  isram (rwx)     : ORIGIN = 0x10000000,  LENGTH = 0x2000  /* 8k   */
+  isramUsb (rwx)  : ORIGIN = 0x20004000,  LENGTH = 0x800   /* 2k   */
+}
+
+  /* Define a symbol for the top of stack */
+  /* It won't be used if user define FIXED_STACKHEAP_SIZE */
+  __StackTop = ORIGIN(isram) + LENGTH(isram);
+
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+  /* MAIN TEXT SECTION */
+  .text : ALIGN(4)
+  {
+    __text_start = .;
+    FILL(0xff)
+    /* Always keep this vector table */
+    KEEP(*(.isr_vector_table))
+    *(.after_vectors*)
+    *(.text*)
+    *(.rodata .rodata.*)
+    . = ALIGN(4);
+    __text_end = .;
+  } > irom
+
+  /*
+   * For exception handling/unwind - some Newlib functions (in common
+   * with C++ and STDC++) use this.
+   * Use KEEP so it's not discarded with --gc-sections
+   */
+  .ARM.extab : ALIGN(4)
+  {
+    KEEP(*(.ARM.extab* .gnu.linkonce.armextab.*))
+  } > irom
+  __exidx_start = .;
+
+  .ARM.exidx : ALIGN(4)
+  {
+    KEEP(*(.ARM.exidx* .gnu.linkonce.armexidx.*))
+  } > irom
+  __exidx_end = .;
+
+  /* This is used for USB RAM section */
+  .usb_ram (NOLOAD): ALIGN(4)
+  {
+    FILL(0xff)
+    *(USB_RAM)
+  } > isramUsb
+
+  /* MAIN BSS SECTION */
+  .bss 0x10000100: ALIGN(4)
+  {
+    __bss_start = .;
+    *(.bss*)
+    rt_*.o(COMMON)
+    *(COMMON)
+    bin/obj/usbd.o(COMMON)
+    *(.heap)
+    __fixed_heap_end = .;
+    *(.stack)
+    . = ALIGN(4) ;
+    __bss_end = .;
+    PROVIDE(end = .);
+  } > isram
+
+  __data_load_addr = LOADADDR (.data);
+  
+  .data : ALIGN(4)
+  {
+    FILL(0xff)
+    __data_start = .;
+    *(.data*)
+    . = ALIGN(4) ;
+    __data_end = .;
+  } > isram AT>irom
+  
+  
+  /* Define a symbol for the start of heap */
+  /* It won't be used if user defined FIXED_STACKHEAP_SIZE */
+  PROVIDE(_pvHeapStart = .);
+}
diff --git a/reform2-lpc-fw/cmsis/lpc1347.ld b/reform2-lpc-fw/cmsis/lpc1347.ld
new file mode 100644
index 0000000000000000000000000000000000000000..938680b92fa66a10672bc1797aea697f51a01976
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/lpc1347.ld
@@ -0,0 +1,90 @@
+/*
+ * LPC1347 linker script file.
+ * This linker is intended to use with libc.
+ */
+
+MEMORY
+{
+  irom  (rx)      : ORIGIN = 0x0,         LENGTH = 0x10000 /* 64k */
+  isram (rwx)     : ORIGIN = 0x10000000,  LENGTH = 0x2000  /* 8k  */
+  isramUsb (rwx)  : ORIGIN = 0x20004000,  LENGTH = 0x800   /* 2k  */
+}
+
+  /* Define a symbol for the top of stack */
+  /* It won't be used if user define FIXED_STACKHEAP_SIZE */
+  __StackTop = ORIGIN(isram) + LENGTH(isram);
+
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+  /* MAIN TEXT SECTION */
+  .text : ALIGN(4)
+  {
+    __text_start = .;
+    FILL(0xff)
+    /* Always keep this vector table */
+    KEEP(*(.isr_vector_table))
+    *(.after_vectors*)
+    *(.text*)
+    *(.rodata .rodata.*)
+    . = ALIGN(4);
+    __text_end = .;
+  } > irom
+
+  /*
+   * For exception handling/unwind - some Newlib functions (in common
+   * with C++ and STDC++) use this.
+   * Use KEEP so it's not discarded with --gc-sections
+   */
+  .ARM.extab : ALIGN(4)
+  {
+    KEEP(*(.ARM.extab* .gnu.linkonce.armextab.*))
+  } > irom
+  __exidx_start = .;
+
+  .ARM.exidx : ALIGN(4)
+  {
+    KEEP(*(.ARM.exidx* .gnu.linkonce.armexidx.*))
+  } > irom
+  __exidx_end = .;
+
+  /* This is used for USB RAM section */
+  .usb_ram (NOLOAD): ALIGN(4)
+  {
+    FILL(0xff)
+    *(USB_RAM)
+  } > isramUsb
+
+  /* MAIN BSS SECTION */
+  .bss 0x10000100: ALIGN(4)
+  {
+    __bss_start = .;
+    *(.bss*)
+    rt_*.o(COMMON)
+    *(COMMON)
+    bin/obj/usbd.o(COMMON)
+    *(.heap)
+    __fixed_heap_end = .;
+    *(.stack)
+    . = ALIGN(4) ;
+    __bss_end = .;
+    PROVIDE(end = .);
+  } > isram
+
+  __data_load_addr = LOADADDR (.data);
+  
+  .data : ALIGN(4)
+  {
+    FILL(0xff)
+    __data_start = .;
+    *(.data*)
+    . = ALIGN(4) ;
+    __data_end = .;
+  } > isram AT>irom
+  
+  
+  /* Define a symbol for the start of heap */
+  /* It won't be used if user defined FIXED_STACKHEAP_SIZE */
+  PROVIDE(_pvHeapStart = .);
+}
diff --git a/reform2-lpc-fw/cmsis/math_helper.c b/reform2-lpc-fw/cmsis/math_helper.c
new file mode 100644
index 0000000000000000000000000000000000000000..75dcd5f252eeb34339159200d547ca05874faa04
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/math_helper.c
@@ -0,0 +1,447 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010 ARM Limited. All rights reserved.  
+*  
+* $Date:        29. November 2010  
+* $Revision: 	V1.0.3  
+*  
+* Project: 	    CMSIS DSP Library 
+*
+* Title:	    math_helper.c
+*
+* Description:	Definition of all helper functions required.  
+*  
+* Target Processor: Cortex-M4/Cortex-M3
+*  
+* Version 1.0.3 2010/11/29 
+*    Re-organized the CMSIS folders and updated documentation.  
+*   
+* Version 1.0.2 2010/11/11  
+*    Documentation updated.   
+*  
+* Version 1.0.1 2010/10/05   
+*    Production release and review comments incorporated.  
+*  
+* Version 1.0.0 2010/09/20   
+*    Production release and review comments incorporated.  
+*  
+* Version 0.0.7  2010/06/10   
+*    Misra-C changes done 
+* -------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+*		Include standard header files  
+* -------------------------------------------------------------------- */
+#include<math.h>
+
+/* ----------------------------------------------------------------------
+*		Include project header files  
+* -------------------------------------------------------------------- */
+#include "math_helper.h"
+
+/** 
+ * @brief  Caluclation of SNR
+ * @param  float* 	Pointer to the reference buffer
+ * @param  float*	Pointer to the test buffer
+ * @param  uint32_t	total number of samples
+ * @return float	SNR
+ * The function Caluclates signal to noise ratio for the reference output 
+ * and test output 
+ */
+
+float arm_snr_f32(float *pRef, float *pTest, uint32_t buffSize)
+{
+  float EnergySignal = 0.0, EnergyError = 0.0;
+  uint32_t i;
+  float SNR;
+  int temp;
+  int *test;
+
+  for (i = 0; i < buffSize; i++)
+    {
+ 	  /* Checking for a NAN value in pRef array */
+	  test =   (int *)(&pRef[i]);
+      temp =  *test;
+
+	  if(temp == 0x7FC00000)
+	  {
+	  		return(0);
+	  }
+
+	  /* Checking for a NAN value in pTest array */
+	  test =   (int *)(&pTest[i]);
+      temp =  *test;
+
+	  if(temp == 0x7FC00000)
+	  {
+	  		return(0);
+	  }
+      EnergySignal += pRef[i] * pRef[i];
+      EnergyError += (pRef[i] - pTest[i]) * (pRef[i] - pTest[i]); 
+    }
+
+	/* Checking for a NAN value in EnergyError */
+	test =   (int *)(&EnergyError);
+    temp =  *test;
+
+    if(temp == 0x7FC00000)
+    {
+  		return(0);
+    }
+	
+
+  SNR = 10 * log10 (EnergySignal / EnergyError);
+
+  return (SNR);
+
+}
+
+
+/** 
+ * @brief  Provide guard bits for Input buffer
+ * @param  q15_t* 	    Pointer to input buffer
+ * @param  uint32_t 	blockSize
+ * @param  uint32_t 	guard_bits
+ * @return none
+ * The function Provides the guard bits for the buffer 
+ * to avoid overflow 
+ */
+
+void arm_provide_guard_bits_q15 (q15_t * input_buf, uint32_t blockSize,
+                            uint32_t guard_bits)
+{
+  uint32_t i;
+
+  for (i = 0; i < blockSize; i++)
+    {
+      input_buf[i] = input_buf[i] >> guard_bits;
+    }
+}
+
+/** 
+ * @brief  Converts float to fixed in q12.20 format
+ * @param  uint32_t 	number of samples in the buffer
+ * @return none
+ * The function converts floating point values to fixed point(q12.20) values 
+ */
+
+void arm_float_to_q12_20(float *pIn, q31_t * pOut, uint32_t numSamples)
+{
+  uint32_t i;
+
+  for (i = 0; i < numSamples; i++)
+    {
+	  /* 1048576.0f corresponds to pow(2, 20) */
+      pOut[i] = (q31_t) (pIn[i] * 1048576.0f);
+
+      pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
+
+      if (pIn[i] == (float) 1.0)
+        {
+          pOut[i] = 0x000FFFFF;
+        }
+    }
+}
+
+/** 
+ * @brief  Compare MATLAB Reference Output and ARM Test output
+ * @param  q15_t* 	Pointer to Ref buffer
+ * @param  q15_t* 	Pointer to Test buffer
+ * @param  uint32_t 	number of samples in the buffer
+ * @return none 
+ */
+
+uint32_t arm_compare_fixed_q15(q15_t *pIn, q15_t * pOut, uint32_t numSamples)
+{
+  uint32_t i; 
+  int32_t diff, diffCrnt = 0;
+  uint32_t maxDiff = 0;
+
+  for (i = 0; i < numSamples; i++)
+  {
+  	diff = pIn[i] - pOut[i];
+  	diffCrnt = (diff > 0) ? diff : -diff;
+
+	if(diffCrnt > maxDiff)
+	{
+		maxDiff = diffCrnt;
+	}	
+  }
+
+  return(maxDiff);
+}
+
+/** 
+ * @brief  Compare MATLAB Reference Output and ARM Test output
+ * @param  q31_t* 	Pointer to Ref buffer
+ * @param  q31_t* 	Pointer to Test buffer
+ * @param  uint32_t 	number of samples in the buffer
+ * @return none 
+ */
+
+uint32_t arm_compare_fixed_q31(q31_t *pIn, q31_t * pOut, uint32_t numSamples)
+{
+  uint32_t i; 
+  int32_t diff, diffCrnt = 0;
+  uint32_t maxDiff = 0;
+
+  for (i = 0; i < numSamples; i++)
+  {
+  	diff = pIn[i] - pOut[i];
+  	diffCrnt = (diff > 0) ? diff : -diff;
+
+	if(diffCrnt > maxDiff)
+	{
+		maxDiff = diffCrnt;
+	}
+  }
+
+  return(maxDiff);
+}
+
+/** 
+ * @brief  Provide guard bits for Input buffer
+ * @param  q31_t* 	Pointer to input buffer
+ * @param  uint32_t 	blockSize
+ * @param  uint32_t 	guard_bits
+ * @return none
+ * The function Provides the guard bits for the buffer 
+ * to avoid overflow 
+ */
+
+void arm_provide_guard_bits_q31 (q31_t * input_buf, 
+								 uint32_t blockSize,
+                                 uint32_t guard_bits)
+{
+  uint32_t i;
+
+  for (i = 0; i < blockSize; i++)
+    {
+      input_buf[i] = input_buf[i] >> guard_bits;
+    }
+}
+
+/** 
+ * @brief  Provide guard bits for Input buffer
+ * @param  q31_t* 	Pointer to input buffer
+ * @param  uint32_t 	blockSize
+ * @param  uint32_t 	guard_bits
+ * @return none
+ * The function Provides the guard bits for the buffer 
+ * to avoid overflow 
+ */
+
+void arm_provide_guard_bits_q7 (q7_t * input_buf, 
+								uint32_t blockSize,
+                                uint32_t guard_bits)
+{
+  uint32_t i;
+
+  for (i = 0; i < blockSize; i++)
+    {
+      input_buf[i] = input_buf[i] >> guard_bits;
+    }
+}
+
+
+
+/** 
+ * @brief  Caluclates number of guard bits 
+ * @param  uint32_t 	number of additions
+ * @return none
+ * The function Caluclates the number of guard bits  
+ * depending on the numtaps 
+ */
+
+uint32_t arm_calc_guard_bits (uint32_t num_adds)
+{
+  uint32_t i = 1, j = 0;
+
+  if (num_adds == 1)
+    {
+      return (0);
+    }
+
+  while (i < num_adds)
+    {
+      i = i * 2;
+      j++;
+    }
+
+  return (j);
+}
+
+/** 
+ * @brief  Converts Q15 to floating-point
+ * @param  uint32_t 	number of samples in the buffer
+ * @return none
+ */
+
+void arm_apply_guard_bits (float32_t * pIn, 
+						   uint32_t numSamples, 
+						   uint32_t guard_bits)
+{
+  uint32_t i;
+
+  for (i = 0; i < numSamples; i++)
+    {
+      pIn[i] = pIn[i] * arm_calc_2pow(guard_bits);
+    }
+}
+
+/** 
+ * @brief  Calculates pow(2, numShifts)
+ * @param  uint32_t 	number of shifts
+ * @return pow(2, numShifts)
+ */
+uint32_t arm_calc_2pow(uint32_t numShifts)
+{
+
+  uint32_t i, val = 1;
+
+  for (i = 0; i < numShifts; i++)
+    {
+      val = val * 2;
+    }	
+
+  return(val);
+}
+
+
+
+/** 
+ * @brief  Converts float to fixed q14 
+ * @param  uint32_t 	number of samples in the buffer
+ * @return none
+ * The function converts floating point values to fixed point values 
+ */
+
+void arm_float_to_q14 (float *pIn, q15_t * pOut, 
+                       uint32_t numSamples)
+{
+  uint32_t i;
+
+  for (i = 0; i < numSamples; i++)
+    {
+	  /* 16384.0f corresponds to pow(2, 14) */
+      pOut[i] = (q15_t) (pIn[i] * 16384.0f);
+
+      pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
+
+      if (pIn[i] == (float) 2.0)
+        {
+          pOut[i] = 0x7FFF;
+        }
+
+    }
+
+}
+
+ 
+/** 
+ * @brief  Converts float to fixed q30 format
+ * @param  uint32_t 	number of samples in the buffer
+ * @return none
+ * The function converts floating point values to fixed point values 
+ */
+
+void arm_float_to_q30 (float *pIn, q31_t * pOut, 
+					   uint32_t numSamples)
+{
+  uint32_t i;
+
+  for (i = 0; i < numSamples; i++)
+    {
+	  /* 1073741824.0f corresponds to pow(2, 30) */
+      pOut[i] = (q31_t) (pIn[i] * 1073741824.0f);
+
+      pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
+
+      if (pIn[i] == (float) 2.0)
+        {
+          pOut[i] = 0x7FFFFFFF;
+        }
+    }
+}
+
+/** 
+ * @brief  Converts float to fixed q30 format
+ * @param  uint32_t 	number of samples in the buffer
+ * @return none
+ * The function converts floating point values to fixed point values 
+ */
+
+void arm_float_to_q29 (float *pIn, q31_t * pOut, 
+					   uint32_t numSamples)
+{
+  uint32_t i;
+
+  for (i = 0; i < numSamples; i++)
+    {
+	  /* 1073741824.0f corresponds to pow(2, 30) */
+      pOut[i] = (q31_t) (pIn[i] * 536870912.0f);
+
+      pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
+
+      if (pIn[i] == (float) 4.0)
+        {
+          pOut[i] = 0x7FFFFFFF;
+        }
+    }
+}
+
+
+/** 
+ * @brief  Converts float to fixed q28 format
+ * @param  uint32_t 	number of samples in the buffer
+ * @return none
+ * The function converts floating point values to fixed point values 
+ */
+
+void arm_float_to_q28 (float *pIn, q31_t * pOut, 
+                       uint32_t numSamples)
+{
+  uint32_t i;
+
+  for (i = 0; i < numSamples; i++)
+    {
+	/* 268435456.0f corresponds to pow(2, 28) */
+      pOut[i] = (q31_t) (pIn[i] * 268435456.0f);
+
+      pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
+
+      if (pIn[i] == (float) 8.0)
+        {
+          pOut[i] = 0x7FFFFFFF;
+        }
+    }
+}
+
+/** 
+ * @brief  Clip the float values to +/- 1 
+ * @param  pIn 	input buffer
+ * @param  numSamples 	number of samples in the buffer
+ * @return none
+ * The function converts floating point values to fixed point values 
+ */
+
+void arm_clip_f32 (float *pIn, uint32_t numSamples)
+{
+  uint32_t i;
+
+  for (i = 0; i < numSamples; i++)
+    {
+      if(pIn[i] > 1.0f)
+	  {
+	    pIn[i] = 1.0;
+	  }
+	  else if( pIn[i] < -1.0f)
+	  {
+	    pIn[i] = -1.0;
+	  }
+	       
+    }
+}
+
+
+
+
diff --git a/reform2-lpc-fw/cmsis/math_helper.h b/reform2-lpc-fw/cmsis/math_helper.h
new file mode 100644
index 0000000000000000000000000000000000000000..4eb34ace8704c9ff49ddd8b0c0cbfebd0212fc6c
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/math_helper.h
@@ -0,0 +1,53 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010 ARM Limited. All rights reserved.  
+*  
+* $Date:        29. November 2010  
+* $Revision: 	V1.0.3  
+*  
+* Project: 	    CMSIS DSP Library 
+*
+* Title:	    math_helper.h
+* 
+*
+* Description:	Prototypes of all helper functions required.  
+*
+* Target Processor: Cortex-M4/Cortex-M3
+*  
+* Version 1.0.3 2010/11/29 
+*    Re-organized the CMSIS folders and updated documentation.  
+*   
+* Version 1.0.2 2010/11/11  
+*    Documentation updated.   
+*  
+* Version 1.0.1 2010/10/05   
+*    Production release and review comments incorporated.  
+*  
+* Version 1.0.0 2010/09/20   
+*    Production release and review comments incorporated.  
+*  
+* Version 0.0.7  2010/06/10   
+*    Misra-C changes done 
+* -------------------------------------------------------------------- */
+
+
+#include "arm_math.h"
+
+#ifndef MATH_HELPER_H
+#define MATH_HELPER_H
+
+float arm_snr_f32(float *pRef, float *pTest,  uint32_t buffSize);  
+void arm_float_to_q12_20(float *pIn, q31_t * pOut, uint32_t numSamples);
+void arm_provide_guard_bits_q15(q15_t *input_buf, uint32_t blockSize, uint32_t guard_bits);
+void arm_provide_guard_bits_q31(q31_t *input_buf, uint32_t blockSize, uint32_t guard_bits);
+void arm_float_to_q14(float *pIn, q15_t *pOut, uint32_t numSamples);
+void arm_float_to_q29(float *pIn, q31_t *pOut, uint32_t numSamples);
+void arm_float_to_q28(float *pIn, q31_t *pOut, uint32_t numSamples);
+void arm_float_to_q30(float *pIn, q31_t *pOut, uint32_t numSamples);
+void arm_clip_f32(float *pIn, uint32_t numSamples);
+uint32_t arm_calc_guard_bits(uint32_t num_adds);
+void arm_apply_guard_bits (float32_t * pIn, uint32_t numSamples, uint32_t guard_bits);
+uint32_t arm_compare_fixed_q15(q15_t *pIn, q15_t * pOut, uint32_t numSamples);
+uint32_t arm_compare_fixed_q31(q31_t *pIn, q31_t *pOut, uint32_t numSamples);
+uint32_t arm_calc_2pow(uint32_t guard_bits);
+#endif
+
diff --git a/reform2-lpc-fw/cmsis/startup_lpc11u_gnumake.c b/reform2-lpc-fw/cmsis/startup_lpc11u_gnumake.c
new file mode 100644
index 0000000000000000000000000000000000000000..6d79d070c5bfcb8c5b423cf55a5b623a28299a53
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/startup_lpc11u_gnumake.c
@@ -0,0 +1,273 @@
+/*================================*/
+/*=====LPC11XX GNU STARTUP========*/
+/*==A CODERED COMPATIBLE STARTUP==*/
+/*================================*/
+#if defined (__cplusplus)
+#ifdef __REDLIB__
+#error Redlib does not support C++
+#else
+//*****************************************************************************
+//
+// The entry point for the C++ library startup
+//
+//*****************************************************************************
+extern "C"
+{
+  extern void __libc_init_array(void);
+}
+#endif
+#endif
+
+#define WEAK __attribute__ ((weak))
+#define ALIAS(f) __attribute__ ((weak, alias (#f)))
+
+#include "LPC11Uxx.h"
+
+//*****************************************************************************
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+extern unsigned int __data_load_addr;
+extern unsigned int __data_start;
+extern unsigned int __data_end;
+extern unsigned int __bss_start;
+extern unsigned int __bss_end;
+extern unsigned int __StackTop;
+#ifdef FIXED_STACKHEAP_SIZE
+#define STACK_SIZE  (800)
+#define HEAP_SIZE  (200)
+unsigned char StackMem[STACK_SIZE] __attribute__ ((section(".stack")));
+unsigned char HeapMem[HEAP_SIZE] __attribute__ ((section(".heap"), align(8)));
+#endif
+//*****************************************************************************
+//
+// Forward declaration of the default handlers. These are aliased.
+// When the application defines a handler (with the same name), this will
+// automatically take precedence over these weak definitions
+//
+//*****************************************************************************
+     void Reset_Handler(void);
+WEAK void NMI_Handler(void);
+WEAK void HardFault_Handler(void);
+WEAK void SVC_Handler(void);
+WEAK void PendSV_Handler(void);
+WEAK void SysTick_Handler(void);
+WEAK void IntDefaultHandler(void);
+//*****************************************************************************
+//
+// Forward declaration of the specific IRQ handlers. These are aliased
+// to the IntDefaultHandler, which is a 'forever' loop. When the application
+// defines a handler (with the same name), this will automatically take
+// precedence over these weak definitions
+//
+//*****************************************************************************
+
+void FLEX_INT0_IRQHandler (void) ALIAS(IntDefaultHandler);
+void FLEX_INT1_IRQHandler (void) ALIAS(IntDefaultHandler);
+void FLEX_INT2_IRQHandler (void) ALIAS(IntDefaultHandler);
+void FLEX_INT3_IRQHandler (void) ALIAS(IntDefaultHandler);
+void FLEX_INT4_IRQHandler (void) ALIAS(IntDefaultHandler);
+void FLEX_INT5_IRQHandler (void) ALIAS(IntDefaultHandler);
+void FLEX_INT6_IRQHandler (void) ALIAS(IntDefaultHandler);
+void FLEX_INT7_IRQHandler (void) ALIAS(IntDefaultHandler);
+void GINT0_IRQHandler     (void) ALIAS(IntDefaultHandler);
+void GINT1_IRQHandler     (void) ALIAS(IntDefaultHandler);
+void SSP1_IRQHandler      (void) ALIAS(IntDefaultHandler);
+void I2C_IRQHandler       (void) ALIAS(IntDefaultHandler);
+void TIMER16_0_IRQHandler (void) ALIAS(IntDefaultHandler);
+void TIMER16_1_IRQHandler (void) ALIAS(IntDefaultHandler);
+void TIMER32_0_IRQHandler (void) ALIAS(IntDefaultHandler);
+void TIMER32_1_IRQHandler (void) ALIAS(IntDefaultHandler);
+void SSP0_IRQHandler      (void) ALIAS(IntDefaultHandler);
+void UART_IRQHandler      (void) ALIAS(IntDefaultHandler);
+void USB_IRQHandler       (void) ALIAS(IntDefaultHandler);
+void USB_FIQHandler       (void) ALIAS(IntDefaultHandler);
+void ADC_IRQHandler       (void) ALIAS(IntDefaultHandler);
+void WDT_IRQHandler       (void) ALIAS(IntDefaultHandler);
+void BOD_IRQHandler       (void) ALIAS(IntDefaultHandler);
+void FMC_IRQHandler       (void) ALIAS(IntDefaultHandler);
+void USBWakeup_IRQHandler (void) ALIAS(IntDefaultHandler);
+
+//*****************************************************************************
+//
+// The entry point for the application.
+// __main() is the entry point for Redlib based applications
+// main() is the entry point for Newlib based applications
+//
+//*****************************************************************************
+#if defined (__REDLIB__)
+extern void __main(void);
+#else
+extern int main(void);
+#endif
+
+//*****************************************************************************
+#if defined (__cplusplus)
+} // extern "C"
+#endif
+
+__attribute__ ((section(".isr_vector_table")))
+void (* const Vectors[])(void) = {
+#ifdef FIXED_STACKHEAP_SIZE
+  (void (*)(void))(StackMem + STACK_SIZE),          // The initial stack pointer
+#else
+  (void (*)(void))&__StackTop,
+#endif
+  Reset_Handler,                    // The reset handler
+  NMI_Handler,                      // The NMI handler
+  HardFault_Handler,                // The hard fault handler
+  0,                                // Reserved
+  0,                                // Reserved
+  0,                                // Reserved
+  0,                                // Reserved
+  0,                                // Reserved
+  0,                                // Reserved
+  0,                                // Reserved
+  SVC_Handler,                      // SVCall handler
+  0,                                // Reserved
+  0,                                // Reserved
+  PendSV_Handler,                   // The PendSV handler
+  SysTick_Handler,                  // The SysTick handler
+
+  // LPC11U specific handlers
+  FLEX_INT0_IRQHandler,             //  0 - GPIO pin interrupt 0
+  FLEX_INT1_IRQHandler,             //  1 - GPIO pin interrupt 1
+  FLEX_INT2_IRQHandler,             //  2 - GPIO pin interrupt 2
+  FLEX_INT3_IRQHandler,             //  3 - GPIO pin interrupt 3
+  FLEX_INT4_IRQHandler,             //  4 - GPIO pin interrupt 4
+  FLEX_INT5_IRQHandler,             //  5 - GPIO pin interrupt 5
+  FLEX_INT6_IRQHandler,             //  6 - GPIO pin interrupt 6
+  FLEX_INT7_IRQHandler,             //  7 - GPIO pin interrupt 7
+  GINT0_IRQHandler,                 //  8 - GPIO GROUP0 interrupt
+  GINT1_IRQHandler,                 //  9 - GPIO GROUP1 interrupt
+  0,                                // 10 - Reserved
+  0,                                // 11 - Reserved
+  0,                                // 12 - Reserved
+  0,                                // 13 - Reserved
+  SSP1_IRQHandler,                  // 14 - SPI/SSP1 Interrupt
+  I2C_IRQHandler,                   // 15 - I2C0
+  TIMER16_0_IRQHandler,             // 16 - CT16B0 (16-bit Timer 0)
+  TIMER16_1_IRQHandler,             // 17 - CT16B1 (16-bit Timer 1)
+  TIMER32_0_IRQHandler,             // 18 - CT32B0 (32-bit Timer 0)
+  TIMER32_1_IRQHandler,             // 19 - CT32B1 (32-bit Timer 1)
+  SSP0_IRQHandler,                  // 20 - SPI/SSP0 Interrupt
+  UART_IRQHandler,                  // 21 - UART0
+  USB_IRQHandler,                   // 22 - USB IRQ
+  USB_FIQHandler,                   // 23 - USB FIQ
+  ADC_IRQHandler,                   // 24 - ADC (A/D Converter)
+  WDT_IRQHandler,                   // 25 - WDT (Watchdog Timer)
+  BOD_IRQHandler,                   // 26 - BOD (Brownout Detect)
+  FMC_IRQHandler,                   // 27 - IP2111 Flash Memory Controller
+  0,                                // 28 - Reserved
+  0,                                // 29 - Reserved
+  USBWakeup_IRQHandler,             // 30 - USB wake-up interrupt
+  0,                                // 31 - Reserved
+};
+
+//*****************************************************************************
+// Reset entry point for your code.
+// Sets up a simple runtime environment and initializes the C/C++
+// library.
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void Reset_Handler(void)
+{
+  /*
+   * Only Initialize Internal SRAM
+   * USB RAM is used for USB purpose
+   */
+  unsigned int *src, *dst;
+
+  /* Copy data section from flash to RAM */
+  src = &__data_load_addr;
+  dst = &__data_start;
+  while (dst < &__data_end)
+    *dst++ = *src++;
+
+  /* Zero fill the bss section */
+  dst = &__bss_start;
+  while (dst < &__bss_end)
+    *dst++ = 0;
+
+  SystemInit();
+
+#if defined (__cplusplus)
+  //
+  // Call C++ library initialisation
+  //
+  __libc_init_array();
+#endif
+
+#if defined (__REDLIB__)
+  // Call the Redlib library, which in turn calls main()
+  __main() ;
+#else
+  main();
+#endif
+	//
+	// main() shouldn't return, but if it does, we'll just enter an infinite loop
+	//
+	while (1) {
+		;
+	}
+}
+
+//*****************************************************************************
+// Default exception handlers. Override the ones here by defining your own
+// handler routines in your application code.
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void NMI_Handler(void)
+{
+    while(1)
+    {
+    }
+}
+
+__attribute__ ((section(".after_vectors")))
+void HardFault_Handler(void)
+{
+    while(1)
+    {
+    }
+}
+
+__attribute__ ((section(".after_vectors")))
+void SVC_Handler(void)
+{
+    while(1)
+    {
+    }
+}
+
+__attribute__ ((section(".after_vectors")))
+void PendSV_Handler(void)
+{
+    while(1)
+    {
+    }
+}
+
+__attribute__ ((section(".after_vectors")))
+void SysTick_Handler(void)
+{
+    while(1)
+    {
+    }
+}
+
+//*****************************************************************************
+//
+// Processor ends up here if an unexpected interrupt occurs or a specific
+// handler is not present in the application code.
+//
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void IntDefaultHandler(void)
+{
+    while(1)
+    {
+    }
+}
+
diff --git a/reform2-lpc-fw/cmsis/startup_lpc11u_lpc13u_codered.c b/reform2-lpc-fw/cmsis/startup_lpc11u_lpc13u_codered.c
new file mode 100644
index 0000000000000000000000000000000000000000..d43c26f59cc4cb96d505b28bccf114232311061a
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/startup_lpc11u_lpc13u_codered.c
@@ -0,0 +1,754 @@
+#include "projectconfig.h"
+
+#if defined CFG_MCU_FAMILY_LPC11UXX
+/* LPC11U24 or LPC11U37 Startup Code */
+
+//*****************************************************************************
+//   +--+
+//   | ++----+
+//   +-++    |
+//     |     |
+//   +-+--+  |
+//   | +--+--+
+//   +----+    Copyright (c) 2011-12 Code Red Technologies Ltd.
+//
+// Microcontroller Startup code for use with Red Suite
+//
+// Version : 120126
+//
+// Software License Agreement
+//
+// The software is owned by Code Red Technologies and/or its suppliers, and is
+// protected under applicable copyright laws.  All rights are reserved.  Any
+// use in violation of the foregoing restrictions may subject the user to criminal
+// sanctions under applicable laws, as well as to civil liability for the breach
+// of the terms and conditions of this license.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
+// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
+// CODE RED TECHNOLOGIES LTD.
+//
+//*****************************************************************************
+#if defined (__cplusplus)
+#ifdef __REDLIB__
+#error Redlib does not support C++
+#else
+//*****************************************************************************
+//
+// The entry point for the C++ library startup
+//
+//*****************************************************************************
+extern "C" {
+	extern void __libc_init_array(void);
+}
+#endif
+#endif
+
+#define WEAK __attribute__ ((weak))
+#define ALIAS(f) __attribute__ ((weak, alias (#f)))
+
+// Code Red - if CMSIS is being used, then SystemInit() routine
+// will be called by startup code rather than in application's main()
+#if defined (__USE_CMSIS)
+#include "LPC11Uxx.h"
+#endif
+
+//*****************************************************************************
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+//*****************************************************************************
+//
+// Forward declaration of the default handlers. These are aliased.
+// When the application defines a handler (with the same name), this will
+// automatically take precedence over these weak definitions
+//
+//*****************************************************************************
+     void ResetISR(void);
+WEAK void NMI_Handler(void);
+WEAK void HardFault_Handler(void);
+WEAK void SVC_Handler(void);
+WEAK void PendSV_Handler(void);
+WEAK void SysTick_Handler(void);
+WEAK void IntDefaultHandler(void);
+//*****************************************************************************
+//
+// Forward declaration of the specific IRQ handlers. These are aliased
+// to the IntDefaultHandler, which is a 'forever' loop. When the application
+// defines a handler (with the same name), this will automatically take
+// precedence over these weak definitions
+//
+//*****************************************************************************
+
+void FLEX_INT0_IRQHandler (void) ALIAS(IntDefaultHandler);
+void FLEX_INT1_IRQHandler (void) ALIAS(IntDefaultHandler);
+void FLEX_INT2_IRQHandler (void) ALIAS(IntDefaultHandler);
+void FLEX_INT3_IRQHandler (void) ALIAS(IntDefaultHandler);
+void FLEX_INT4_IRQHandler (void) ALIAS(IntDefaultHandler);
+void FLEX_INT5_IRQHandler (void) ALIAS(IntDefaultHandler);
+void FLEX_INT6_IRQHandler (void) ALIAS(IntDefaultHandler);
+void FLEX_INT7_IRQHandler (void) ALIAS(IntDefaultHandler);
+void GINT0_IRQHandler (void) ALIAS(IntDefaultHandler);
+void GINT1_IRQHandler (void) ALIAS(IntDefaultHandler);
+void SSP1_IRQHandler (void) ALIAS(IntDefaultHandler);
+void I2C_IRQHandler (void) ALIAS(IntDefaultHandler);
+void TIMER16_0_IRQHandler (void) ALIAS(IntDefaultHandler);
+void TIMER16_1_IRQHandler (void) ALIAS(IntDefaultHandler);
+void TIMER32_0_IRQHandler (void) ALIAS(IntDefaultHandler);
+void TIMER32_1_IRQHandler (void) ALIAS(IntDefaultHandler);
+void SSP0_IRQHandler (void) ALIAS(IntDefaultHandler);
+void UART_IRQHandler (void) ALIAS(IntDefaultHandler);
+void USB_IRQHandler (void) ALIAS(IntDefaultHandler);
+void USB_FIQHandler (void) ALIAS(IntDefaultHandler);
+void ADC_IRQHandler (void) ALIAS(IntDefaultHandler);
+void WDT_IRQHandler (void) ALIAS(IntDefaultHandler);
+void BOD_IRQHandler (void) ALIAS(IntDefaultHandler);
+void FMC_IRQHandler (void) ALIAS(IntDefaultHandler);
+void USBWakeup_IRQHandler (void) ALIAS(IntDefaultHandler);
+
+//*****************************************************************************
+//
+// The entry point for the application.
+// __main() is the entry point for redlib based applications
+// main() is the entry point for newlib based applications
+//
+//*****************************************************************************
+//
+// The entry point for the application.
+// __main() is the entry point for Redlib based applications
+// main() is the entry point for Newlib based applications
+//
+//*****************************************************************************
+#if defined (__REDLIB__)
+extern void __main(void);
+#else
+extern int main(void);
+#endif
+
+//*****************************************************************************
+//
+// External declaration for the pointer to the stack top from the Linker Script
+//
+//*****************************************************************************
+extern void _vStackTop(void);
+
+//*****************************************************************************
+#if defined (__cplusplus)
+} // extern "C"
+#endif
+//*****************************************************************************
+//
+// The vector table.  Note that the proper constructs must be placed on this to
+// ensure that it ends up at physical address 0x0000.0000.
+//
+//*****************************************************************************
+extern void (* const g_pfnVectors[])(void);
+__attribute__ ((section(".isr_vector")))
+void (* const g_pfnVectors[])(void) = {
+    &_vStackTop,		      // The initial stack pointer
+    ResetISR,                         // The reset handler
+    NMI_Handler,                      // The NMI handler
+    HardFault_Handler,                // The hard fault handler
+    0,                                // Reserved
+    0,                      	      // Reserved
+    0,                                // Reserved
+    0,                                // Reserved
+    0,                                // Reserved
+    0,                                // Reserved
+    0,                                // Reserved
+    SVC_Handler,                   // SVCall handler
+    0,                                // Reserved
+    0,                                // Reserved
+    PendSV_Handler,                   // The PendSV handler
+    SysTick_Handler,                  // The SysTick handler
+
+    // LPC11U specific handlers
+    FLEX_INT0_IRQHandler,             //  0 - GPIO pin interrupt 0
+    FLEX_INT1_IRQHandler,             //  1 - GPIO pin interrupt 1
+    FLEX_INT2_IRQHandler,             //  2 - GPIO pin interrupt 2
+    FLEX_INT3_IRQHandler,             //  3 - GPIO pin interrupt 3
+    FLEX_INT4_IRQHandler,             //  4 - GPIO pin interrupt 4
+    FLEX_INT5_IRQHandler,             //  5 - GPIO pin interrupt 5
+    FLEX_INT6_IRQHandler,             //  6 - GPIO pin interrupt 6
+    FLEX_INT7_IRQHandler,             //  7 - GPIO pin interrupt 7
+    GINT0_IRQHandler,                 //  8 - GPIO GROUP0 interrupt
+    GINT1_IRQHandler,                 //  9 - GPIO GROUP1 interrupt
+    0,                                // 10 - Reserved
+    0,                                // 11 - Reserved
+    0,                                // 12 - Reserved
+    0,                                // 13 - Reserved
+    SSP1_IRQHandler,                  // 14 - SPI/SSP1 Interrupt
+    I2C_IRQHandler,                   // 15 - I2C0
+    TIMER16_0_IRQHandler,             // 16 - CT16B0 (16-bit Timer 0)
+    TIMER16_1_IRQHandler,             // 17 - CT16B1 (16-bit Timer 1)
+    TIMER32_0_IRQHandler,             // 18 - CT32B0 (32-bit Timer 0)
+    TIMER32_1_IRQHandler,             // 19 - CT32B1 (32-bit Timer 1)
+    SSP0_IRQHandler,                  // 20 - SPI/SSP0 Interrupt
+    UART_IRQHandler,                  // 21 - UART0
+    USB_IRQHandler,                   // 22 - USB IRQ
+    USB_FIQHandler,                   // 23 - USB FIQ
+    ADC_IRQHandler,                   // 24 - ADC (A/D Converter)
+    WDT_IRQHandler,                   // 25 - WDT (Watchdog Timer)
+    BOD_IRQHandler,                   // 26 - BOD (Brownout Detect)
+    FMC_IRQHandler,                   // 27 - IP2111 Flash Memory Controller
+    0,                                // 28 - Reserved
+    0,                                // 29 - Reserved
+    USBWakeup_IRQHandler,             // 30 - USB wake-up interrupt
+    0,                                // 31 - Reserved
+};
+
+//*****************************************************************************
+// Functions to carry out the initialization of RW and BSS data sections. These
+// are written as separate functions rather than being inlined within the
+// ResetISR() function in order to cope with MCUs with multiple banks of
+// memory.
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void data_init(unsigned int romstart, unsigned int start, unsigned int len) {
+	unsigned int *pulDest = (unsigned int*) start;
+	unsigned int *pulSrc = (unsigned int*) romstart;
+	unsigned int loop;
+	for (loop = 0; loop < len; loop = loop + 4)
+		*pulDest++ = *pulSrc++;
+}
+
+__attribute__ ((section(".after_vectors")))
+void bss_init(unsigned int start, unsigned int len) {
+	unsigned int *pulDest = (unsigned int*) start;
+	unsigned int loop;
+	for (loop = 0; loop < len; loop = loop + 4)
+		*pulDest++ = 0;
+}
+
+#ifndef USE_OLD_STYLE_DATA_BSS_INIT
+//*****************************************************************************
+// The following symbols are constructs generated by the linker, indicating
+// the location of various points in the "Global Section Table". This table is
+// created by the linker via the Code Red managed linker script mechanism. It
+// contains the load address, execution address and length of each RW data
+// section and the execution and length of each BSS (zero initialized) section.
+//*****************************************************************************
+extern unsigned int __data_section_table;
+extern unsigned int __data_section_table_end;
+extern unsigned int __bss_section_table;
+extern unsigned int __bss_section_table_end;
+#else
+//*****************************************************************************
+// The following symbols are constructs generated by the linker, indicating
+// the load address, execution address and length of the RW data section and
+// the execution and length of the BSS (zero initialized) section.
+// Note that these symbols are not normally used by the managed linker script
+// mechanism in Red Suite/LPCXpresso 3.6 (Windows) and LPCXpresso 3.8 (Linux).
+// They are provide here simply so this startup code can be used with earlier
+// versions of Red Suite which do not support the more advanced managed linker
+// script mechanism introduced in the above version. To enable their use,
+// define "USE_OLD_STYLE_DATA_BSS_INIT".
+//*****************************************************************************
+extern unsigned int _etext;
+extern unsigned int _data;
+extern unsigned int _edata;
+extern unsigned int _bss;
+extern unsigned int _ebss;
+#endif
+
+
+//*****************************************************************************
+// Reset entry point for your code.
+// Sets up a simple runtime environment and initializes the C/C++
+// library.
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void
+ResetISR(void) {
+
+#ifndef USE_OLD_STYLE_DATA_BSS_INIT
+    //
+    // Copy the data sections from flash to SRAM.
+    //
+	unsigned int LoadAddr, ExeAddr, SectionLen;
+	unsigned int *SectionTableAddr;
+
+	// Load base address of Global Section Table
+	SectionTableAddr = &__data_section_table;
+
+    // Copy the data sections from flash to SRAM.
+	while (SectionTableAddr < &__data_section_table_end) {
+		LoadAddr = *SectionTableAddr++;
+		ExeAddr = *SectionTableAddr++;
+		SectionLen = *SectionTableAddr++;
+		data_init(LoadAddr, ExeAddr, SectionLen);
+	}
+	// At this point, SectionTableAddr = &__bss_section_table;
+	// Zero fill the bss segment
+	while (SectionTableAddr < &__bss_section_table_end) {
+		ExeAddr = *SectionTableAddr++;
+		SectionLen = *SectionTableAddr++;
+		bss_init(ExeAddr, SectionLen);
+	}
+#else
+	// Use Old Style Data and BSS section initialization.
+	// This will only initialize a single RAM bank.
+	unsigned int * LoadAddr, *ExeAddr, *EndAddr, SectionLen;
+
+    // Copy the data segment from flash to SRAM.
+	LoadAddr = &_etext;
+	ExeAddr = &_data;
+	EndAddr = &_edata;
+	SectionLen = (void*)EndAddr - (void*)ExeAddr;
+	data_init((unsigned int)LoadAddr, (unsigned int)ExeAddr, SectionLen);
+	// Zero fill the bss segment
+	ExeAddr = &_bss;
+	EndAddr = &_ebss;
+	SectionLen = (void*)EndAddr - (void*)ExeAddr;
+	bss_init ((unsigned int)ExeAddr, SectionLen);
+#endif
+
+#ifdef __USE_CMSIS
+	SystemInit();
+#endif
+
+#if defined (__cplusplus)
+	//
+	// Call C++ library initialisation
+	//
+	__libc_init_array();
+#endif
+
+#if defined (__REDLIB__)
+	// Call the Redlib library, which in turn calls main()
+__main() ;
+#else
+	main();
+#endif
+	//
+	// main() shouldn't return, but if it does, we'll just enter an infinite loop
+	//
+	while (1) {
+		;
+	}
+}
+
+//*****************************************************************************
+// Default exception handlers. Override the ones here by defining your own
+// handler routines in your application code.
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void NMI_Handler(void)
+{
+    while(1)
+    {
+    }
+}
+__attribute__ ((section(".after_vectors")))
+void HardFault_Handler(void)
+{
+    while(1)
+    {
+    }
+}
+__attribute__ ((section(".after_vectors")))
+void SVC_Handler(void)
+{
+    while(1)
+    {
+    }
+}
+__attribute__ ((section(".after_vectors")))
+void PendSV_Handler(void)
+{
+    while(1)
+    {
+    }
+}
+__attribute__ ((section(".after_vectors")))
+void SysTick_Handler(void)
+{
+    while(1)
+    {
+    }
+}
+
+//*****************************************************************************
+//
+// Processor ends up here if an unexpected interrupt occurs or a specific
+// handler is not present in the application code.
+//
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void IntDefaultHandler(void)
+{
+    while(1)
+    {
+    }
+}
+
+#elif defined CFG_MCU_FAMILY_LPC13UXX
+/* LPC11U37 Startup Code */
+
+//*****************************************************************************
+//   +--+       
+//   | ++----+   
+//   +-++    |  
+//     |     |  
+//   +-+--+  |   
+//   | +--+--+  
+//   +----+    Copyright (c) 2012 Code Red Technologies Ltd.
+//
+// NXP LPC13U Microcontroller Startup code for use with Red Suite
+//
+// Version : 120202
+//
+// Software License Agreement
+// 
+// The software is owned by Code Red Technologies and/or its suppliers, and is 
+// protected under applicable copyright laws.  All rights are reserved.  Any 
+// use in violation of the foregoing restrictions may subject the user to criminal 
+// sanctions under applicable laws, as well as to civil liability for the breach 
+// of the terms and conditions of this license.
+// 
+// THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
+// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
+// CODE RED TECHNOLOGIES LTD. 
+//
+//*****************************************************************************
+#if defined (__cplusplus)
+#ifdef __REDLIB__
+#error Redlib does not support C++
+#else
+//*****************************************************************************
+//
+// The entry point for the C++ library startup
+//
+//*****************************************************************************
+extern "C" {
+	extern void __libc_init_array(void);
+}
+#endif
+#endif
+
+#define WEAK __attribute__ ((weak))
+#define ALIAS(f) __attribute__ ((weak, alias (#f)))
+
+// Code Red - if CMSIS is being used, then SystemInit() routine
+// will be called by startup code rather than in application's main()
+#if defined (__USE_CMSIS)
+#include "LPC13Uxx.h"
+#endif
+
+//*****************************************************************************
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+//*****************************************************************************
+//
+// Forward declaration of the default handlers. These are aliased.
+// When the application defines a handler (with the same name), this will 
+// automatically take precedence over these weak definitions
+//
+//*****************************************************************************
+void ResetISR(void);
+WEAK void NMI_Handler(void);
+WEAK void HardFault_Handler(void);
+WEAK void MemManage_Handler(void);
+WEAK void BusFault_Handler(void);
+WEAK void UsageFault_Handler(void);
+WEAK void SVC_Handler(void);
+WEAK void DebugMon_Handler(void);
+WEAK void PendSV_Handler(void);
+WEAK void SysTick_Handler(void);
+WEAK void IntDefaultHandler(void);
+//*****************************************************************************
+//
+// Forward declaration of the specific IRQ handlers. These are aliased
+// to the IntDefaultHandler, which is a 'forever' loop. When the application
+// defines a handler (with the same name), this will automatically take 
+// precedence over these weak definitions
+//
+//*****************************************************************************
+void PIN_INT0_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT1_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT2_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT3_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT4_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT5_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT6_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT7_IRQHandler(void) ALIAS(IntDefaultHandler);
+void GINT0_IRQHandler(void) ALIAS(IntDefaultHandler);
+void GINT1_IRQHandler(void) ALIAS(IntDefaultHandler);
+void OSTIMER_IRQHandler(void) ALIAS(IntDefaultHandler);
+void SSP1_IRQHandler(void) ALIAS(IntDefaultHandler);
+void I2C_IRQHandler(void) ALIAS(IntDefaultHandler);
+void CT16B0_IRQHandler(void) ALIAS(IntDefaultHandler);
+void CT16B1_IRQHandler(void) ALIAS(IntDefaultHandler);
+void CT32B0_IRQHandler(void) ALIAS(IntDefaultHandler);
+void CT32B1_IRQHandler(void) ALIAS(IntDefaultHandler);
+void SSP0_IRQHandler(void) ALIAS(IntDefaultHandler);
+void USART_IRQHandler(void) ALIAS(IntDefaultHandler);
+void USB_IRQHandler(void) ALIAS(IntDefaultHandler);
+void USB_FIQHandler(void) ALIAS(IntDefaultHandler);
+void ADC_IRQHandler(void) ALIAS(IntDefaultHandler);
+void WDT_IRQHandler(void) ALIAS(IntDefaultHandler);
+void BOD_IRQHandler(void) ALIAS(IntDefaultHandler);
+void FMC_IRQHandler(void) ALIAS(IntDefaultHandler);
+void OSCFAIL_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PVTCIRCUIT_IRQHandler(void) ALIAS(IntDefaultHandler);
+void USBWakeup_IRQHandler(void) ALIAS(IntDefaultHandler);
+
+//*****************************************************************************
+//
+// The entry point for the application.
+// __main() is the entry point for Redlib based applications
+// main() is the entry point for Newlib based applications
+//
+//*****************************************************************************
+#if defined (__REDLIB__)
+extern void __main(void);
+#else
+extern int main(void);
+#endif
+
+//*****************************************************************************
+//
+// External declaration for the pointer to the stack top from the Linker Script
+//
+//*****************************************************************************
+extern void _vStackTop(void);
+
+//*****************************************************************************
+#if defined (__cplusplus)
+} // extern "C"
+#endif
+//*****************************************************************************
+//
+// The vector table.  Note that the proper constructs must be placed on this to
+// ensure that it ends up at physical address 0x0000.0000.
+//
+//*****************************************************************************
+extern void (* const g_pfnVectors[])(void);
+__attribute__ ((section(".isr_vector")))
+void (* const g_pfnVectors[])(void) = {
+	// Core Level - CM3
+		&_vStackTop, // The initial stack pointer
+		ResetISR, // The reset handler
+		NMI_Handler, // The NMI handler
+		HardFault_Handler, // The hard fault handler
+		MemManage_Handler, // The MPU fault handler
+		BusFault_Handler, // The bus fault handler
+		UsageFault_Handler, // The usage fault handler
+		0, // Reserved
+		0, // Reserved
+		0, // Reserved
+		0, // Reserved
+		SVC_Handler, // SVCall handler
+		DebugMon_Handler, // Debug monitor handler
+		0, // Reserved
+		PendSV_Handler, // The PendSV handler
+		SysTick_Handler, // The SysTick handler
+
+        // LPC13U External Interrupts
+		PIN_INT0_IRQHandler,	// All GPIO pin can be routed to PIN_INTx
+		PIN_INT1_IRQHandler,
+		PIN_INT2_IRQHandler,
+		PIN_INT3_IRQHandler,
+		PIN_INT4_IRQHandler,
+		PIN_INT5_IRQHandler,
+		PIN_INT6_IRQHandler,
+		PIN_INT7_IRQHandler,
+		GINT0_IRQHandler,
+		GINT1_IRQHandler,		// PIO0 (0:7)
+		0,
+		0,
+		OSTIMER_IRQHandler,
+		0,
+		SSP1_IRQHandler,		// SSP1
+		I2C_IRQHandler,        	//  I2C
+		CT16B0_IRQHandler,		// 16-bit Timer0
+		CT16B1_IRQHandler,      // 16-bit Timer1
+		CT32B0_IRQHandler,      // 32-bit Timer0
+		CT32B1_IRQHandler,      // 32-bit Timer1
+		SSP0_IRQHandler,        // SSP0
+		USART_IRQHandler,       // USART
+		USB_IRQHandler,         // USB IRQ
+		USB_FIQHandler,         // USB FIQ
+		ADC_IRQHandler,         // A/D Converter
+		WDT_IRQHandler,         // Watchdog timer
+		BOD_IRQHandler,         // Brown Out Detect
+		FMC_IRQHandler,         // IP2111 Flash Memory Controller
+		OSCFAIL_IRQHandler,     // OSC FAIL
+		PVTCIRCUIT_IRQHandler,  // PVT CIRCUIT
+		USBWakeup_IRQHandler,   // USB wake up
+		0,
+	};
+
+//*****************************************************************************
+// Functions to carry out the initialization of RW and BSS data sections. These
+// are written as separate functions rather than being inlined within the
+// ResetISR() function in order to cope with MCUs with multiple banks of
+// memory.
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void data_init(unsigned int romstart, unsigned int start, unsigned int len) {
+	unsigned int *pulDest = (unsigned int*) start;
+	unsigned int *pulSrc = (unsigned int*) romstart;
+	unsigned int loop;
+	for (loop = 0; loop < len; loop = loop + 4)
+		*pulDest++ = *pulSrc++;
+}
+
+__attribute__ ((section(".after_vectors")))
+void bss_init(unsigned int start, unsigned int len) {
+	unsigned int *pulDest = (unsigned int*) start;
+	unsigned int loop;
+	for (loop = 0; loop < len; loop = loop + 4)
+		*pulDest++ = 0;
+}
+
+//*****************************************************************************
+// The following symbols are constructs generated by the linker, indicating
+// the location of various points in the "Global Section Table". This table is
+// created by the linker via the Code Red managed linker script mechanism. It
+// contains the load address, execution address and length of each RW data
+// section and the execution and length of each BSS (zero initialized) section.
+//*****************************************************************************
+extern unsigned int __data_section_table;
+extern unsigned int __data_section_table_end;
+extern unsigned int __bss_section_table;
+extern unsigned int __bss_section_table_end;
+
+//*****************************************************************************
+// Reset entry point for your code.
+// Sets up a simple runtime environment and initializes the C/C++
+// library.
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void
+ResetISR(void) {
+
+    //
+    // Copy the data sections from flash to SRAM.
+    //
+	unsigned int LoadAddr, ExeAddr, SectionLen;
+	unsigned int *SectionTableAddr;
+
+	// Load base address of Global Section Table
+	SectionTableAddr = &__data_section_table;
+
+    // Copy the data sections from flash to SRAM.
+	while (SectionTableAddr < &__data_section_table_end) {
+		LoadAddr = *SectionTableAddr++;
+		ExeAddr = *SectionTableAddr++;
+		SectionLen = *SectionTableAddr++;
+		data_init(LoadAddr, ExeAddr, SectionLen);
+	}
+	// At this point, SectionTableAddr = &__bss_section_table;
+	// Zero fill the bss segment
+	while (SectionTableAddr < &__bss_section_table_end) {
+		ExeAddr = *SectionTableAddr++;
+		SectionLen = *SectionTableAddr++;
+		bss_init(ExeAddr, SectionLen);
+	}
+
+#ifdef __USE_CMSIS
+	SystemInit();
+#endif
+
+#if defined (__cplusplus)
+	//
+	// Call C++ library initialisation
+	//
+	__libc_init_array();
+#endif
+
+#if defined (__REDLIB__)
+	// Call the Redlib library, which in turn calls main()
+__main() ;
+#else
+	main();
+#endif
+	//
+	// main() shouldn't return, but if it does, we'll just enter an infinite loop
+	//
+	while (1) {
+		;
+	}
+}
+
+//*****************************************************************************
+// Default exception handlers. Override the ones here by defining your own
+// handler routines in your application code.
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void NMI_Handler(void) {
+	while (1) {
+	}
+}
+__attribute__ ((section(".after_vectors")))
+void HardFault_Handler(void) {
+	while (1) {
+	}
+}
+__attribute__ ((section(".after_vectors")))
+void MemManage_Handler(void) {
+	while (1) {
+	}
+}
+__attribute__ ((section(".after_vectors")))
+void BusFault_Handler(void) {
+	while (1) {
+	}
+}
+__attribute__ ((section(".after_vectors")))
+void UsageFault_Handler(void) {
+	while (1) {
+	}
+}
+__attribute__ ((section(".after_vectors")))
+void SVC_Handler(void) {
+	while (1) {
+	}
+}
+__attribute__ ((section(".after_vectors")))
+void DebugMon_Handler(void) {
+	while (1) {
+	}
+}
+__attribute__ ((section(".after_vectors")))
+void PendSV_Handler(void) {
+	while (1) {
+	}
+}
+__attribute__ ((section(".after_vectors")))
+void SysTick_Handler(void) {
+	while (1) {
+	}
+}
+
+//*****************************************************************************
+//
+// Processor ends up here if an unexpected interrupt occurs or a handler
+// is not present in the application code.
+//
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void IntDefaultHandler(void) {
+	//
+	// Go into an infinite loop.
+	//
+	while (1) {
+	}
+}
+
+#else
+#error "cr_startup.c: No MCU defined"
+#endif
+
+
+
diff --git a/reform2-lpc-fw/cmsis/startup_lpc13u_gnumake.c b/reform2-lpc-fw/cmsis/startup_lpc13u_gnumake.c
new file mode 100644
index 0000000000000000000000000000000000000000..701c62714a30d92fbdcfc5365ce457a321293056
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/startup_lpc13u_gnumake.c
@@ -0,0 +1,316 @@
+/*================================*/
+/*=====LPC11XX GNU STARTUP========*/
+/*==A CODERED COMPATIBLE STARTUP==*/
+/*================================*/
+#if defined (__cplusplus)
+#ifdef __REDLIB__
+#error Redlib does not support C++
+#else
+//*****************************************************************************
+//
+// The entry point for the C++ library startup
+//
+//*****************************************************************************
+extern "C"
+{
+  extern void __libc_init_array(void);
+}
+#endif
+#endif
+
+#define WEAK __attribute__ ((weak))
+#define ALIAS(f) __attribute__ ((weak, alias (#f)))
+
+#include "LPC13Uxx.h"
+
+//*****************************************************************************
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+extern unsigned int __data_load_addr;
+extern unsigned int __data_start;
+extern unsigned int __data_end;
+extern unsigned int __bss_start;
+extern unsigned int __bss_end;
+extern unsigned int __StackTop;
+#ifdef FIXED_STACKHEAP_SIZE
+#define STACK_SIZE  (800)
+#define HEAP_SIZE  (200)
+unsigned char StackMem[STACK_SIZE] __attribute__ ((section(".stack")));
+unsigned char HeapMem[HEAP_SIZE] __attribute__ ((section(".heap"), align(8)));
+#endif
+//*****************************************************************************
+//
+// Forward declaration of the default handlers. These are aliased.
+// When the application defines a handler (with the same name), this will
+// automatically take precedence over these weak definitions
+//
+//*****************************************************************************
+     void Reset_Handler(void);
+WEAK void NMI_Handler(void);
+WEAK void HardFault_Handler(void);
+WEAK void MemManage_Handler(void);
+WEAK void BusFault_Handler(void);
+WEAK void UsageFault_Handler(void);
+WEAK void SVC_Handler(void);
+WEAK void DebugMon_Handler(void);
+WEAK void PendSV_Handler(void);
+WEAK void SysTick_Handler(void);
+WEAK void IntDefaultHandler(void);
+//*****************************************************************************
+//
+// Forward declaration of the specific IRQ handlers. These are aliased
+// to the IntDefaultHandler, which is a 'forever' loop. When the application
+// defines a handler (with the same name), this will automatically take
+// precedence over these weak definitions
+//
+//*****************************************************************************
+void PIN_INT0_IRQHandler   (void) ALIAS(IntDefaultHandler);
+void PIN_INT1_IRQHandler   (void) ALIAS(IntDefaultHandler);
+void PIN_INT2_IRQHandler   (void) ALIAS(IntDefaultHandler);
+void PIN_INT3_IRQHandler   (void) ALIAS(IntDefaultHandler);
+void PIN_INT4_IRQHandler   (void) ALIAS(IntDefaultHandler);
+void PIN_INT5_IRQHandler   (void) ALIAS(IntDefaultHandler);
+void PIN_INT6_IRQHandler   (void) ALIAS(IntDefaultHandler);
+void PIN_INT7_IRQHandler   (void) ALIAS(IntDefaultHandler);
+void GINT0_IRQHandler      (void) ALIAS(IntDefaultHandler);
+void GINT1_IRQHandler      (void) ALIAS(IntDefaultHandler);
+void OSTIMER_IRQHandler    (void) ALIAS(IntDefaultHandler);
+void SSP1_IRQHandler       (void) ALIAS(IntDefaultHandler);
+void I2C_IRQHandler        (void) ALIAS(IntDefaultHandler);
+void CT16B0_IRQHandler     (void) ALIAS(IntDefaultHandler);
+void CT16B1_IRQHandler     (void) ALIAS(IntDefaultHandler);
+void CT32B0_IRQHandler     (void) ALIAS(IntDefaultHandler);
+void CT32B1_IRQHandler     (void) ALIAS(IntDefaultHandler);
+void SSP0_IRQHandler       (void) ALIAS(IntDefaultHandler);
+void USART_IRQHandler      (void) ALIAS(IntDefaultHandler);
+void USB_IRQHandler        (void) ALIAS(IntDefaultHandler);
+void USB_FIQHandler        (void) ALIAS(IntDefaultHandler);
+void ADC_IRQHandler        (void) ALIAS(IntDefaultHandler);
+void WDT_IRQHandler        (void) ALIAS(IntDefaultHandler);
+void BOD_IRQHandler        (void) ALIAS(IntDefaultHandler);
+void FMC_IRQHandler        (void) ALIAS(IntDefaultHandler);
+void OSCFAIL_IRQHandler    (void) ALIAS(IntDefaultHandler);
+void PVTCIRCUIT_IRQHandler (void) ALIAS(IntDefaultHandler);
+void USBWakeup_IRQHandler  (void) ALIAS(IntDefaultHandler);
+
+//*****************************************************************************
+//
+// The entry point for the application.
+// __main() is the entry point for Redlib based applications
+// main() is the entry point for Newlib based applications
+//
+//*****************************************************************************
+#if defined (__REDLIB__)
+extern void __main(void);
+#else
+extern int main(void);
+#endif
+
+//*****************************************************************************
+#if defined (__cplusplus)
+} // extern "C"
+#endif
+//*****************************************************************************
+//
+// The vector table.  Note that the proper constructs must be placed on this to
+// ensure that it ends up at physical address 0x0000.0000.
+//
+//*****************************************************************************
+__attribute__ ((section(".isr_vector_table")))
+void (* const Vectors[])(void) = {
+#ifdef FIXED_STACKHEAP_SIZE
+  (void (*)(void))(StackMem + STACK_SIZE),          // The initial stack pointer
+#else
+  (void (*)(void))&__StackTop,
+#endif
+  Reset_Handler,            // The reset handler
+  NMI_Handler,              // The NMI handler
+  HardFault_Handler,        // The hard fault handler
+  MemManage_Handler,        // The MPU fault handler
+  BusFault_Handler,          // The bus fault handler
+  UsageFault_Handler,        // The usage fault handler
+  0,                        // Reserved
+  0,                        // Reserved
+  0,                        // Reserved
+  0,                        // Reserved
+  SVC_Handler,              // SVCall handler
+  DebugMon_Handler,          // Debug monitor handler
+  0,                        // Reserved
+  PendSV_Handler,            // The PendSV handler
+  SysTick_Handler,          // The SysTick handler
+
+  // LPC13U External Interrupts
+  PIN_INT0_IRQHandler,      // All GPIO pin can be routed to PIN_INTx
+  PIN_INT1_IRQHandler,
+  PIN_INT2_IRQHandler,
+  PIN_INT3_IRQHandler,
+  PIN_INT4_IRQHandler,
+  PIN_INT5_IRQHandler,
+  PIN_INT6_IRQHandler,
+  PIN_INT7_IRQHandler,
+  GINT0_IRQHandler,
+  GINT1_IRQHandler,          // PIO0 (0:7)
+  0,
+  0,
+  OSTIMER_IRQHandler,
+  0,
+  SSP1_IRQHandler,          // SSP1
+  I2C_IRQHandler,            //  I2C
+  CT16B0_IRQHandler,        // 16-bit Timer0
+  CT16B1_IRQHandler,        // 16-bit Timer1
+  CT32B0_IRQHandler,        // 32-bit Timer0
+  CT32B1_IRQHandler,        // 32-bit Timer1
+  SSP0_IRQHandler,          // SSP0
+  USART_IRQHandler,         // USART
+  USB_IRQHandler,           // USB IRQ
+  USB_FIQHandler,           // USB FIQ
+  ADC_IRQHandler,           // A/D Converter
+  WDT_IRQHandler,           // Watchdog timer
+  BOD_IRQHandler,           // Brown Out Detect
+  FMC_IRQHandler,           // IP2111 Flash Memory Controller
+  OSCFAIL_IRQHandler,       // OSC FAIL
+  PVTCIRCUIT_IRQHandler,   // PVT CIRCUIT
+  USBWakeup_IRQHandler,     // USB wake up
+  0,
+};
+
+//*****************************************************************************
+// Reset entry point for your code.
+// Sets up a simple runtime environment and initializes the C/C++
+// library.
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void Reset_Handler(void)
+{
+  /*
+   * Only Initialize Internal SRAM
+   * USB RAM is used for USB purpose
+   */
+  unsigned int *src, *dst;
+
+  /* Copy data section from flash to RAM */
+  src = &__data_load_addr;
+  dst = &__data_start;
+  while (dst < &__data_end)
+    *dst++ = *src++;
+
+  /* Zero fill the bss section */
+  dst = &__bss_start;
+  while (dst < &__bss_end)
+    *dst++ = 0;
+
+  SystemInit();
+
+#if defined (__cplusplus)
+  //
+  // Call C++ library initialisation
+  //
+  __libc_init_array();
+#endif
+
+#if defined (__REDLIB__)
+  // Call the Redlib library, which in turn calls main()
+  __main() ;
+#else
+  main();
+#endif
+	//
+	// main() shouldn't return, but if it does, we'll just enter an infinite loop
+	//
+	while (1) {
+		;
+	}
+}
+
+//*****************************************************************************
+//
+// This is the code that gets called when the processor receives a NMI.  This
+// simply enters an infinite loop, preserving the system state for examination
+// by a debugger.
+//
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void NMI_Handler(void)
+{
+    while(1)
+    {
+    }
+}
+
+__attribute__ ((section(".after_vectors")))
+void HardFault_Handler(void)
+{
+    while(1)
+    {
+    }
+}
+
+__attribute__ ((section(".after_vectors")))
+void MemManage_Handler(void)
+{
+    while(1)
+    {
+    }
+}
+
+__attribute__ ((section(".after_vectors")))
+void BusFault_Handler(void)
+{
+    while(1)
+    {
+    }
+}
+
+__attribute__ ((section(".after_vectors")))
+void UsageFault_Handler(void)
+{
+    while(1)
+    {
+    }
+}
+
+__attribute__ ((section(".after_vectors")))
+void SVCall_Handler(void)
+{
+    while(1)
+    {
+    }
+}
+__attribute__ ((section(".after_vectors")))
+void DebugMon_Handler(void)
+{
+    while(1)
+    {
+    }
+}
+
+__attribute__ ((section(".after_vectors")))
+void PendSV_Handler(void)
+{
+    while(1)
+    {
+    }
+}
+__attribute__ ((section(".after_vectors")))
+void SysTick_Handler(void)
+{
+    while(1)
+    {
+    }
+}
+
+//*****************************************************************************
+//
+// Processor ends up here if an unexpected interrupt occurs or a handler
+// is not present in the application code.
+//
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void IntDefaultHandler(void)
+{
+    while(1)
+    {
+    }
+}
diff --git a/reform2-lpc-fw/cmsis/system_LPC11Uxx.c b/reform2-lpc-fw/cmsis/system_LPC11Uxx.c
new file mode 100644
index 0000000000000000000000000000000000000000..f10fe23221aa0ee7dae67e8fa7a889474d3582a3
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/system_LPC11Uxx.c
@@ -0,0 +1,458 @@
+/******************************************************************************
+ * @file     system_LPC11Uxx.c
+ * @purpose  CMSIS Cortex-M3 Device Peripheral Access Layer Source File
+ *           for the NXP LPC13xx Device Series
+ * @version  V1.10
+ * @date     24. November 2010
+ *
+ * @note
+ * Copyright (C) 2009-2010 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M 
+ * processor based microcontrollers.  This file can be freely distributed 
+ * within development tools that are supporting such ARM based processors. 
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+
+#include <stdint.h>
+#include "LPC11Uxx.h"
+
+/*
+//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
+*/
+
+/*--------------------- Clock Configuration ----------------------------------
+//
+// <e> Clock Configuration
+//   <h> System Oscillator Control Register (SYSOSCCTRL)
+//     <o1.0>      BYPASS: System Oscillator Bypass Enable
+//                     <i> If enabled then PLL input (sys_osc_clk) is fed
+//                     <i> directly from XTALIN and XTALOUT pins.
+//     <o1.9>      FREQRANGE: System Oscillator Frequency Range
+//                     <i> Determines frequency range for Low-power oscillator.
+//                   <0=> 1 - 20 MHz
+//                   <1=> 15 - 25 MHz
+//   </h>
+//
+//   <h> Watchdog Oscillator Control Register (WDTOSCCTRL)
+//     <o2.0..4>   DIVSEL: Select Divider for Fclkana
+//                     <i> wdt_osc_clk = Fclkana/ (2 � (1 + DIVSEL))
+//                   <0-31>
+//     <o2.5..8>   FREQSEL: Select Watchdog Oscillator Analog Output Frequency (Fclkana)
+//                   <0=> Undefined
+//                   <1=> 0.5 MHz
+//                   <2=> 0.8 MHz
+//                   <3=> 1.1 MHz
+//                   <4=> 1.4 MHz
+//                   <5=> 1.6 MHz
+//                   <6=> 1.8 MHz
+//                   <7=> 2.0 MHz
+//                   <8=> 2.2 MHz
+//                   <9=> 2.4 MHz
+//                   <10=> 2.6 MHz
+//                   <11=> 2.7 MHz
+//                   <12=> 2.9 MHz
+//                   <13=> 3.1 MHz
+//                   <14=> 3.2 MHz
+//                   <15=> 3.4 MHz
+//   </h>
+//
+//   <h> System PLL Control Register (SYSPLLCTRL)
+//                   <i> F_clkout = M * F_clkin = F_CCO / (2 * P)
+//                   <i> F_clkin must be in the range of  10 MHz to  25 MHz
+//                   <i> F_CCO   must be in the range of 156 MHz to 320 MHz
+//     <o3.0..4>   MSEL: Feedback Divider Selection
+//                     <i> M = MSEL + 1
+//                   <0-31>
+//     <o3.5..6>   PSEL: Post Divider Selection
+//                   <0=> P = 1
+//                   <1=> P = 2
+//                   <2=> P = 4
+//                   <3=> P = 8
+//   </h>
+//
+//   <h> System PLL Clock Source Select Register (SYSPLLCLKSEL)
+//     <o4.0..1>   SEL: System PLL Clock Source
+//                   <0=> IRC Oscillator
+//                   <1=> System Oscillator
+//                   <2=> Reserved
+//                   <3=> Reserved
+//   </h>
+//
+//   <h> Main Clock Source Select Register (MAINCLKSEL)
+//     <o5.0..1>   SEL: Clock Source for Main Clock
+//                   <0=> IRC Oscillator
+//                   <1=> Input Clock to System PLL
+//                   <2=> WDT Oscillator
+//                   <3=> System PLL Clock Out
+//   </h>
+//
+//   <h> System AHB Clock Divider Register (SYSAHBCLKDIV)
+//     <o6.0..7>   DIV: System AHB Clock Divider
+//                     <i> Divides main clock to provide system clock to core, memories, and peripherals.
+//                     <i> 0 = is disabled
+//                   <0-255>
+//   </h>
+//
+//   <h> USB PLL Control Register (USBPLLCTRL)
+//                   <i> F_clkout = M * F_clkin = F_CCO / (2 * P)
+//                   <i> F_clkin must be in the range of  10 MHz to  25 MHz
+//                   <i> F_CCO   must be in the range of 156 MHz to 320 MHz
+//     <o7.0..4>   MSEL: Feedback Divider Selection
+//                     <i> M = MSEL + 1
+//                   <0-31>
+//     <o7.5..6>   PSEL: Post Divider Selection
+//                   <0=> P = 1
+//                   <1=> P = 2
+//                   <2=> P = 4
+//                   <3=> P = 8
+//   </h>
+//
+//   <h> USB PLL Clock Source Select Register (USBPLLCLKSEL)
+//     <o8.0..1>   SEL: USB PLL Clock Source
+//                     <i> USB PLL clock source must be switched to System Oscillator for correct USB operation
+//                   <0=> IRC Oscillator
+//                   <1=> System Oscillator
+//                   <2=> Reserved
+//                   <3=> Reserved
+//   </h>
+//
+//   <h> USB Clock Source Select Register (USBCLKSEL)
+//     <o9.0..1>   SEL: System PLL Clock Source
+//                   <0=> USB PLL out
+//                   <1=> Main clock
+//                   <2=> Reserved
+//                   <3=> Reserved
+//   </h>
+//
+//   <h> USB Clock Divider Register (USBCLKDIV)
+//     <o10.0..7>  DIV: USB Clock Divider
+//                     <i> Divides USB clock to 48 MHz.
+//                     <i> 0 = is disabled
+//                   <0-255>
+//   </h>
+// </e>
+*/
+#define CLOCK_SETUP           1
+#define SYSOSCCTRL_Val        0x00000000              // Reset: 0x000
+#define WDTOSCCTRL_Val        0x00000000              // Reset: 0x000
+#define SYSPLLCTRL_Val        0x00000023              // Reset: 0x000
+#define SYSPLLCLKSEL_Val      0x00000001              // Reset: 0x000
+#define MAINCLKSEL_Val        0x00000003              // Reset: 0x000
+#define SYSAHBCLKDIV_Val      0x00000001              // Reset: 0x001
+#define USBPLLCTRL_Val        0x00000023              // Reset: 0x000
+#define USBPLLCLKSEL_Val      0x00000001              // Reset: 0x000
+#define USBCLKSEL_Val         0x00000000              // Reset: 0x000
+#define USBCLKDIV_Val         0x00000001              // Reset: 0x001
+
+/*
+//-------- <<< end of configuration section >>> ------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+  Check the register settings
+ *----------------------------------------------------------------------------*/
+#define CHECK_RANGE(val, min, max)                ((val < min) || (val > max))
+#define CHECK_RSVD(val, mask)                     (val & mask)
+
+/* Clock Configuration -------------------------------------------------------*/
+#if (CHECK_RSVD((SYSOSCCTRL_Val),  ~0x00000003))
+   #error "SYSOSCCTRL: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RSVD((WDTOSCCTRL_Val),  ~0x000001FF))
+   #error "WDTOSCCTRL: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RANGE((SYSPLLCLKSEL_Val), 0, 2))
+   #error "SYSPLLCLKSEL: Value out of range!"
+#endif
+
+#if (CHECK_RSVD((SYSPLLCTRL_Val),  ~0x000001FF))
+   #error "SYSPLLCTRL: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RSVD((MAINCLKSEL_Val),  ~0x00000003))
+   #error "MAINCLKSEL: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RANGE((SYSAHBCLKDIV_Val), 0, 255))
+   #error "SYSAHBCLKDIV: Value out of range!"
+#endif
+
+#if (CHECK_RANGE((USBPLLCLKSEL_Val), 0, 1))
+   #error "USBPLLCLKSEL: Value out of range!"
+#endif
+
+#if (CHECK_RSVD((USBPLLCTRL_Val),  ~0x000001FF))
+   #error "USBPLLCTRL: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RANGE((USBCLKSEL_Val), 0, 1))
+   #error "USBCLKSEL: Value out of range!"
+#endif
+
+#if (CHECK_RANGE((USBCLKDIV_Val), 0, 255))
+   #error "USBCLKDIV: Value out of range!"
+#endif
+
+
+/*----------------------------------------------------------------------------
+  DEFINES
+ *----------------------------------------------------------------------------*/
+    
+/*----------------------------------------------------------------------------
+  Define clocks
+ *----------------------------------------------------------------------------*/
+#define __XTAL            (12000000UL)    /* Oscillator frequency             */
+#define __SYS_OSC_CLK     (    __XTAL)    /* Main oscillator frequency        */
+#define __IRC_OSC_CLK     (12000000UL)    /* Internal RC oscillator frequency */
+
+
+#define __FREQSEL   ((WDTOSCCTRL_Val >> 5) & 0x0F)
+#define __DIVSEL   (((WDTOSCCTRL_Val & 0x1F) << 1) + 2)
+
+#if (CLOCK_SETUP)                         /* Clock Setup              */
+  #if  (__FREQSEL ==  0)
+    #define __WDT_OSC_CLK        ( 0)                  /* undefined */
+  #elif (__FREQSEL ==  1)
+    #define __WDT_OSC_CLK        ( 500000 / __DIVSEL)
+  #elif (__FREQSEL ==  2)
+    #define __WDT_OSC_CLK        ( 800000 / __DIVSEL)
+  #elif (__FREQSEL ==  3)
+    #define __WDT_OSC_CLK        (1100000 / __DIVSEL)
+  #elif (__FREQSEL ==  4)
+    #define __WDT_OSC_CLK        (1400000 / __DIVSEL)
+  #elif (__FREQSEL ==  5)
+    #define __WDT_OSC_CLK        (1600000 / __DIVSEL)
+  #elif (__FREQSEL ==  6)
+    #define __WDT_OSC_CLK        (1800000 / __DIVSEL)
+  #elif (__FREQSEL ==  7)
+    #define __WDT_OSC_CLK        (2000000 / __DIVSEL)
+  #elif (__FREQSEL ==  8)
+    #define __WDT_OSC_CLK        (2200000 / __DIVSEL)
+  #elif (__FREQSEL ==  9)
+    #define __WDT_OSC_CLK        (2400000 / __DIVSEL)
+  #elif (__FREQSEL == 10)
+    #define __WDT_OSC_CLK        (2600000 / __DIVSEL)
+  #elif (__FREQSEL == 11)
+    #define __WDT_OSC_CLK        (2700000 / __DIVSEL)
+  #elif (__FREQSEL == 12)
+    #define __WDT_OSC_CLK        (2900000 / __DIVSEL)
+  #elif (__FREQSEL == 13)
+    #define __WDT_OSC_CLK        (3100000 / __DIVSEL)
+  #elif (__FREQSEL == 14)
+    #define __WDT_OSC_CLK        (3200000 / __DIVSEL)
+  #else
+    #define __WDT_OSC_CLK        (3400000 / __DIVSEL)
+  #endif
+
+  /* sys_pllclkin calculation */
+  #if   ((SYSPLLCLKSEL_Val & 0x03) == 0)
+    #define __SYS_PLLCLKIN           (__IRC_OSC_CLK)
+  #elif ((SYSPLLCLKSEL_Val & 0x03) == 1)
+    #define __SYS_PLLCLKIN           (__SYS_OSC_CLK)
+  #else
+    #define __SYS_PLLCLKIN           (0)
+  #endif
+
+  #define  __SYS_PLLCLKOUT         (__SYS_PLLCLKIN * ((SYSPLLCTRL_Val & 0x01F) + 1))
+
+  /* main clock calculation */
+  #if   ((MAINCLKSEL_Val & 0x03) == 0)
+    #define __MAIN_CLOCK             (__IRC_OSC_CLK)
+  #elif ((MAINCLKSEL_Val & 0x03) == 1)
+    #define __MAIN_CLOCK             (__SYS_PLLCLKIN)
+  #elif ((MAINCLKSEL_Val & 0x03) == 2)
+    #if (__FREQSEL ==  0)
+      #error "MAINCLKSEL: WDT Oscillator selected but FREQSEL is undefined!"
+    #else
+      #define __MAIN_CLOCK           (__WDT_OSC_CLK)
+    #endif
+  #elif ((MAINCLKSEL_Val & 0x03) == 3)
+    #define __MAIN_CLOCK             (__SYS_PLLCLKOUT)
+  #else
+    #define __MAIN_CLOCK             (0)
+  #endif
+
+  #define __SYSTEM_CLOCK             (__MAIN_CLOCK / SYSAHBCLKDIV_Val)         
+
+#else
+  #define __SYSTEM_CLOCK             (__IRC_OSC_CLK)
+#endif  // CLOCK_SETUP 
+
+
+/*----------------------------------------------------------------------------
+  Clock Variable definitions
+ *----------------------------------------------------------------------------*/
+uint32_t SystemCoreClock = __SYSTEM_CLOCK;/*!< System Clock Frequency (Core Clock)*/
+
+
+/*----------------------------------------------------------------------------
+  Clock functions
+ *----------------------------------------------------------------------------*/
+void SystemCoreClockUpdate (void)            /* Get Core Clock Frequency      */
+{
+  uint32_t wdt_osc = 0;
+
+  /* Determine clock frequency according to clock register values             */
+  switch ((LPC_SYSCON->WDTOSCCTRL >> 5) & 0x0F) {
+    case 0:  wdt_osc =       0; break;
+    case 1:  wdt_osc =  500000; break;
+    case 2:  wdt_osc =  800000; break;
+    case 3:  wdt_osc = 1100000; break;
+    case 4:  wdt_osc = 1400000; break;
+    case 5:  wdt_osc = 1600000; break;
+    case 6:  wdt_osc = 1800000; break;
+    case 7:  wdt_osc = 2000000; break;
+    case 8:  wdt_osc = 2200000; break;
+    case 9:  wdt_osc = 2400000; break;
+    case 10: wdt_osc = 2600000; break;
+    case 11: wdt_osc = 2700000; break;
+    case 12: wdt_osc = 2900000; break;
+    case 13: wdt_osc = 3100000; break;
+    case 14: wdt_osc = 3200000; break;
+    case 15: wdt_osc = 3400000; break;
+  }
+  wdt_osc /= ((LPC_SYSCON->WDTOSCCTRL & 0x1F) << 1) + 2;
+ 
+  switch (LPC_SYSCON->MAINCLKSEL & 0x03) {
+    case 0:                             /* Internal RC oscillator             */
+      SystemCoreClock = __IRC_OSC_CLK;
+      break;
+    case 1:                             /* Input Clock to System PLL          */
+      switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
+          case 0:                       /* Internal RC oscillator             */
+            SystemCoreClock = __IRC_OSC_CLK;
+            break;
+          case 1:                       /* System oscillator                  */
+            SystemCoreClock = __SYS_OSC_CLK;
+            break;
+          case 2:                       /* Reserved                           */
+          case 3:                       /* Reserved                           */
+            SystemCoreClock = 0;
+            break;
+      }
+      break;
+    case 2:                             /* WDT Oscillator                     */
+      SystemCoreClock = wdt_osc;
+      break;
+    case 3:                             /* System PLL Clock Out               */
+      switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
+          case 0:                       /* Internal RC oscillator             */
+            if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
+              SystemCoreClock = __IRC_OSC_CLK;
+            } else {
+              SystemCoreClock = __IRC_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
+            }
+            break;
+          case 1:                       /* System oscillator                  */
+            if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
+              SystemCoreClock = __SYS_OSC_CLK;
+            } else {
+              SystemCoreClock = __SYS_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
+            }
+            break;
+          case 2:                       /* Reserved                           */
+          case 3:                       /* Reserved                           */
+            SystemCoreClock = 0;
+            break;
+      }
+      break;
+  }
+
+  SystemCoreClock /= LPC_SYSCON->SYSAHBCLKDIV;  
+
+}
+
+/**
+ * Initialize the system
+ *
+ * @param  none
+ * @return none
+ *
+ * @brief  Setup the microcontroller system.
+ *         Initialize the System.
+ */
+void SystemInit (void) {
+  volatile uint32_t i;
+
+#if (CLOCK_SETUP)                                 /* Clock Setup              */
+
+#if ((SYSPLLCLKSEL_Val & 0x03) == 1)
+  LPC_SYSCON->PDRUNCFG     &= ~(1 << 5);          /* Power-up System Osc      */
+  LPC_SYSCON->SYSOSCCTRL    = SYSOSCCTRL_Val;
+  for (i = 0; i < 200; i++) __NOP();
+#endif
+
+  LPC_SYSCON->SYSPLLCLKSEL  = SYSPLLCLKSEL_Val;   /* Select PLL Input         */
+  LPC_SYSCON->SYSPLLCLKUEN  = 0x01;               /* Update Clock Source      */
+  LPC_SYSCON->SYSPLLCLKUEN  = 0x00;               /* Toggle Update Register   */
+  LPC_SYSCON->SYSPLLCLKUEN  = 0x01;
+  while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01));     /* Wait Until Updated       */
+#if ((MAINCLKSEL_Val & 0x03) == 3)                /* Main Clock is PLL Out    */
+  LPC_SYSCON->SYSPLLCTRL    = SYSPLLCTRL_Val;
+  LPC_SYSCON->PDRUNCFG     &= ~(1 << 7);          /* Power-up SYSPLL          */
+  while (!(LPC_SYSCON->SYSPLLSTAT & 0x01));	      /* Wait Until PLL Locked    */
+#endif
+
+#if (((MAINCLKSEL_Val & 0x03) == 2) )
+  LPC_SYSCON->WDTOSCCTRL    = WDTOSCCTRL_Val;
+  LPC_SYSCON->PDRUNCFG     &= ~(1 << 6);          /* Power-up WDT Clock       */
+  for (i = 0; i < 200; i++) __NOP();
+#endif
+
+  LPC_SYSCON->MAINCLKSEL    = MAINCLKSEL_Val;     /* Select PLL Clock Output  */
+  LPC_SYSCON->MAINCLKUEN    = 0x01;               /* Update MCLK Clock Source */
+  LPC_SYSCON->MAINCLKUEN    = 0x00;               /* Toggle Update Register   */
+  LPC_SYSCON->MAINCLKUEN    = 0x01;
+  while (!(LPC_SYSCON->MAINCLKUEN & 0x01));       /* Wait Until Updated       */
+
+  LPC_SYSCON->SYSAHBCLKDIV  = SYSAHBCLKDIV_Val;
+
+#if ((USBCLKDIV_Val & 0x1FF) != 0)                /* USB clock is used        */
+  LPC_SYSCON->PDRUNCFG     &= ~(1 << 10);         /* Power-up USB PHY         */
+
+  /* Regardless USB PLL is used as USB clock or not, USB PLL needs to be configured. */
+  LPC_SYSCON->PDRUNCFG     &= ~(1 <<  8);         /* Power-up USB PLL         */
+  LPC_SYSCON->USBPLLCLKSEL  = USBPLLCLKSEL_Val;   /* Select PLL Input         */
+  LPC_SYSCON->USBPLLCLKUEN  = 0x01;               /* Update Clock Source      */
+  LPC_SYSCON->USBPLLCLKUEN  = 0x00;               /* Toggle Update Register   */
+  LPC_SYSCON->USBPLLCLKUEN  = 0x01;
+  while (!(LPC_SYSCON->USBPLLCLKUEN & 0x01));     /* Wait Until Updated       */
+  LPC_SYSCON->USBPLLCTRL    = USBPLLCTRL_Val;
+  while (!(LPC_SYSCON->USBPLLSTAT   & 0x01));     /* Wait Until PLL Locked    */
+
+  LPC_SYSCON->USBCLKSEL  = USBCLKSEL_Val;         /* Select USB Clock         */
+  LPC_SYSCON->USBCLKUEN  = 0x00;                  /* Toggle Update Register   */
+  LPC_SYSCON->USBCLKUEN  = 0x01;
+  LPC_SYSCON->USBCLKDIV  = USBCLKDIV_Val;         /* Set USB clock divider    */
+
+#if ((USBCLKSEL_Val & 0x003) != 0)
+/* Wait for clock switch to happen */
+  for (i = 0; i < 200; i++) __NOP();
+/* Turn-off USB PLL to save power */
+  LPC_SYSCON->PDRUNCFG     |=  (1 <<  8);         /* Power-down USB PLL       */
+#endif
+
+#else                                             /* USB clock is not used    */                        
+  LPC_SYSCON->PDRUNCFG     |=  (1 << 10);         /* Power-down USB PHY       */
+  LPC_SYSCON->PDRUNCFG     |=  (1 <<  8);         /* Power-down USB PLL       */
+#endif
+
+#endif
+
+  /* System clock to the IOCON needs to be enabled or
+  most of the I/O related peripherals won't work. */
+  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<16);
+
+}
diff --git a/reform2-lpc-fw/cmsis/system_LPC11Uxx.h b/reform2-lpc-fw/cmsis/system_LPC11Uxx.h
new file mode 100644
index 0000000000000000000000000000000000000000..aaf73f70524b7ad3aca8ec4c52e3178c0ff75b08
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/system_LPC11Uxx.h
@@ -0,0 +1,64 @@
+/**************************************************************************//**
+ * @file     system_LPC11Uxx.h
+ * @brief    CMSIS Cortex-M0 Device Peripheral Access Layer Header File
+ *           for the NXP LPC11Uxx Device Series
+ * @version  V1.10
+ * @date     24. November 2010
+ *
+ * @note
+ * Copyright (C) 2009-2010 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M 
+ * processor based microcontrollers.  This file can be freely distributed 
+ * within development tools that are supporting such ARM based processors. 
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+
+#ifndef __SYSTEM_LPC11Uxx_H
+#define __SYSTEM_LPC11Uxx_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+extern uint32_t SystemCoreClock;     /*!< System Clock Frequency (Core Clock)  */
+
+
+/**
+ * Initialize the system
+ *
+ * @param  none
+ * @return none
+ *
+ * @brief  Setup the microcontroller system.
+ *         Initialize the System and update the SystemCoreClock variable.
+ */
+extern void SystemInit (void);
+
+/**
+ * Update SystemCoreClock variable
+ *
+ * @param  none
+ * @return none
+ *
+ * @brief  Updates the SystemCoreClock with current core Clock 
+ *         retrieved from cpu registers.
+ */
+extern void SystemCoreClockUpdate (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SYSTEM_LPC11Uxx_H */
diff --git a/reform2-lpc-fw/cmsis/system_LPC13Uxx.c b/reform2-lpc-fw/cmsis/system_LPC13Uxx.c
new file mode 100644
index 0000000000000000000000000000000000000000..fbdef8a9260c9350eca985b8566db1e1ef3c5c40
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/system_LPC13Uxx.c
@@ -0,0 +1,437 @@
+/******************************************************************************
+ * @file     system_LPC13Uxx.c
+ * @purpose  CMSIS Cortex-M3 Device Peripheral Access Layer Source File
+ *           for the NXP LPC13xx Device Series
+ * @version  V1.10
+ * @date     24. November 2010
+ *
+ * @note
+ * Copyright (C) 2009-2010 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M 
+ * processor based microcontrollers.  This file can be freely distributed 
+ * within development tools that are supporting such ARM based processors. 
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+
+#include <stdint.h>
+#include "LPC13Uxx.h"
+
+/*
+//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
+*/
+
+/*--------------------- Clock Configuration ----------------------------------
+//
+// <e> Clock Configuration
+//   <h> System Oscillator Control Register (SYSOSCCTRL)
+//     <o1.0>      BYPASS: System Oscillator Bypass Enable
+//                     <i> If enabled then PLL input (sys_osc_clk) is fed
+//                     <i> directly from XTALIN and XTALOUT pins.
+//     <o1.9>      FREQRANGE: System Oscillator Frequency Range
+//                     <i> Determines frequency range for Low-power oscillator.
+//                   <0=> 1 - 20 MHz
+//                   <1=> 15 - 25 MHz
+//   </h>
+//
+//   <h> Watchdog Oscillator Control Register (WDTOSCCTRL)
+//     <o2.0..4>   DIVSEL: Select Divider for Fclkana
+//                     <i> wdt_osc_clk = Fclkana/ (2 � (1 + DIVSEL))
+//                   <0-31>
+//     <o2.5..8>   FREQSEL: Select Watchdog Oscillator Analog Output Frequency (Fclkana)
+//                   <0=> Undefined
+//                   <1=> 0.5 MHz
+//                   <2=> 0.8 MHz
+//                   <3=> 1.1 MHz
+//                   <4=> 1.4 MHz
+//                   <5=> 1.6 MHz
+//                   <6=> 1.8 MHz
+//                   <7=> 2.0 MHz
+//                   <8=> 2.2 MHz
+//                   <9=> 2.4 MHz
+//                   <10=> 2.6 MHz
+//                   <11=> 2.7 MHz
+//                   <12=> 2.9 MHz
+//                   <13=> 3.1 MHz
+//                   <14=> 3.2 MHz
+//                   <15=> 3.4 MHz
+//   </h>
+//
+//   <h> System PLL Control Register (SYSPLLCTRL)
+//                   <i> F_clkout = M * F_clkin = F_CCO / (2 * P)
+//                   <i> F_clkin must be in the range of  10 MHz to  25 MHz
+//                   <i> F_CCO   must be in the range of 156 MHz to 320 MHz
+//     <o3.0..4>   MSEL: Feedback Divider Selection
+//                     <i> M = MSEL + 1
+//                   <0-31>
+//     <o3.5..6>   PSEL: Post Divider Selection
+//                   <0=> P = 1
+//                   <1=> P = 2
+//                   <2=> P = 4
+//                   <3=> P = 8
+//   </h>
+//
+//   <h> System PLL Clock Source Select Register (SYSPLLCLKSEL)
+//     <o4.0..1>   SEL: System PLL Clock Source
+//                   <0=> IRC Oscillator
+//                   <1=> System Oscillator
+//                   <2=> Reserved
+//                   <3=> Reserved
+//   </h>
+//
+//   <h> Main Clock Source Select Register (MAINCLKSEL)
+//     <o5.0..1>   SEL: Clock Source for Main Clock
+//                   <0=> IRC Oscillator
+//                   <1=> Input Clock to System PLL
+//                   <2=> WDT Oscillator
+//                   <3=> System PLL Clock Out
+//   </h>
+//
+//   <h> System AHB Clock Divider Register (SYSAHBCLKDIV)
+//     <o6.0..7>   DIV: System AHB Clock Divider
+//                     <i> Divides main clock to provide system clock to core, memories, and peripherals.
+//                     <i> 0 = is disabled
+//                   <0-255>
+//   </h>
+//
+//   <h> USB PLL Control Register (USBPLLCTRL)
+//                   <i> F_clkout = M * F_clkin = F_CCO / (2 * P)
+//                   <i> F_clkin must be in the range of  10 MHz to  25 MHz
+//                   <i> F_CCO   must be in the range of 156 MHz to 320 MHz
+//     <o7.0..4>   MSEL: Feedback Divider Selection
+//                     <i> M = MSEL + 1
+//                   <0-31>
+//     <o7.5..6>   PSEL: Post Divider Selection
+//                   <0=> P = 1
+//                   <1=> P = 2
+//                   <2=> P = 4
+//                   <3=> P = 8
+//   </h>
+//
+//   <h> USB PLL Clock Source Select Register (USBPLLCLKSEL)
+//     <o8.0..1>   SEL: USB PLL Clock Source
+//                     <i> USB PLL clock source must be switched to System Oscillator for correct USB operation
+//                   <0=> IRC Oscillator
+//                   <1=> System Oscillator
+//                   <2=> Reserved
+//                   <3=> Reserved
+//   </h>
+//
+//   <h> USB Clock Source Select Register (USBCLKSEL)
+//     <o9.0..1>   SEL: System PLL Clock Source
+//                   <0=> USB PLL out
+//                   <1=> Main clock
+//                   <2=> Reserved
+//                   <3=> Reserved
+//   </h>
+//
+//   <h> USB Clock Divider Register (USBCLKDIV)
+//     <o10.0..7>  DIV: USB Clock Divider
+//                     <i> Divides USB clock to 48 MHz.
+//                     <i> 0 = is disabled
+//                   <0-255>
+//   </h>
+// </e>
+*/
+#define CLOCK_SETUP           1
+#define SYSOSCCTRL_Val        0x00000000              // Reset: 0x000
+#define WDTOSCCTRL_Val        0x00000000              // Reset: 0x000
+#define SYSPLLCTRL_Val        0x00000025              // Reset: 0x000
+#define SYSPLLCLKSEL_Val      0x00000001              // Reset: 0x000
+#define MAINCLKSEL_Val        0x00000003              // Reset: 0x000
+#define SYSAHBCLKDIV_Val      0x00000001              // Reset: 0x001
+#define USBPLLCTRL_Val        0x00000023              // Reset: 0x000
+#define USBPLLCLKSEL_Val      0x00000001              // Reset: 0x000
+#define USBCLKSEL_Val         0x00000000              // Reset: 0x000
+#define USBCLKDIV_Val         0x00000001              // Reset: 0x001
+
+/*
+//-------- <<< end of configuration section >>> ------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+  Check the register settings
+ *----------------------------------------------------------------------------*/
+#define CHECK_RANGE(val, min, max)                ((val < min) || (val > max))
+#define CHECK_RSVD(val, mask)                     (val & mask)
+
+/* Clock Configuration -------------------------------------------------------*/
+#if (CHECK_RSVD((SYSOSCCTRL_Val),  ~0x00000003))
+   #error "SYSOSCCTRL: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RSVD((WDTOSCCTRL_Val),  ~0x000001FF))
+   #error "WDTOSCCTRL: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RANGE((SYSPLLCLKSEL_Val), 0, 2))
+   #error "SYSPLLCLKSEL: Value out of range!"
+#endif
+
+#if (CHECK_RSVD((SYSPLLCTRL_Val),  ~0x000001FF))
+   #error "SYSPLLCTRL: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RSVD((MAINCLKSEL_Val),  ~0x00000003))
+   #error "MAINCLKSEL: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RANGE((SYSAHBCLKDIV_Val), 0, 255))
+   #error "SYSAHBCLKDIV: Value out of range!"
+#endif
+
+#if (CHECK_RANGE((USBPLLCLKSEL_Val), 0, 1))
+   #error "USBPLLCLKSEL: Value out of range!"
+#endif
+
+#if (CHECK_RSVD((USBPLLCTRL_Val),  ~0x000001FF))
+   #error "USBPLLCTRL: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RANGE((USBCLKSEL_Val), 0, 1))
+   #error "USBCLKSEL: Value out of range!"
+#endif
+
+#if (CHECK_RANGE((USBCLKDIV_Val), 0, 255))
+   #error "USBCLKDIV: Value out of range!"
+#endif
+
+
+/*----------------------------------------------------------------------------
+  DEFINES
+ *----------------------------------------------------------------------------*/
+    
+/*----------------------------------------------------------------------------
+  Define clocks
+ *----------------------------------------------------------------------------*/
+#define __XTAL            (12000000UL)    /* Oscillator frequency             */
+#define __SYS_OSC_CLK     (    __XTAL)    /* Main oscillator frequency        */
+#define __IRC_OSC_CLK     (12000000UL)    /* Internal RC oscillator frequency */
+
+
+#define __FREQSEL   ((WDTOSCCTRL_Val >> 5) & 0x0F)
+#define __DIVSEL   (((WDTOSCCTRL_Val & 0x1F) << 1) + 2)
+
+#if (CLOCK_SETUP)                         /* Clock Setup              */
+  #if  (__FREQSEL ==  0)
+    #define __WDT_OSC_CLK        ( 0)                  /* undefined */
+  #elif (__FREQSEL ==  1)
+    #define __WDT_OSC_CLK        ( 500000 / __DIVSEL)
+  #elif (__FREQSEL ==  2)
+    #define __WDT_OSC_CLK        ( 800000 / __DIVSEL)
+  #elif (__FREQSEL ==  3)
+    #define __WDT_OSC_CLK        (1100000 / __DIVSEL)
+  #elif (__FREQSEL ==  4)
+    #define __WDT_OSC_CLK        (1400000 / __DIVSEL)
+  #elif (__FREQSEL ==  5)
+    #define __WDT_OSC_CLK        (1600000 / __DIVSEL)
+  #elif (__FREQSEL ==  6)
+    #define __WDT_OSC_CLK        (1800000 / __DIVSEL)
+  #elif (__FREQSEL ==  7)
+    #define __WDT_OSC_CLK        (2000000 / __DIVSEL)
+  #elif (__FREQSEL ==  8)
+    #define __WDT_OSC_CLK        (2200000 / __DIVSEL)
+  #elif (__FREQSEL ==  9)
+    #define __WDT_OSC_CLK        (2400000 / __DIVSEL)
+  #elif (__FREQSEL == 10)
+    #define __WDT_OSC_CLK        (2600000 / __DIVSEL)
+  #elif (__FREQSEL == 11)
+    #define __WDT_OSC_CLK        (2700000 / __DIVSEL)
+  #elif (__FREQSEL == 12)
+    #define __WDT_OSC_CLK        (2900000 / __DIVSEL)
+  #elif (__FREQSEL == 13)
+    #define __WDT_OSC_CLK        (3100000 / __DIVSEL)
+  #elif (__FREQSEL == 14)
+    #define __WDT_OSC_CLK        (3200000 / __DIVSEL)
+  #else
+    #define __WDT_OSC_CLK        (3400000 / __DIVSEL)
+  #endif
+
+  /* sys_pllclkin calculation */
+  #if   ((SYSPLLCLKSEL_Val & 0x03) == 0)
+    #define __SYS_PLLCLKIN           (__IRC_OSC_CLK)
+  #elif ((SYSPLLCLKSEL_Val & 0x03) == 1)
+    #define __SYS_PLLCLKIN           (__SYS_OSC_CLK)
+  #else
+    #define __SYS_PLLCLKIN           (0)
+  #endif
+
+  #define  __SYS_PLLCLKOUT         (__SYS_PLLCLKIN * ((SYSPLLCTRL_Val & 0x01F) + 1))
+
+  /* main clock calculation */
+  #if   ((MAINCLKSEL_Val & 0x03) == 0)
+    #define __MAIN_CLOCK             (__IRC_OSC_CLK)
+  #elif ((MAINCLKSEL_Val & 0x03) == 1)
+    #define __MAIN_CLOCK             (__SYS_PLLCLKIN)
+  #elif ((MAINCLKSEL_Val & 0x03) == 2)
+    #if (__FREQSEL ==  0)
+      #error "MAINCLKSEL: WDT Oscillator selected but FREQSEL is undefined!"
+    #else
+      #define __MAIN_CLOCK           (__WDT_OSC_CLK)
+    #endif
+  #elif ((MAINCLKSEL_Val & 0x03) == 3)
+    #define __MAIN_CLOCK             (__SYS_PLLCLKOUT)
+  #else
+    #define __MAIN_CLOCK             (0)
+  #endif
+
+  #define __SYSTEM_CLOCK             (__MAIN_CLOCK / SYSAHBCLKDIV_Val)         
+
+#else
+  #define __SYSTEM_CLOCK             (__IRC_OSC_CLK)
+#endif  // CLOCK_SETUP 
+
+
+/*----------------------------------------------------------------------------
+  Clock Variable definitions
+ *----------------------------------------------------------------------------*/
+uint32_t SystemCoreClock = __SYSTEM_CLOCK;/*!< System Clock Frequency (Core Clock)*/
+
+
+/*----------------------------------------------------------------------------
+  Clock functions
+ *----------------------------------------------------------------------------*/
+void SystemCoreClockUpdate (void)            /* Get Core Clock Frequency      */
+{
+  uint32_t wdt_osc = 0;
+
+  /* Determine clock frequency according to clock register values             */
+  switch ((LPC_SYSCON->WDTOSCCTRL >> 5) & 0x0F) {
+    case 0:  wdt_osc =       0; break;
+    case 1:  wdt_osc =  500000; break;
+    case 2:  wdt_osc =  800000; break;
+    case 3:  wdt_osc = 1100000; break;
+    case 4:  wdt_osc = 1400000; break;
+    case 5:  wdt_osc = 1600000; break;
+    case 6:  wdt_osc = 1800000; break;
+    case 7:  wdt_osc = 2000000; break;
+    case 8:  wdt_osc = 2200000; break;
+    case 9:  wdt_osc = 2400000; break;
+    case 10: wdt_osc = 2600000; break;
+    case 11: wdt_osc = 2700000; break;
+    case 12: wdt_osc = 2900000; break;
+    case 13: wdt_osc = 3100000; break;
+    case 14: wdt_osc = 3200000; break;
+    case 15: wdt_osc = 3400000; break;
+  }
+  wdt_osc /= ((LPC_SYSCON->WDTOSCCTRL & 0x1F) << 1) + 2;
+ 
+  switch (LPC_SYSCON->MAINCLKSEL & 0x03) {
+    case 0:                             /* Internal RC oscillator             */
+      SystemCoreClock = __IRC_OSC_CLK;
+      break;
+    case 1:                             /* Input Clock to System PLL          */
+      switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
+          case 0:                       /* Internal RC oscillator             */
+            SystemCoreClock = __IRC_OSC_CLK;
+            break;
+          case 1:                       /* System oscillator                  */
+            SystemCoreClock = __SYS_OSC_CLK;
+            break;
+          case 2:                       /* Reserved                           */
+          case 3:                       /* Reserved                           */
+            SystemCoreClock = 0;
+            break;
+      }
+      break;
+    case 2:                             /* WDT Oscillator                     */
+      SystemCoreClock = wdt_osc;
+      break;
+    case 3:                             /* System PLL Clock Out               */
+      switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
+          case 0:                       /* Internal RC oscillator             */
+            if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
+              SystemCoreClock = __IRC_OSC_CLK;
+            } else {
+              SystemCoreClock = __IRC_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
+            }
+            break;
+          case 1:                       /* System oscillator                  */
+            if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
+              SystemCoreClock = __SYS_OSC_CLK;
+            } else {
+              SystemCoreClock = __SYS_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
+            }
+            break;
+          case 2:                       /* Reserved                           */
+          case 3:                       /* Reserved                           */
+            SystemCoreClock = 0;
+            break;
+      }
+      break;
+  }
+
+  SystemCoreClock /= LPC_SYSCON->SYSAHBCLKDIV;  
+
+}
+
+/**
+ * Initialize the system
+ *
+ * @param  none
+ * @return none
+ *
+ * @brief  Setup the microcontroller system.
+ *         Initialize the System.
+ */
+void SystemInit (void) {
+  volatile uint32_t i;
+
+#if (CLOCK_SETUP)                                 /* Clock Setup              */
+
+#if ((SYSPLLCLKSEL_Val & 0x03) == 1)
+  LPC_SYSCON->PDRUNCFG     &= ~(1 << 5);          /* Power-up System Osc      */
+  LPC_SYSCON->SYSOSCCTRL    = SYSOSCCTRL_Val;
+  for (i = 0; i < 200; i++) __NOP();
+#endif
+
+  LPC_SYSCON->SYSPLLCLKSEL  = SYSPLLCLKSEL_Val;   /* Select PLL Input         */
+#if ((MAINCLKSEL_Val & 0x03) == 3)                /* Main Clock is PLL Out    */
+  LPC_SYSCON->SYSPLLCTRL    = SYSPLLCTRL_Val;
+  LPC_SYSCON->PDRUNCFG     &= ~(1 << 7);          /* Power-up SYSPLL          */
+  while (!(LPC_SYSCON->SYSPLLSTAT & 0x01));	      /* Wait Until PLL Locked    */
+#endif
+
+#if (((MAINCLKSEL_Val & 0x03) == 2) )
+  LPC_SYSCON->WDTOSCCTRL    = WDTOSCCTRL_Val;
+  LPC_SYSCON->PDRUNCFG     &= ~(1 << 6);          /* Power-up WDT Clock       */
+  for (i = 0; i < 200; i++) __NOP();
+#endif
+
+  LPC_SYSCON->MAINCLKSEL    = MAINCLKSEL_Val;     /* Select PLL Clock Output  */
+
+  LPC_SYSCON->SYSAHBCLKDIV  = SYSAHBCLKDIV_Val;
+
+#if ((USBCLKDIV_Val & 0x1FF) != 0)                /* USB clock is used        */
+  LPC_SYSCON->PDRUNCFG     &= ~(1 << 10);         /* Power-up USB PHY         */
+
+  /* Regardless USB PLL is used as USB clock or not, USB PLL needs to be configured. */
+  LPC_SYSCON->PDRUNCFG     &= ~(1 <<  8);         /* Power-up USB PLL         */
+  LPC_SYSCON->USBPLLCLKSEL  = USBPLLCLKSEL_Val;   /* Select PLL Input         */
+  LPC_SYSCON->USBPLLCTRL    = USBPLLCTRL_Val;
+  while (!(LPC_SYSCON->USBPLLSTAT   & 0x01));     /* Wait Until PLL Locked    */
+
+  LPC_SYSCON->USBCLKSEL     = USBCLKSEL_Val;      /* Select USB Clock         */
+  LPC_SYSCON->USBCLKDIV     = USBCLKDIV_Val;      /* Set USB clock divider    */
+
+#else                                             /* USB clock is not used    */                        
+  LPC_SYSCON->PDRUNCFG     |=  (1 << 10);         /* Power-down USB PHY       */
+  LPC_SYSCON->PDRUNCFG     |=  (1 <<  8);         /* Power-down USB PLL       */
+#endif
+
+#endif
+
+  /* System clock to the IOCON needs to be enabled or
+  most of the I/O related peripherals won't work. */
+  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<16);
+
+}
diff --git a/reform2-lpc-fw/cmsis/system_LPC13Uxx.h b/reform2-lpc-fw/cmsis/system_LPC13Uxx.h
new file mode 100644
index 0000000000000000000000000000000000000000..615a5e23cd7b9236a7c84eb6747b1f5e2266f8f3
--- /dev/null
+++ b/reform2-lpc-fw/cmsis/system_LPC13Uxx.h
@@ -0,0 +1,64 @@
+/**************************************************************************//**
+ * @file     system_LPC13Uxx.h
+ * @brief    CMSIS Cortex-M3 Device Peripheral Access Layer Header File
+ *           for the NXP LPC13Uxx Device Series
+ * @version  V1.10
+ * @date     24. November 2010
+ *
+ * @note
+ * Copyright (C) 2009-2010 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M 
+ * processor based microcontrollers.  This file can be freely distributed 
+ * within development tools that are supporting such ARM based processors. 
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+
+#ifndef __SYSTEM_LPC13Uxx_H
+#define __SYSTEM_LPC13Uxx_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+extern uint32_t SystemCoreClock;     /*!< System Clock Frequency (Core Clock)  */
+
+
+/**
+ * Initialize the system
+ *
+ * @param  none
+ * @return none
+ *
+ * @brief  Setup the microcontroller system.
+ *         Initialize the System and update the SystemCoreClock variable.
+ */
+extern void SystemInit (void);
+
+/**
+ * Update SystemCoreClock variable
+ *
+ * @param  none
+ * @return none
+ *
+ * @brief  Updates the SystemCoreClock with current core Clock 
+ *         retrieved from cpu registers.
+ */
+extern void SystemCoreClockUpdate (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SYSTEM_LPC13Uxx_H */
diff --git a/reform2-lpc-fw/doc/README.md b/reform2-lpc-fw/doc/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..6545b5955a69efaee9f42178e01a0b2056fe8d73
--- /dev/null
+++ b/reform2-lpc-fw/doc/README.md
@@ -0,0 +1,134 @@
+# LPC11U/LPC13U Code Base Documentation #
+
+Documentation for this codebase is spread out between this folder (/doc) and some of the key folders in the codebase where README.md files are appropriately placed.
+
+## Basic Structure ##
+
+While every attempt has been made to organize the LPC11U/LPC13U code base in a clear, coherent way, a basic explanation of the project structure will hopefully help you understand where to get started.
+
+The code base uses the following folder structure:
+
+- **cmsis/**: Contains the CMSIS header files, startup code and linkers for the GCC toolchain when using 'make'.  These files are generally only used with 'make' since LPCXpresso and Crossworks for ARM both product their own makefiles, linker scripts and startup code internally.
+- **doc/**: This folder, containing some basic documentation is 'markdown' format
+- **src/**: All of the main source code for the code base is placed in this folder, including main.c, projectconfig.h, etc.
+- **tests/**: This folder contains the [Unity](http://throwtheswitch.org/white-papers/unity-intro.html) unit testing framework, and some basic unit tests that are used to verify certain sections of the code base.  For further information, see the [Unit Tests](/tests/README.md) page.
+- **tools/**: This folder contains some binary tools and additional resources that are useful when working with the code base, such as the source code for the lpcrc tool that can be used to fix the checksum of compiled binaries to work with the USB bootloader.
+
+## Supported Toolchains ##
+
+This codebase is targetted at GCC, and currently supports the following toolchains or IDEs.  All of these tools support development on the three main platforms (Windows, Linux, Mac), though the exact capabilities and requirements of the different tools varies.  For more information on a specific toolchain or IDE, click on the links below:
+
+- [GCC/Makefile](toolchain_make.md)
+- [LPCXpresso](toolchain_lpcxpresso.md)
+- [Crossworks for ARM](toolchain_crossworks.md)
+- CodeLite
+
+## Starting a New Project with the LPC11U/LPC13U Code Base ##
+
+The code base is organised in a way that 'attempts' to keep the code and drivers relevant across a number of projects or boards.  The intention is to provide a common code base that only needs to be updated once, and every board supported by the code base will automatically benefit from the latest code updates.
+
+In order to accomplish this, every source file in the code base references a common [projectconfig.h](../src/projectconfig.h) file that is placed in the root 'src/' folder.
+
+The projectconfig.h file in turn references a board-specific config file in the 'src/boards/' folder that contains all of the HW and project-specific implementation details for a single project.  You should be able to simply change your board selection in projectconfig.h, and the rest of the project will continue to work as is, redirecting things like the LED, CLI input and output, USB end points, etc., to the appropriate destination.
+
+If you wish to start a new project, the best thing to do is to copy the matching boardxxx.c and boardxxx.h files that best match your own HW or project, add a new reference to the projectconfig.h file for them, and then modify those files.
+
+For example, to create a new board config for something based on the LPC1347 LPCXpresso board, create a copy of [src/boards/lpcxpresso1347/board_lpcxpresso1347.c](../src/boards/lpcxpresso1347/board_lpcxpresso1347.c) and [src/boards/lpcxpresso1347/board_lpcxpresso1347.h](../src/boards/lpcxpresso1347/board_lpcxpresso1347.h) and rename them to something appropriate like board_myproject.c/h.
+
+Open the new files up and change the names in the ifdef check at the top of the header to something unique:
+
+```
+ #ifndef __BOARD_LPCXPRESSO1347_H__
+ #define __BOARD_LPCXPRESSO1347_H__
+```
+To:
+```
+ #ifndef __BOARD_MYPROJECT_H__ 
+ #define __BOARD_MYPROJECT_H__
+```
+And change the board guard macro in the .c file to something unique:
+```
+ #if defined CFG_BRD_LPCXPRESSO_LPC1347
+```
+To:
+```
+ #if defined CFG_BRD_MYPROJECT
+```
+Next ... open up [src/projectconfig.h](../src/projectconfig.h) and add the new definition above to the board selection list, and point it to the new board config header file:
+```
+ /*=========================================================================
+    BOARD SELECTION
+
+    Because several boards use this code library with sometimes slightly
+    different pin configuration, you will need to specify which board you
+    are using by enabling one of the following definitions. The code base
+    will then try to configure itself accordingly for that board.
+
+    -----------------------------------------------------------------------*/
+    // #define CFG_BRD_LPC11U24_DEBUGGER
+    // #define CFG_BRD_LPCXPRESSO_LPC1347
+    #define CFG_BRD_WIRELESS_STANDALONE_AT86RF212
+    // #define CFG_BRD_WIRELESS_USBSTICK_AT86RF212
+
+    #ifdef CFG_BRD_LPC11U24_DEBUGGER
+      #include "boards/board_11u24debugger.h"
+    #endif
+    #ifdef CFG_BRD_LPCXPRESSO_LPC1347
+      #include "boards/board_lpcxpresso1347.h"
+    #endif
+    #ifdef CFG_BRD_WIRELESS_STANDALONE_AT86RF212
+      #include "boards/board_standalone_at86rf2xx.h"
+    #endif
+    #ifdef CFG_BRD_WIRELESS_USBSTICK_AT86RF212
+      #include "boards/board_usbstick_at86rf2xx.h"
+    #endif
+ /*=========================================================================*/
+```
+To:
+```
+ /*=========================================================================
+    BOARD SELECTION
+
+    Because several boards use this code library with sometimes slightly
+    different pin configuration, you will need to specify which board you
+    are using by enabling one of the following definitions. The code base
+    will then try to configure itself accordingly for that board.
+
+    -----------------------------------------------------------------------*/
+    // #define CFG_BRD_LPC11U24_DEBUGGER
+    // #define CFG_BRD_LPCXPRESSO_LPC1347
+    // #define CFG_BRD_WIRELESS_STANDALONE_AT86RF212
+    // #define CFG_BRD_WIRELESS_USBSTICK_AT86RF212
+    #define CFG_BRD_MYPROJECT
+
+    #ifdef CFG_BRD_LPC11U24_DEBUGGER
+      #include "boards/board_11u24debugger.h"
+    #endif
+    #ifdef CFG_BRD_LPCXPRESSO_LPC1347
+      #include "boards/board_lpcxpresso1347.h"
+    #endif
+    #ifdef CFG_BRD_WIRELESS_STANDALONE_AT86RF212
+      #include "boards/board_standalone_at86rf2xx.h"
+    #endif
+    #ifdef CFG_BRD_WIRELESS_USBSTICK_AT86RF212
+      #include "boards/board_usbstick_at86rf2xx.h"
+    #endif
+    #ifdef CFG_BRD_MYPROJECT
+      #include "boards/board_myproject.h"
+    #endif
+ /*=========================================================================*/
+```
+All that's left to do now if start customizing the boardInit() and related functions in the header file, and all of the various config settings in the board header!
+
+## Other Documentation (outside /doc)##
+
+
+- [Board/HW Abstraction Layer](../src/boards/README.md)
+- [Command Line Interface (CLI)](../src/cli/README.md)
+- [USB Support](../src/core/usb/README.md)
+- [Sensor Abstraction Layer](../src/drivers/sensors/README.md)
+- [Localisation Support](../src/localisation/README.md)
+- [Unit Tests](../src/tests/README.md)
+
+
+
diff --git a/reform2-lpc-fw/doc/doxygen/LPC1347_LPC11U37_CodeBase.doxyfile b/reform2-lpc-fw/doc/doxygen/LPC1347_LPC11U37_CodeBase.doxyfile
new file mode 100644
index 0000000000000000000000000000000000000000..84c51d38038dff62f51bdb6a60a61617274e7929
--- /dev/null
+++ b/reform2-lpc-fw/doc/doxygen/LPC1347_LPC11U37_CodeBase.doxyfile
@@ -0,0 +1,1864 @@
+# Doxyfile 1.8.3
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a hash (#) is considered a comment and will be ignored.
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should
+# identify the project. Note that if you do not use Doxywizard you need
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME = LPC1343/LPC11U37 Code Base
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = 
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF = 
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is
+# included in the documentation. The maximum height of the logo should not
+# exceed 55 pixels and the maximum width should not exceed 200 pixels.
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = output
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip. Note that you specify absolute paths here, but also
+# relative paths, which will be relative from the directory where doxygen is
+# started.
+
+STRIP_FROM_PATH = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful if your file system
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES = 
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding
+# "class=itcl::class" will allow you to use the command class in the
+# itcl::class meaning.
+
+TCL_SUBST = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension,
+# and language is one of the parsers supported by doxygen: IDL, Java,
+# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C,
+# C++. For instance to make doxygen treat .inc files as Fortran files (default
+# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note
+# that for custom extensions you also need to set FILE_PATTERNS otherwise the
+# files are not read by doxygen.
+
+EXTENSION_MAPPING = 
+
+# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all
+# comments according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you
+# can mix doxygen, HTML, and XML commands with Markdown formatting.
+# Disable only in case of backward compatibilities issues.
+
+MARKDOWN_SUPPORT = YES
+
+# When enabled doxygen tries to link words that correspond to documented classes,
+# or namespaces to their corresponding documentation. Such a link can be
+# prevented in individual cases by by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also makes the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES (the
+# default) will make doxygen replace the get and set methods by a property in
+# the documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
+# unions are shown inside the group in which they are included (e.g. using
+# @ingroup) instead of on a separate page (for HTML and Man pages) or
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
+# unions with only public data fields will be shown inline in the documentation
+# of the scope in which they are defined (i.e. file, namespace, or group
+# documentation), provided this scope is documented. If set to NO (the default),
+# structs, classes, and unions are shown on a separate page (for HTML and Man
+# pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penalty.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will roughly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+SYMBOL_CACHE_SIZE = 0
+
+# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
+# their name and scope. Since this can be an expensive process and often the
+# same symbol appear multiple times in the code, doxygen keeps a cache of
+# pre-resolved symbols. If the cache is too small doxygen will become slower.
+# If the cache is too large, memory is wasted. The cache size is given by this
+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+LOOKUP_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = YES
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+# do proper type resolution of all parameters of a function it will reject a
+# match between the prototype and the implementation of a member function even
+# if there is only one candidate or it is obvious which candidate to choose
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST = YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if section-label ... \endif
+# and \cond section-label ... \endcond blocks.
+
+ENABLED_SECTIONS = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or macro consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and macros in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE = 
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files
+# containing the references data. This must be a list of .bib files. The
+# .bib extension is automatically appended if omitted. Using this command
+# requires the bibtex tool to be installed. See also
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
+# feature you need bibtex and perl available in the search path. Do not use
+# file names with spaces, bibtex cannot handle them.
+
+CITE_BIB_FILES = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = C:\Users\Kevin\Documents\RedSuiteNXP_5.0.11_1037_beta\workspace\LPC1347_LPC11U37_CodeBase\src
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS = 
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE = C:\Users\Kevin\Documents\RedSuiteNXP_5.0.11_1037_beta\workspace\LPC1347_LPC11U37_CodeBase\src\drivers\rf\bluetooth\nrf8001 C:\Users\Kevin\Documents\RedSuiteNXP_5.0.11_1037_beta\workspace\LPC1347_LPC11U37_CodeBase\src\core\usb\romdriver C:\Users\Kevin\Documents\RedSuiteNXP_5.0.11_1037_beta\workspace\LPC1347_LPC11U37_CodeBase\src\drivers\rf\chibi C:\Users\Kevin\Documents\RedSuiteNXP_5.0.11_1037_beta\workspace\LPC1347_LPC11U37_CodeBase\src\drivers\storage\fatfs
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS = *.md 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty or if
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
+# and it is also possible to disable source filtering for a specific pattern
+# using *.ext= (so without naming a filter). This option only has effect when
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS = 
+
+# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page (index.html).
+# This can be useful if you have a project on for instance GitHub and want reuse
+# the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE = 
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C, C++ and Fortran comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header. Note that when using a custom header you are responsible
+#  for the proper inclusion of any scripts and style sheets that doxygen
+# needs, which is dependent on the configuration options used.
+# It is advised to generate a default header using "doxygen -w html
+# header.html footer.html stylesheet.css YourConfigFile" and then modify
+# that header. Note that the header is subject to change so you typically
+# have to redo this when upgrading to a newer version of doxygen or when
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If left blank doxygen will
+# generate a default style sheet. Note that it is recommended to use
+# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this
+# tag will in the future become obsolete.
+
+HTML_STYLESHEET = 
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional
+# user-defined cascading style sheet that is included after the standard
+# style sheets created by doxygen. Using this option one can overrule
+# certain style aspects. This is preferred over using HTML_STYLESHEET
+# since it does not replace the standard style sheet and is therefor more
+# robust against future updates. Doxygen will copy the style sheet file to
+# the output directory.
+
+HTML_EXTRA_STYLESHEET = 
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES = 
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the style sheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of
+# entries shown in the various tree structured indices initially; the user
+# can expand and collapse entries dynamically later on. Doxygen will expand
+# the tree to such a level that at most the specified number of entries are
+# visible (unless a fully collapsed tree already exceeds this amount).
+# So setting the number of entries 1 will produce a full collapsed tree by
+# default. 0 is a special value representing an infinite number of entries
+# and will result in a full expanded tree by default.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely
+# identify the documentation publisher. This should be a reverse domain-name
+# style string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME = 
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS = 
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+#  will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
+# at top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it. Since the tabs have the same information as the
+# navigation tree you can set this option to NO if you already set
+# GENERATE_TREEVIEW to YES.
+
+DISABLE_INDEX = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+# Since the tree basically has the same information as the tab index you
+# could consider to set DISABLE_INDEX to NO when enabling this option.
+
+GENERATE_TREEVIEW = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML
+# documentation. Note that a value of 0 will completely suppress the enum
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
+# (see http://www.mathjax.org) which uses client side Javascript for the
+# rendering instead of using prerendered bitmaps. Use this if you do not
+# have LaTeX installed or if you want to formulas look prettier in the HTML
+# output. When enabled you may also need to install MathJax separately and
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# thA MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and
+# SVG. The default value is HTML-CSS, which is slower, but has the best
+# compatibility.
+
+MATHJAX_FORMAT = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the
+# HTML output directory using the MATHJAX_RELPATH option. The destination
+# directory should contain the MathJax.js script. For instance, if the mathjax
+# directory is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to
+# the MathJax Content Delivery Network so you can quickly see the result without
+# installing MathJax.
+# However, it is strongly recommended to install a local
+# copy of MathJax from http://www.mathjax.org before deployment.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS = 
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript.
+# There are two flavours of web server based search depending on the
+# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
+# searching and an index file used by the script. When EXTERNAL_SEARCH is
+# enabled the indexing and searching needs to be provided by external tools.
+# See the manual for details.
+
+SERVER_BASED_SEARCH = NO
+
+# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain
+# the search results. Doxygen ships with an example indexer (doxyindexer) and
+# search engine (doxysearch.cgi) which are based on the open source search engine
+# library Xapian. See the manual for configuration details.
+
+EXTERNAL_SEARCH = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will returned the search results when EXTERNAL_SEARCH is enabled.
+# Doxygen ships with an example search engine (doxysearch) which is based on
+# the open source search engine library Xapian. See the manual for configuration
+# details.
+
+SEARCHENGINE_URL = 
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+
+SEARCHDATA_FILE = searchdata.xml
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through other
+# doxygen projects that are not otherwise connected via tags files, but are
+# all added to the same search index. Each project needs to have a tag file set
+# via GENERATE_TAGFILE. The search mapping then maps the name of the tag file
+# to a relative location where the documentation can be found,
+# similar to the
+# TAGFILES option but without actually processing the tag file.
+# The format is: EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+
+EXTRA_SEARCH_MAPPINGS = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER = 
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
+# the generated latex document. The footer should contain everything after
+# the last chapter. If it is left blank doxygen will generate a
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE = plain
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load style sheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE = 
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA = 
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition that
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all references to function-like macros
+# that are alone on a line, have an all uppercase name, and do not end with a
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. For each
+# tag file the location of the external documentation should be added. The
+# format of a tag file without this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths
+# or URLs. Note that each tag file must have a unique name (where the name does
+# NOT include the path). If a tag file is not located in the directory in which
+# doxygen is run, you must also specify the path to the tagfile here.
+
+TAGFILES = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option also works with HAVE_DOT disabled, but it is recommended to
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH = 
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS = 0
+
+# By default doxygen will use the Helvetica font for all dot files that
+# doxygen generates. When you want a differently looking font you can specify
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find
+# the font, which can be done by putting it in a standard location or by setting
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
+# directory containing the font.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the Helvetica font.
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
+# set the path where dot can find it.
+
+DOT_FONTPATH = 
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside
+# the class node. If there are many fields or methods and many nodes the
+# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
+# threshold limits the number of items for each type to make the size more
+# managable. Set this to 0 for no limit. Note that the threshold may be
+# exceeded by 50% before the limit is enforced.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are svg, png, jpg, or gif.
+# If left blank png will be used. If you choose svg you need to set
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# Note that this requires a modern browser other than Internet Explorer.
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS = 
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the
+# \mscfile command).
+
+MSCFILE_DIRS = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
diff --git a/reform2-lpc-fw/doc/doxygen/output/readme.txt b/reform2-lpc-fw/doc/doxygen/output/readme.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e275ee7ceccece75a1d9970577f102c2b7778232
--- /dev/null
+++ b/reform2-lpc-fw/doc/doxygen/output/readme.txt
@@ -0,0 +1 @@
+Placeholder to make sure the output folder exists for doxygen
\ No newline at end of file
diff --git a/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_ASM_Target.PNG b/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_ASM_Target.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..6e3f7e4e77f3c5d2588e407e9fb130f411f5b71e
Binary files /dev/null and b/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_ASM_Target.PNG differ
diff --git a/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_C_Includes.PNG b/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_C_Includes.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..5fe99a856591a79e16ac193e540a54b0b230e8f4
Binary files /dev/null and b/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_C_Includes.PNG differ
diff --git a/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_C_Symbols.PNG b/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_C_Symbols.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..1b9b131acda50bbd7b1a42874085ed62d52c95a0
Binary files /dev/null and b/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_C_Symbols.PNG differ
diff --git a/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_C_Target.PNG b/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_C_Target.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..caa0dcb7d3dbaa7639da010cdba3fba8fedb63e8
Binary files /dev/null and b/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_C_Target.PNG differ
diff --git a/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_Linker_Libs.PNG b/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_Linker_Libs.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..5505888989adce2bbe84dc4823d1d44f9929b6c4
Binary files /dev/null and b/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_Linker_Libs.PNG differ
diff --git a/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_Linker_Target.PNG b/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_Linker_Target.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..588acfd794391ba88f86e2e7d3e69c99abbed9f6
Binary files /dev/null and b/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_Linker_Target.PNG differ
diff --git a/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_MCUSelection.PNG b/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_MCUSelection.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..2fad5711919c9e6b019750cde9694f07fbdbfd9a
Binary files /dev/null and b/reform2-lpc-fw/doc/images/CodeRed_SwitchMCU_MCUSelection.PNG differ
diff --git a/reform2-lpc-fw/doc/toolchain_crossworks.md b/reform2-lpc-fw/doc/toolchain_crossworks.md
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/reform2-lpc-fw/doc/toolchain_lpcxpresso.md b/reform2-lpc-fw/doc/toolchain_lpcxpresso.md
new file mode 100644
index 0000000000000000000000000000000000000000..73e469d4e046cbae77fbc935670c8ae3638ed405
--- /dev/null
+++ b/reform2-lpc-fw/doc/toolchain_lpcxpresso.md
@@ -0,0 +1,58 @@
+# LPCXpresso Support in the LPC11U/LPC13U Code Base #
+
+This codebase includes project files for NXP's free Eclipse-based LPCXpresso IDE, which is based on the Code Red's commercial Red Suite.  The key advantage of LPXpresso -- aside from being free for binaries up to 128KB -- is that along with the IDE, you can purchase very low-cost LPCXpresso development board that include a full on-board HW debugger.  The HW debugger can be 'cut' from the MCU half of the board, and you can then use that debugger inside the LPCXpresso IDE to program and debug any support LPC MCU, including any HW that you develop based on this code base.
+
+
+## Getting Started with LPCXpresso and the LPC11U/LPC13U Code Base ##
+
+While teaching you how to use LPCXpresso/RedSuite or Eclipse is beyond the scope of this tutorial, this will hopefully explain some of the main issues you'll encounter when using this code base with this IDE.
+
+The main issue is the fact that the code base supports two different chip families with two different cores: ARM Cortex M0 for the LPC11U24/LPC11U37 and ARM Cortex M3 for the LPC1347.
+
+If you are switching between cores, of if your project files are configured for a different core than you want to use, you'll need to make a few changes to the project files, as detailed below ...
+
+## Switching MCUs with LPCXpresso/RedSuite ##
+
+One of the unfortunate restrictions of using a common code base for the LPC11Uxx and LPC13Uxx with LPCXpresso/RedSuite is that the MCU settings are not included in the 'target' scope, so there's not easy way to switch your project config between LPC11U and LPC13U configs.
+
+You need to make some manual changes to your project if you want to switch from a Cortex M0 LPC11U part to a Cortex M3 LPC13xx part or vice versa. This guide will show you the steps necessary to make these changes inside the IDE.
+
+**Step One: Selecting your MCU**
+
+Right-click on your project name in the Project Explorer and select 'Properties'.  From there, navigate to **C/C++ Build > MCU Settings** and select your MCU:
+
+- LPC11Uxx > LPC11U24/401
+- LPC11Uxx > LPC11U37/401
+- LPC13xx (12bit ADC) > LPC1347
+
+![MCU Settings](images/CodeRed_SwitchMCU_MCUSelection.PNG?raw=true)
+
+**Step Two: MCU C Settings**
+
+Next you need to update the references to the external CMSIS library and the selected core in the MCU C Settings dialogue (C/C++ Build > MCU Settings > MCU C Compiler).
+
+**NOTE: Be sure to make these changes for every Configuration in the 'Configuration' dropdown at the top of the dialogue box!**
+
+![C Symbols](images/CodeRed_SwitchMCU_C_Symbols.PNG?raw=true)
+
+![C Includes](images/CodeRed_SwitchMCU_C_Includes.PNG?raw=true)
+
+![C Target](images/CodeRed_SwitchMCU_C_Target.PNG?raw=true)
+
+**Step Three: MCU Assembler Settings**
+
+Next change the target architecture in the assembler settings exactly the same way you did for the C settings, making sure to repeat the steps for every configuration:
+
+![C Target](images/CodeRed_SwitchMCU_ASM_Target.PNG?raw=true)
+
+**Step Four: MCU Linker Settings**
+
+Finally, update the linker configuration to point to the correct libraries and to links files with the right target core:
+
+![C Target](images/CodeRed_SwitchMCU_Linker_Libs.PNG?raw=true)
+
+![C Target](images/CodeRed_SwitchMCU_Linker_Target.PNG?raw=true)
+
+**Step Five: Clean and build your project**
+
+Your project should work with the new MCU and core now.  Clean and then build the project, and see if you have any issues.
diff --git a/reform2-lpc-fw/doc/toolchain_make.md b/reform2-lpc-fw/doc/toolchain_make.md
new file mode 100644
index 0000000000000000000000000000000000000000..57fd4d268c41428cd8f4fd29aadd6811f7582f66
--- /dev/null
+++ b/reform2-lpc-fw/doc/toolchain_make.md
@@ -0,0 +1,128 @@
+# Using Make with the LPC11U/LPC13U Code Base #
+
+The 'make' command-line build system gives you a great deal of control over how build your projects.  You can choose the toolchain you want to build with (including one you rolled yourself), the exact library versions you wish to include, perform useful manipulations on your source code and the assembled binaries, and a lot of other tasks all from one central location or makefile.
+
+Unfortunately, getting the most from a make-based system also requires a little bit of know-how before you can get the most from it, and if this is your first time working with GCC and embedded systems you may find it easier to start with one of the graphic IDEs to build and deploy your code.  There are project files for Eclipse and Crossworks for ARM included with the code base for exactly this reason.
+
+## Why Make? ##
+
+A make-based build system gives you complete control over every build parameters for your firmware, and allows you to step outside the box that your favorite IDE keeps you in.  
+
+Graphical IDEs definately have their place -- 95% of the development for this code base was done in an IDE -- but when it comes to building production code, a make file is a good decision since it's repeatable, and you have the finest degree of control over the output.
+
+## Which Toolchain? ##
+
+This is a more complicate question to answer.  There are a lot of options out there for ARM cross-compilers, including [rolling your own toolchain](http://www.microbuilder.eu/Tutorials/SoftwareDevelopment/BuildingGCCToolchain.aspx).  Generally, the easiest option is going to be to go with a pre-compiled toolchain though.
+
+The most common pre-compiled cross-compiling toolchains for ARM are:
+
+- [GCC ARM Embedded](https://launchpad.net/gcc-arm-embedded) - Maintained by ARM, this new but popular toolchain includes a standard C library thats been optimised for small embedded ARM processors.  This is a good choice moving forward since development is active and it usually takes advantage of the latest changes to the underlying GCC code.  Installers are available for Windows, Mac and Linux.
+- [Yagarto](http://www.yagarto.de/) - A popular pre-compiled toolchain for ARM available in an easy to use installer for both Windows and the Mac.  It also includes a seperate installer (YAGARTO Tools) that will add support for the tools you'll need when building like 'make' and common Linux commands like 'mkdir'.  This is an easy to use option and works well out of the box since it includes everything you need in two installers.
+- [Sourcery CodeBench Lite](http://www.mentor.com/embedded-software/sourcery-tools/sourcery-codebench/editions/lite-edition/) - Formerly CodeSourcery G++ Lite before being purchased by Mentor, the Lite edition of this toolchain is still available free of charge and includes installers for Windows and Linux.
+
+**Note: Even if you're using the GCC ARM Embedded toolchain, on Windows you'll still want to download and install [YAGARTO Tools](http://www.yagarto.de/) to have the pre-compiled binaries you'll need to run the makefile (make, mkdir, rm, etc.).**
+
+# Getting Started #
+
+Assuming you have a toolchain installed and available in your PATH variable, you simply need to run the following command to build your firmware:
+```
+make
+```
+Once the build process is complete and if there are no errors, you will find the compiled binaries in the /bin folder.
+
+To clean up after a build process and remove all files generated, run:
+```
+make clean
+```
+
+# Configuring the Makefile #
+
+The code base has a relatively basic makefile that should work out of the box with only one or two minor change depending on your exact requirements.
+
+## Selecting Your Core ##
+
+To produce the best possible code, GCC needs to know what core to create code for when running the compiler and the assembler.
+
+Depending on if you are using a Cortex M0 (LPC11U24, LPC11U37) or a Cortex M3 (LPC1347) MCU, you need to modify the 'TARGET' definition at the top of the makefile as follows:
+
+For LPC11U parts:
+```
+TARGET = lpc11u
+```
+
+For LPC1347 and related parts:
+```
+TARGET = lpc13u
+```
+
+## Setting the Optimisation Level ##
+
+While it's normally a good idea to do your initial development with compiler optimisation turned off, if you wish to change the optimisation level for production builds, you simply need to assign an appropriate value to the OPTIMIZATION field below.
+```
+OPTIMIZATION = 0
+```
+See the GCC documentation for more info on optimisation levels, but valid values are:
+```
+ 0     - No optimisation
+ 1/2/3 - Increasing levels of optimisation
+ s     - Optimise for size
+```
+
+## Selecting Your Toolchain ##
+
+The other step that needs to be customized is to indicate the toolchain that you will be using to cross-compile the code base.
+
+You will need to update the 'GNU GCC compiler prefix' section in the Makefile to point to an appropriate path, or just use the generic toolchain 'prefix' if you have added to toolchain location to your system PATH variable.  
+
+If you don't know if your toolchain is available in your system PATH just type 'arm-none-eabi-gcc --version' and you'll either see the version of your toolchain or you'll get an error.
+
+By default, the following entries are included in the makefile:
+
+```
+ # Use the default toolchain (based on the PATH variable, etc.)
+ CROSS_COMPILE = arm-none-eabi-
+
+ # Use a toolchain at a specific location
+ # CROSS_COMPILE = C:/code_red/RedSuiteNXP_5.0.12_1048/redsuite/tools/bin/arm-none-eabi-
+ # CROSS_COMPILE = C:/arm/gnu4.7.2012.q4/bin/arm-none-eabi-
+```
+The first (default) entry assumes that arm-none-eabi-* is available in the system PATH and no hard-coded folder location is required.  If you have installed a pre-rolled toolchain like Yagarto or ARM's Embedded GCC toolchain and selected to option to add it to the path variable, this is probably what you want to select.
+
+To use a specific toolchain and a specific location, you can optionally add the path directly to that toolchain, following the example of the two additional entries above.  This can be useful if you want to compare several toolchains to see which produces the smallest code, etc.
+
+## ARM GCC Embedded Toolchain Requirements ##
+
+ARM has recently started providing their own optimized toolchain and standard c library for embedded projects.  In order to take advantage of their new nano-C library (optimised for the smallest code size), you need to uncomment the following line under Compiler Options:
+
+```
+ # For use with the GCC ARM Embedded toolchain
+ # GCFLAGS += --specs=nano.specs
+```
+This isn't mandatory, but is highly recommended since functions like printf are extremely large in the default c library.
+
+## LPCXpresso Toolchain Requirements ##
+
+If you are building with the LPCXpresso toolchain from the command-line, you will also need to uncomment the following sections in the makefile to include two additional libraries and add some required 'defines':
+
+Uncomment the following line under Compiler Options
+```
+ # For use with the LPCXpresso toolchain
+ # GCFLAGS += -D__REDLIB__ -D__CODE_RED
+```
+
+And uncomment the two addition external libraries below:
+```
+ # External Libraries
+ LDLIBS   = -lm
+ # The following libraries are required with the LPCXpresso toolchain
+ # LDLIBS  += -lcr_c -lcr_eabihelpers
+```
+
+## Adding Files to the Build Process ##
+
+It's relatively easy to add new files to the build process ... simply follow the example in the 'Source Files' section, and add the folder to the VPATH field and the file(s) to the OBJS field, paying attention to use '+=' and not '=', since using the latter will remove any previous entries.
+```
+VPATH += /my/path/to/src/files
+OBJS  += $(OBJ_PATH)/file1.o
+OBJS  += $(OBJ_PATH)/file2.o
+```
diff --git a/reform2-lpc-fw/firmware-bin-from-mcu b/reform2-lpc-fw/firmware-bin-from-mcu
new file mode 100644
index 0000000000000000000000000000000000000000..f60bb1f772602981098de2b81de43640348ed2c0
Binary files /dev/null and b/reform2-lpc-fw/firmware-bin-from-mcu differ
diff --git a/reform2-lpc-fw/flash.sh b/reform2-lpc-fw/flash.sh
new file mode 100755
index 0000000000000000000000000000000000000000..67be4df5cd83c948f29a2372da10332b75f56117
--- /dev/null
+++ b/reform2-lpc-fw/flash.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+dd if=bin/firmware.bin of="/media/mntmn/CRP DISABLD/firmware.bin" conv=nocreat,notrunc
+sync
+umount "/media/mntmn/CRP DISABLD"
+
diff --git a/reform2-lpc-fw/src/GPATH b/reform2-lpc-fw/src/GPATH
new file mode 100644
index 0000000000000000000000000000000000000000..4211e02f0fbc45b5f65ac31f45e00bd34067cace
Binary files /dev/null and b/reform2-lpc-fw/src/GPATH differ
diff --git a/reform2-lpc-fw/src/GRTAGS b/reform2-lpc-fw/src/GRTAGS
new file mode 100644
index 0000000000000000000000000000000000000000..38d824ed0b99ea1deda7aaa931873cbeb1e2cd74
Binary files /dev/null and b/reform2-lpc-fw/src/GRTAGS differ
diff --git a/reform2-lpc-fw/src/GTAGS b/reform2-lpc-fw/src/GTAGS
new file mode 100644
index 0000000000000000000000000000000000000000..151f496ab8181469141635ed5d53a507e4664bee
Binary files /dev/null and b/reform2-lpc-fw/src/GTAGS differ
diff --git a/reform2-lpc-fw/src/README.md b/reform2-lpc-fw/src/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..c8a55322c42e0a4d522a3589473d1440bb5fdc6a
--- /dev/null
+++ b/reform2-lpc-fw/src/README.md
@@ -0,0 +1,46 @@
+# Where's main.c ? #
+
+To make it easier to use the code base across a number of projects, the '**int main(void)**' function is placed inside a board-specific file in '/src/boards/board_name/', along with a header file containing all of the configuration flags for that project.
+
+You select a target board by adding a single #define somewhere in your project (this should already be done for you in the LPCXpresso and Crossworks project files, as well as in the Makefile), and projectconfig.h in the root src folder will point the code base to the right board file based on this define:
+
+```
+    #if defined(CFG_BRD_LPCXPRESSO_LPC1347)
+      #include "boards/lpcxpresso1347/board_lpcxpresso1347.h"
+    #elif defined(CFG_BRD_RF1GHZNODE)
+       #include "boards/rf1ghznode/board_rf1ghznode.h"
+    #elif defined(CFG_BRD_RF1GHZUSB)
+      #include "boards/rf1ghzusb/board_rf1ghzusb.h"
+    #elif defined (CFG_BRD_LPCNFC)
+      #include "boards/lpcnfc/board_lpcnfc.h"
+    #elif defined (CFG_BRD_LPCSTEPPER)
+      #include "boards/lpcstepper/board_lpcstepper.h"
+    #elif defined (CFG_BRD_SIMULATOR)
+      #include "boards/simulator/board_simulator.h"
+    #else
+      #error "No CFG_BRD_* has been defined"
+    #endif
+```
+
+# Source Code Organisation #
+
+To maintain a basic structure in the code base, the code is divided into several folders:
+
+###src/boards###
+Board or project-specific code, including the board-specific 'main' function that serves as the entry point for your projects, and any board/project-specific config settings.  See **projectconfig.h** for more information on selecting a target board.
+
+###src/cli###
+
+Core code for the text-based command-line interface. This is only used if **CFG\_INTERFACE** is enabled in your board config file, in combination with either **CFG\_PRINTF\_USBCDC** or **CFG\_PRINTF\_UART**.
+
+###src/core###
+Drivers for the core peripherals on the MCU, such as GPIO, USB, ADC, the delay timer, etc.
+
+###src/drivers###
+Drivers for any HW other than the core MCU peripherals, such as various sensors or displays, and some helper functions like code to bit-bang SPI, simple DSP filters, etc.
+
+###src/localisation###
+A rudimentary attempt at providing localised text to allow multiple languages in one firmware build (experimental code, and likely to change in future releases)
+
+###src/protocol###
+A simple binary protocol to handle commands via binary serial buses like USB, SPI or I2C. This is still in development and should be considered experimental code, but the goal is to eventually provide an easy way to interact with a PC via USB using a class like USB HID or via another MCU with SPI.
diff --git a/reform2-lpc-fw/src/asserts.h b/reform2-lpc-fw/src/asserts.h
new file mode 100644
index 0000000000000000000000000000000000000000..e7caddf8e5f4b40eda8738f961a81e5aae6d402f
--- /dev/null
+++ b/reform2-lpc-fw/src/asserts.h
@@ -0,0 +1,174 @@
+/**************************************************************************/
+/*!
+    @file     asserts.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Various static and dynamic ASSERT macros to simplify error
+              checking, and centralise error logging when debugging.
+    @ingroup  Errors
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _ASSERTS_H_
+#define _ASSERTS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined DEBUG
+  #define _PRINTF(...)      printf(__VA_ARGS__)
+#else
+  #define _PRINTF(...)
+#endif
+
+/*! Compiler specific macro returning a string containing the current line number */
+#define ASSERT_LINE __LINE__
+/*! Compiler specific macro returning a integer containing the current file name */
+#define ASSERT_FILE __FILE__
+/*! Compiler specific macro returning a string containing the current function */
+#define ASSERT_FUNC __func__
+
+#define STRING_CONCAT(a, b) a##b                  // TODO: Move to another place
+#define XSTRING_CONCAT(a, b) STRING_CONCAT(a, b)  // Expand then concat ... TODO: Move to another place
+
+/**************************************************************************/
+/*!
+    @brief  This macro will assert the test condition and return the
+            specified returnValue, as well as the specified 'message'
+            string in the \ref ASSERT output
+
+    @code
+    // Make sure 'addr' is within range
+    ASSERT(addr <= MAX_ADDR, ERROR_ADDRESSOUTOFRANGE, "Invalid address");
+    @endcode
+*/
+/**************************************************************************/
+#define ASSERT_MESSAGE(condition, returnValue, message) \
+        do{\
+          if (!(condition)) {\
+            _PRINTF("Assert: %s at line %d: %s%s", ASSERT_FUNC, ASSERT_LINE, message, CFG_PRINTF_NEWLINE);\
+            return (returnValue);\
+          }\
+        }while(0)
+
+/**************************************************************************/
+/*!
+    @brief Checks the condition, and if the assert fails the supplied
+           returnValue will be returned in the calling function.
+
+    @code
+    // Make sure 'addr' is within range
+    ASSERT(addr <= MAX_ADDR, ERROR_ADDRESSOUTOFRANGE);
+    @endcode
+*/
+/**************************************************************************/
+#define ASSERT(condition, returnValue)  ASSERT_MESSAGE(condition, returnValue, NULL)
+
+/**************************************************************************/
+/*!
+    @brief  Checks the supplied \ref err_t value (sts), and if it is
+            not equal to \ref ERROR_NONE the sts value will be returned
+            and the supplied error message will be sent via _PRINTF.
+
+    @details
+
+    This macro is useful to check if a function returned an error without
+    bloating your own code with endless "if (error) {...}".
+
+    @code
+    // If anything other than ERROR_NONE is returned by tsl2561Init()
+    // this macro will log the error as well as the optional message,
+    // and exit the function returning the err_t value.
+    ASSERT_STATUS(tsl2561Init(), "Initialisation failed!");
+    @endcode
+*/
+/**************************************************************************/
+#define ASSERT_STATUS_MESSAGE(sts, message) \
+        do{\
+          err_t status = (sts);\
+          if (ERROR_NONE != status) {\
+            _PRINTF("Assert: %s at line %d: 0x%X %s%s", ASSERT_FUNC, ASSERT_LINE, (uint32_t) status, message, CFG_PRINTF_NEWLINE);\
+            return status;\
+          }\
+        } while(0)
+
+/**************************************************************************/
+/*!
+    @brief  Checks the supplied \ref err_t value (sts), and if it is
+            not equal to \ref ERROR_NONE the sts value will be returned.
+
+    @details
+    This macro is useful to check if a function returned an error without
+    bloating your own code with endless "if (error) {...}".
+
+    @code
+    // If anything other than ERROR_NONE is returned by tsl2561Enable()
+    // this macro will log the error and exit the function returning the
+    // err_t value.
+    ASSERT_STATUS(tsl2561Enable());
+    @endcode
+*/
+/**************************************************************************/
+#define ASSERT_STATUS(sts)                ASSERT_STATUS_MESSAGE(sts, NULL)
+
+/**************************************************************************/
+/*!
+    @brief  Checks the supplied condition using a static assert
+
+    @details
+    The ASSERT_xxx macros are for dynamic assertions that can provide
+    protection against unexpected conditions encountered at runtime. An
+    even stronger check can be provided by static assertions that can be
+    evaluated by the compiler at the time code is compiled. A static
+    assertion can be defined like the ASSERT_xxx macros, but can be used
+    standalone (i.e., not in a conditional), for instance as follows:
+
+    @code
+    // This assertion will trigger an error when the code is compiled
+    // on 32-bit machines.
+    STATIC_ASSERT(sizeof(void *) != 4);
+
+    // To check the opposite requirement, i.e., to make sure that we are
+    // executing on a 32-bit machine only, the following static assertion
+    // can be used, which will trigger an error when the code is compiled
+    // on machines that do not have a 32-bit wordsize:
+    STATIC_ASSERT(sizeof(void *) == 4);
+    @endcode
+*/
+/**************************************************************************/
+#define STATIC_ASSERT(const_expr) enum { XSTRING_CONCAT(static_assert_, __LINE__) = 1/(!!(const_expr)) }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/binary.h b/reform2-lpc-fw/src/binary.h
new file mode 100644
index 0000000000000000000000000000000000000000..e3f50b7dcab6898a3f9ad928148e565eb0a416a6
--- /dev/null
+++ b/reform2-lpc-fw/src/binary.h
@@ -0,0 +1,88 @@
+/**************************************************************************/
+/*!
+    @file     binary.h
+    @author   hathach (tinyusb.org)
+
+    @brief    Helper macros to work with binary data
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, hathach (tinyusb.org)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _TUSB_BINARY_H_
+#define _TUSB_BINARY_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/// n-th Bit
+#define BIT_(n) (1 << (n))
+
+/// set n-th bit of x to 1
+#define BIT_SET_(x, n) ( (x) | BIT_(n) )
+
+/// clear n-th bit of x
+#define BIT_CLR_(x, n) ( (x) & (~BIT_(n)) )
+
+
+#if defined(__GNUC__) && !defined(__CC_ARM)
+
+#define BIN8(x)               (0b##x)
+#define BIN16(b1, b2)         (0b##b1##b2)
+#define BIN32(b1, b2, b3, b4) (0b##b1##b2##b3##b4)
+
+#else
+
+//  internal macro of B8, B16, B32
+#define _B8__(x) (((x&0x0000000FUL)?1:0) \
+                +((x&0x000000F0UL)?2:0) \
+                +((x&0x00000F00UL)?4:0) \
+                +((x&0x0000F000UL)?8:0) \
+                +((x&0x000F0000UL)?16:0) \
+                +((x&0x00F00000UL)?32:0) \
+                +((x&0x0F000000UL)?64:0) \
+                +((x&0xF0000000UL)?128:0))
+
+#define BIN8(d) ((uint8_t) _B8__(0x##d##UL))
+#define BIN16(dmsb,dlsb) (((uint16_t)BIN8(dmsb)<<8) + BIN8(dlsb))
+#define BIN32(dmsb,db2,db3,dlsb) \
+            (((uint32_t)BIN8(dmsb)<<24) \
+            + ((uint32_t)BIN8(db2)<<16) \
+            + ((uint32_t)BIN8(db3)<<8) \
+            + BIN8(dlsb))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TUSB_BINARY_H_ */
+
+/** @} */
diff --git a/reform2-lpc-fw/src/boards/README.md b/reform2-lpc-fw/src/boards/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..ccf1af52d7dcb69fcc1aa57fe3b05340cd372b66
--- /dev/null
+++ b/reform2-lpc-fw/src/boards/README.md
@@ -0,0 +1,19 @@
+# Board/HW Abstraction Layer #
+
+In an effort to make it easy to keep the underlying drivers and core code up to date across multiple projects (so that code only needs to be maintained in one place), a simple board abstraction layer is implemented.
+
+All config flags and settings are defined in a board-specific config file, and three mandatory functions (defined in **board.h**) must be implemented in every board_*.c file:
+
+- void boardLED(uint8_t state)
+- void boardSleep(void)
+- void boardWakeup(void)
+
+These three functions are called at different places in the code, and allow you to switch target HW without having to change anything else in your underlying project code (aside from HW-specific functions which you should place in the board_*.c file when possible).
+
+The program entry point ('main') is also implementd in the board_*.c file so that any board-specific requirements can be met at the board level.
+
+## Selecting a Board ##
+
+Board selection takes place via a mandatory 'define' that is stored in either the makefile (if you are using a GNU toolchain from the command-line) or in the IDE project settings.
+
+The **projectconfig.h** file checks for a valid board flag, and throws an error if no valid board flag was found. This file should be 'included' (#include 'projectconfig.h') in every file in the code base, since it points to the appropriate **board_*.h** file, which defines all of your project settings.
diff --git a/reform2-lpc-fw/src/boards/board.h b/reform2-lpc-fw/src/boards/board.h
new file mode 100644
index 0000000000000000000000000000000000000000..10a0b0a963378a506b09377a85ef1a661fc6389e
--- /dev/null
+++ b/reform2-lpc-fw/src/boards/board.h
@@ -0,0 +1,110 @@
+/**************************************************************************/
+/*!
+    @defgroup Boards Board/HW Abstration Layer
+
+    @brief    Board/HW abstraction layer to allow multiple boards to share
+              the same code base.
+
+    @details
+
+    Each board that uses this code base is required to implement a few key
+    functions that allow you to abstract away HW-specific activities like
+    board initialisation, and entering or exiting the low power modes.
+
+    The generic board header file also contains all of the system-wide
+    config settings for the project.
+*/
+/**************************************************************************/
+
+/**************************************************************************/
+/*!
+    @file     board.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Mandatory functions for the board/HW abstraction layer
+    @ingroup  Boards
+
+    @details
+
+    Each board that uses this code base is required to implement the
+    functions defined in this header.  This allows the core board-specific
+    functions to be abstracted away during startup, and when entering the
+    sleep modes, without having to be aware of what the target HW is.
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __BOARD_H__
+#define __BOARD_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+// Any board support file needs to implement these common methods, which
+// allow the low-level board-specific details to be abstracted away from
+// the higher level stacks and shared peripheral code
+
+/**************************************************************************/
+/*!
+    @brief Initialises the HW and configures the board for normal operation
+*/
+/**************************************************************************/
+void boardInit(void);
+
+/**************************************************************************/
+/*!
+    @brief Turns the LED(s) on or off
+*/
+/**************************************************************************/
+void boardLED(uint8_t state);
+
+/**************************************************************************/
+/*!
+    @brief Configure the board for low power and enter sleep mode
+*/
+/**************************************************************************/
+void boardSleep(void);
+
+/**************************************************************************/
+/*!
+    @brief  Restores parts and system peripherals to an appropriate
+            state after waking up from sleep mode
+*/
+/**************************************************************************/
+void boardWakeup(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/boards/lpcnfc/board_lpcnfc.c b/reform2-lpc-fw/src/boards/lpcnfc/board_lpcnfc.c
new file mode 100644
index 0000000000000000000000000000000000000000..b40fd97762ff4599a8207e693a3f75909d77461b
--- /dev/null
+++ b/reform2-lpc-fw/src/boards/lpcnfc/board_lpcnfc.c
@@ -0,0 +1,205 @@
+/**************************************************************************/
+/*!
+    @file     board_lpcnfc.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section DESCRIPTION
+
+    Common, board-specific files for the LPC1347/PN532 LPCNFC board
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#if defined CFG_BRD_LPCNFC
+
+#include "boards/board.h"
+#include "core/gpio/gpio.h"
+#include "core/delay/delay.h"
+#include "core/eeprom/eeprom.h"
+#include "core/pmu/pmu.h"
+
+#ifdef CFG_CHIBI
+  #include "messages.h"
+  #include "drivers/rf/802.15.4/chibi/chb.h"
+  #include "drivers/rf/802.15.4/chibi/chb_drvr.h"
+#endif
+
+#ifdef CFG_USB
+  #include "core/usb/usbd.h"
+  #ifdef CFG_USB_CDC
+    #include "core/usb/usb_cdc.h"
+  #endif
+#endif
+
+#ifdef CFG_TFTLCD
+  #include "drivers/displays/graphic/lcd.h"
+#endif
+
+#ifdef CFG_INTERFACE
+  #include "cli/cli.h"
+#endif
+
+#ifdef CFG_PN532
+  #include "drivers/rf/nfc/pn532/pn532.h"
+#endif
+
+#ifdef CFG_ENABLE_UART
+  #include "core/uart/uart.h"
+#endif
+
+#ifdef CFG_SDCARD
+/**************************************************************************/
+/*!
+    Handles timestamp requests for SD cards (adjust depending on if you
+    want to use the RTC, or just return 0, etc.)
+*/
+/**************************************************************************/
+DWORD get_fattime ()
+{
+  DWORD tmr = 0;
+
+  // tmr =  (((DWORD)rtcYear - 80) << 25)
+  //      | ((DWORD)rtcMon << 21)
+  //      | ((DWORD)rtcMday << 16)
+  //      | (WORD)(rtcHour << 11)
+  //      | (WORD)(rtcMin << 5)
+  //      | (WORD)(rtcSec >> 1);
+
+  return tmr;
+}
+#endif
+
+/**************************************************************************/
+/*!
+    @brief Board-specific initialisation function
+*/
+/**************************************************************************/
+void boardInit(void)
+{
+  SystemCoreClockUpdate();
+  delayInit();
+  GPIOInit();
+
+  #ifdef CFG_PRINTF_UART
+    uartInit(CFG_UART_BAUDRATE);
+  #endif
+
+  /* Set user LED pin to output and disable it */
+  LPC_GPIO->DIR[CFG_LED_PORT] |= (1 << CFG_LED_PIN);
+  boardLED(CFG_LED_ON);
+
+  /* Initialise USB */
+  #ifdef CFG_USB
+    delay(500);
+    usb_init();
+  #endif
+
+  /* Start the command line interface */
+  #ifdef CFG_INTERFACE
+    cliInit();
+  #endif
+
+  /* Make sure pins are in a relevant state */
+  LPC_IOCON->PIO0_4         = (1<<0);                     // I2C-SCL            I2C = standard mode
+  LPC_IOCON->PIO0_5         = (1<<0);                     // I2C-SDA            I2C = standard mode
+  LPC_IOCON->PIO0_16        = (0<<0) | (0<<3) | (1<<7);   // GPIO (RSTPD_N)     no pull-up/down, ADMODE = digital
+  LPC_IOCON->PIO0_17        = (0<<0) | (0<<3);            // GPIO (IRQ)         no pull-up/down
+
+  /* Start the PN532 */
+  #ifdef CFG_PN532
+    pn532Init();
+  #endif
+
+  /* Turn the user LED off */
+  boardLED(CFG_LED_OFF);
+}
+
+/**************************************************************************/
+/*!
+    @brief Primary entry point for this project.
+*/
+/**************************************************************************/
+#if !defined(_TEST_)
+int main(void)
+{
+  /* Configure the HW */
+  boardInit();
+
+  while (1)
+  {
+    /* Poll for CLI input if CFG_INTERFACE is enabled */
+    #ifdef CFG_INTERFACE
+      cliPoll();
+    #endif
+  }
+}
+#endif
+
+/**************************************************************************/
+/*!
+    @brief Turns the LED(s) on or off
+*/
+/**************************************************************************/
+void boardLED(uint8_t state)
+{
+  if (state)
+  {
+    LPC_GPIO->SET[CFG_LED_PORT] = (1 << CFG_LED_PIN);
+  }
+  else
+  {
+    LPC_GPIO->CLR[CFG_LED_PORT] = (1 << CFG_LED_PIN);
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Configure the board for low power and enter sleep mode
+*/
+/**************************************************************************/
+void boardSleep(void)
+{
+  // ToDo!
+}
+
+/**************************************************************************/
+/*!
+    @brief  Restores parts and system peripherals to an appropriate
+            state after waking up from sleep mode
+*/
+/**************************************************************************/
+void boardWakeup(void)
+{
+  // ToDo!
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/boards/lpcnfc/board_lpcnfc.h b/reform2-lpc-fw/src/boards/lpcnfc/board_lpcnfc.h
new file mode 100644
index 0000000000000000000000000000000000000000..aa2b38ab7a01dd50a9b9399f423a1d6435a577d9
--- /dev/null
+++ b/reform2-lpc-fw/src/boards/lpcnfc/board_lpcnfc.h
@@ -0,0 +1,656 @@
+/**************************************************************************/
+/*!
+    @file     board_lpcnfc.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Board file for the LPC1347/PN532 LPCNFC board
+    @ingroup  Boards
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013 K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __BOARD_LPCNFC_H__
+#define __BOARD_LPCNFC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sysdefs.h"
+
+/*=========================================================================
+    MCU SELECTION
+
+    Include one of the following definitions depending on if you are
+    using the LPC11U37 or LPC1347.  They're generally interchangeable, but
+    the LPC11Uxx and LPC13xx CMSIS implementations have some differences
+    in naming convention, and occasionally a feature is only available on
+    the M3 (DWT for example).  Selecting the appropriate MCU allows
+    the right code to be included when differences between the CMSIS
+    implementations are present.
+
+    -----------------------------------------------------------------------*/
+    // #define CFG_MCU_LPC11U24FBD48_401
+    #define CFG_MCU_LPC11U37FBD48_401
+    // #define CFG_MCU_LPC1347FBD48
+    // #define CFG_MCU_LPC1347FHN33
+
+    /* Basic error checking */
+    #if !defined CFG_MCU_LPC1347FBD48 && \
+        !defined CFG_MCU_LPC11U37FBD48_401 && \
+        !defined CFG_MCU_LPC11U24FBD48_401 && \
+        !defined CFG_MCU_LPC1347FHN33
+      #error "An MCU must be selected in projectconfig.h (Ex. CFG_MCU_LPC11U37FBD48_401, CFG_MCU_LPC1347FBD48, etc.)"
+    #endif
+
+    /* Set flag to indicate which CMSIS library to use */
+    #if (defined CFG_MCU_LPC1347FBD48 || defined CFG_MCU_LPC1347FHN33)
+      #define CFG_MCU_FAMILY_LPC13UXX
+    #elif (defined CFG_MCU_LPC11U24FBD48_401 || defined CFG_MCU_LPC11U37FBD48_401)
+      #define CFG_MCU_FAMILY_LPC11UXX
+    #endif
+
+    /* Include the correct MCU header file */
+    #if defined CFG_MCU_FAMILY_LPC13UXX
+      #include "LPC13Uxx.h"
+    #endif
+    #if defined CFG_MCU_FAMILY_LPC11UXX
+      #include "LPC11Uxx.h"
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    FIRMWARE VERSION SETTINGS
+    -----------------------------------------------------------------------*/
+    #define CFG_FIRMWARE_VERSION_MAJOR      (0)
+    #define CFG_FIRMWARE_VERSION_MINOR      (0)
+    #define CFG_FIRMWARE_VERSION_REVISION   (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    GPIO INTERRUPTS
+    -----------------------------------------------------------------------
+    This table shows where GPIO interrupts are mapped in this project
+    (Note that the LPC11U and LPC13U use different names for the
+    IRQ Handlers in the standard headers)
+
+    Interrupt                                     Location
+    ------------------------------------------    -------------------------
+    PIN_INT0_IRQHandler - FLEX_INT0_IRQHandler    chb_drvr.c
+    PIN_INT1_IRQHandler - FLEX_INT1_IRQHandler    pcf2129.c
+    PIN_INT2_IRQHandler - FLEX_INT2_IRQHandler
+    PIN_INT3_IRQHandler - FLEX_INT3_IRQHandler
+    PIN_INT4_IRQHandler - FLEX_INT4_IRQHandler
+    PIN_INT5_IRQHandler - FLEX_INT5_IRQHandler
+    PIN_INT6_IRQHandler - FLEX_INT6_IRQHandler
+    PIN_INT7_IRQHandler - FLEX_INT7_IRQHandler
+    GINT0_IRQHandler
+    GINT0_IRQHandler
+    -----------------------------------------------------------------------*/
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SUPPORTED PERIPHERALS
+    -----------------------------------------------------------------------
+    Because all ISRs are referenced in the startup code, GCC typically
+    won't optimise out the ISR functions during compilation even if the
+    ISRs will never be entered, resulting in larger binaries than required
+    (for example if no I2C sensors are used, be sure to disable I2C support
+    since the I2C ISR is quite large).
+
+    Use the defines below to include or exclude support for specific
+    peripherals.
+
+    NOTE: GPIO ISRs are handled separately in GPIO INTERRUPTS below
+    -----------------------------------------------------------------------*/
+    #define CFG_ENABLE_I2C
+    #define CFG_ENABLE_UART
+    #define CFG_ENABLE_USB
+    #define CFG_ENABLE_TIMER32
+/*=========================================================================*/
+
+
+/*=========================================================================
+    EEPROM
+    -----------------------------------------------------------------------
+    EEPROM is used to persist certain user modifiable values to make
+    sure that these changes remain in effect after a reset or hard
+    power-down.  The addresses in EEPROM for these various system
+    settings/values are defined below.  The first 256 bytes of EEPROM
+    are reserved for this (0x0000..0x00FF).
+
+    CFG_EEPROM_SIZE           The number of bytes available on the EEPROM
+    CFG_EEPROM_RESERVED       The last byte of reserved EEPROM memory
+
+          EEPROM Address (0x0000..0x00FF)
+          ===============================
+          0 1 2 3 4 5 6 7 8 9 A B C D E F
+    000x  x x . . x x x x x x x x . . . .   Chibi
+    001x  . . . . . . . . . . . . . . . .
+    002x  . . . . . . . . . . . . . . . .
+    003x  . . . . . . . . . . . . . . . .
+    004x  . . . . . . . . . . . . . . . .
+    005x  . . . . . . . . . . . . . . . .
+    006x  . . . . . . . . . . . . . . . .
+    007x  . . . . . . . . . . . . . . . .
+    008x  . . . . . . . . . . . . . . . .
+    009x  . . . . . . . . . . . . . . . .
+    00Ax  . . . . . . . . . . . . . . . .
+    00Bx  . . . . . . . . . . . . . . . .
+    00Cx  . . . . . . . . . . . . . . . .
+    00Dx  . . . . . . . . . . . . . . . .
+    00Ex  . . . . . . . . . . . . . . . .
+    00Fx  . . . . . . . . . . . . . . . .
+
+    -----------------------------------------------------------------------*/
+    #define CFG_EEPROM_SIZE                   (4032)
+    #define CFG_EEPROM_RESERVED               (0x00FF)              // Protect first 256 bytes of memory
+    #define CFG_EEPROM_CHIBI_NODEADDR         (uint16_t)(0x0000)    // 2
+    #define CFG_EEPROM_CHIBI_IEEEADDR         (uint16_t)(0x0004)    // 8
+/*=========================================================================*/
+
+
+/*=========================================================================
+    ON-BOARD LED
+    -----------------------------------------------------------------------
+
+    CFG_LED_PORT              The port for the on board LED
+    CFG_LED_PIN               The pin for the on board LED
+    CFG_LED_ON                The pin state to turn the LED on (0 = low, 1 = high)
+    CFG_LED_OFF               The pin state to turn the LED off (0 = low, 1 = high)
+
+    -----------------------------------------------------------------------*/
+    #define CFG_LED_PORT                  (0)
+    #define CFG_LED_PIN                   (23)
+    #define CFG_LED_ON                    (0)
+    #define CFG_LED_OFF                   (1)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    ADC
+    -----------------------------------------------------------------------
+
+    CFG_ADC_MODE_LOWPOWER     If set to 1, this will configure the ADC
+                              for low-power operation (LPC1347 only)
+    CFG_ADC_MODE_10BIT        If set to 1, this will configure the ADC
+                              for 10-bit mode (LPC1347 only)
+
+    -----------------------------------------------------------------------*/
+    #define CFG_ADC_MODE_LOWPOWER       (0)
+    #define CFG_ADC_MODE_10BIT          (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    UART
+    -----------------------------------------------------------------------
+
+    CFG_UART_BAUDRATE         The default UART speed.  This value is used
+                              when initialising UART, and should be a
+                              standard value like 57600, 9600, etc.
+                              NOTE: This value may be overridden if
+                              another value is stored in EEPROM!
+    CFG_UART_BUFSIZE          The length in bytes of the UART RX FIFO. This
+                              will determine the maximum number of received
+                              characters to store in memory.
+
+    -----------------------------------------------------------------------*/
+    #define CFG_UART_BAUDRATE           (115200)
+    #define CFG_UART_BUFSIZE            (256)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SPI
+    -----------------------------------------------------------------------
+
+    CFG_SSP_SCK0_LOCATION     The location of the SCK pin for SSP0
+    CFG_SSP_MISO1_LOCATION    The location of the MISO1 pin for SSP1
+    CFG_SSP_MOSI1_LOCATION    The location of the MOSI1 pin for SSP1
+    CFG_SSP_SCK1_LOCATION     The location of the SCK pin for SSP1
+
+    -----------------------------------------------------------------------*/
+    #define CFG_SSP_SCK0_0_6            (6)     // Used by USBConnect
+    #define CFG_SSP_SCK0_0_10           (10)    // Used by SWD
+    #define CFG_SSP_SCK0_1_29           (29)
+
+    #define CFG_SSP_MISO1_0_22          (22)
+    #define CFG_SSP_MISO1_1_21          (21)
+    #define CFG_SSP_MOSI1_0_21          (21)
+    #define CFG_SSP_MOSI1_1_22          (22)
+    #define CFG_SSP_SCK1_1_15           (15)
+    #define CFG_SSP_SCK1_1_20           (20)
+
+    // Select the appropriate pin locations here
+    #define CFG_SSP_SCK0_LOCATION       (CFG_SSP_SCK0_1_29)
+    #define CFG_SSP_MISO1_LOCATION      (CFG_SSP_MISO1_1_21)
+    #define CFG_SSP_MOSI1_LOCATION      (CFG_SSP_MOSI1_1_22)
+    #define CFG_SSP_SCK1_LOCATION       (CFG_SSP_SCK1_1_20)
+
+    // Set the phase and polarity for SSP0 and SSP1
+    #define CFG_SSP_CPOL0               (0)
+    #define CFG_SSP_CPHA0               (0)
+    #define CFG_SSP_CPOL1               (0)
+    #define CFG_SSP_CPHA1               (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PRINTF REDIRECTION
+    -----------------------------------------------------------------------
+
+    CFG_PRINTF_MAXSTRINGSIZE  Maximum size of string buffer for printf
+    CFG_PRINTF_UART           Will cause all printf statements to be
+                              redirected to UART
+    CFG_PRINTF_USBCDC         Will cause all printf statements to be
+                              redirect to USB Serial
+    CFG_PRINTF_NEWLINE        This is typically "\r\n" for Windows or
+                              "\n" for *nix
+
+    Note: If no printf redirection definitions are present, all printf
+    output will be ignored.
+    -----------------------------------------------------------------------*/
+    #define CFG_PRINTF_MAXSTRINGSIZE    (255)
+    // #define CFG_PRINTF_UART
+    #define CFG_PRINTF_USBCDC
+    // #define CFG_PRINTF_DEBUG
+
+    #define CFG_PRINTF_NEWLINE          "\n"
+/*=========================================================================*/
+
+
+/*=========================================================================
+    COMMAND LINE INTERFACE
+    -----------------------------------------------------------------------
+
+    CFG_INTERFACE             If this field is defined the UART or USBCDC
+                              based command-line interface will be included
+    CFG_INTERFACE_MAXMSGSIZE  The maximum number of bytes to accept for an
+                              incoming command
+    CFG_INTERFACE_PROMPT      The command prompt to display at the start
+                              of every new data entry line
+    CFG_INTERFACE_SILENTMODE  If this is set to 1 only text generated in
+                              response to commands will be send to the
+                              output buffer.  The command prompt will not
+                              be displayed and incoming text will not be
+                              echoed back to the output buffer (allowing
+                              you to see the text you have input).  This
+                              is normally only desirable in a situation
+                              where another MCU is communicating with
+                              the LPC1343.
+    CFG_INTERFACE_DROPCR      If this is set to 1 all incoming \r
+                              characters will be dropped
+    CFG_INTERFACE_ENABLEIRQ   If this is set to 1 the IRQ pin will be
+                              set high when a command starts executing
+                              and will go low when the command has
+                              finished executing or the LCD is not busy.
+                              This allows another device to know when a
+                              new command can safely be sent.
+    CFG_INTERFACE_IRQPORT     The gpio port for the IRQ/busy pin
+    CFG_INTERFACE_IRQPIN      The gpio pin number for the IRQ/busy pin
+    CFG_INTERFACE_SHORTERRORS If this is enabled only short 1 character
+                              error messages will be returned (followed
+                              by CFG_PRINTF_NEWLINE), rather than more
+                              verbose error messages.  The specific
+                              characters used are defined below.
+    CFG_INTERFACE_CONFIRMREADY  If this is set to 1 a text confirmation
+                              will be sent when the command prompt is
+                              ready for a new command.  This is in
+                              addition to CFG_INTERFACE_ENABLEIRQ if
+                              this is also enabled.  The character used
+                              is defined below.
+    CFG_INTERFACE_LONGSYSINFO If this is set to 1 extra information will
+                              be included in the Sys Info ('V') command
+                              on the CLI. This can be useful when trying
+                              to debug problems on remote HW, or with
+                              unknown firmware.  It will also use about
+                              0.5KB flash, though, so only enable it is
+                              necessary.
+
+    NOTE:                     The command-line interface will use either
+                              USB-CDC or UART depending on whether
+                              CFG_PRINTF_UART or CFG_PRINTF_USBCDC are
+                              selected.
+    -----------------------------------------------------------------------*/
+    #define CFG_INTERFACE
+    #define CFG_INTERFACE_MAXMSGSIZE    (256)
+    #define CFG_INTERFACE_PROMPT        "LPCNFC >> "
+    #define CFG_INTERFACE_SILENTMODE    (0)
+    #define CFG_INTERFACE_DROPCR        (0)
+    #define CFG_INTERFACE_ENABLEIRQ     (0)
+    #define CFG_INTERFACE_IRQPORT       (0)
+    #define CFG_INTERFACE_IRQPIN        (7)
+    #define CFG_INTERFACE_SHORTERRORS   (0)
+    #define CFG_INTERFACE_CONFIRMREADY  (0)
+    #define CFG_INTERFACE_LONGSYSINFO   (1)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SIMPLE BINARY PROTOCOL
+    -----------------------------------------------------------------------
+
+    CFG_PROTOCOL             If this field is defined the binary command
+                              parser will be included
+    -----------------------------------------------------------------------*/
+    // #define CFG_PROTOCOL
+
+    // #define CFG_PROTOCOL_VIA_HID
+    #define CFG_PROTOCOL_VIA_BULK
+
+    #if defined(CFG_PROTOCOL) && !defined(CFG_PROTOCOL_VIA_HID) && !defined(CFG_PROTOCOL_VIA_BULK)
+        #error CFG_PROTOCOL must be enabled with either CFG_PROTOCOL_VIA_HID or CFG_PROTOCOL_VIA_BULK
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    TFT LCD
+    -----------------------------------------------------------------------
+
+    CFG_TFTLCD                  If defined, this will cause drivers for
+                                a pre-determined LCD screen to be included
+                                during build.  Only one LCD driver can be
+                                included during the build process (for ex.
+                                'drivers/displays/hw/ILI9325.c')
+    CFG_TFTLCD_INCLUDESMALLFONTS If set to 1, smallfont support will be
+                                included for 3x6, 5x8, 7x8 and 8x8 fonts.
+                                This should only be enabled if these small
+                                fonts are required since there is already
+                                support for larger fonts generated with
+                                Dot Factory
+                                http://www.pavius.net/downloads/tools/53-the-dot-factory
+    CFG_TFTLCD_USEAAFONTS       If set to a non-zero value, anti-aliased
+                                fonts will be used instead of regular 1-bit
+                                font.  These result in much higher-
+                                quality text, but the fonts are 2 or 4
+                                times larger than plain bitmap fonts and
+                                take a bit more rendering time to display.
+    CFG_TFTLCD_TS_DEFAULTTHRESHOLD  Default minimum threshold to trigger a
+                                touch event with the touch screen (and exit
+                                from 'tsWaitForEvent' in touchscreen.c).
+                                Should be an 8-bit value somewhere between
+                                8 and 75 in normal circumstances.  This is
+                                the default value and may be overriden by
+                                a value stored in EEPROM.
+    CFG_TFTLCD_TS_KEYPADDELAY   The delay in milliseconds between key
+                                presses in dialogue boxes
+    ----------------------------------------------------------------------*/
+    // #define CFG_TFTLCD
+    #define CFG_TFTLCD_INCLUDESMALLFONTS   (1)
+    #define CFG_TFTLCD_USEAAFONTS          (0)
+    #define CFG_TFTLCD_TS_DEFAULTTHRESHOLD (50)
+    #define CFG_TFTLCD_TS_KEYPADDELAY      (100)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    MICRO-SD CARD
+    -----------------------------------------------------------------------
+
+    CFG_SDCARD                If this field is defined SD Card and FAT32
+                              file system support will be included
+    CFG_SDCARD_SPIPORT        SSP Port used for the SD card (0 or 1)
+    CFG_SDCARD_READONLY       If this is set to 1, all commands to
+                              write to the SD card will be removed
+                              saving some flash space.
+    CFG_SDCARD_CDPORT         The card detect port number
+    CFG_SDCARD_CDPIN          The card detect pin number
+
+    NOTE:                     All config settings for FAT32 are defined
+                              in ffconf.h
+    -----------------------------------------------------------------------*/
+    // #define CFG_SDCARD
+    #define CFG_SDCARD_READONLY         (1)   // Must be 0 or 1
+    #define CFG_SDCARD_SPIPORT          (0)
+    #define CFG_SDCARD_SSELPORT         (0)
+    #define CFG_SDCARD_SSELPIN          (0)
+    #define CFG_SDCARD_CDPORT           (0)
+    #define CFG_SDCARD_CDPIN            (0)
+    #define CFG_SDCARD_ENBLPORT         (0)
+    #define CFG_SDCARD_ENBLPIN          (0)
+
+    #ifdef CFG_SDCARD
+      #if !((CFG_SDCARD_READONLY == 0) || (CFG_SDCARD_READONLY == 1))
+        #error "Invalid value for CFG_SDCARD_READONLY"
+      #endif
+      #if !((CFG_SDCARD_SPIPORT == 0) || (CFG_SDCARD_SPIPORT == 1))
+        #error "Invalid SPI port for CFG_SDCARD_SPIPORT"
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    CHIBI WIRELESS STACK
+    -----------------------------------------------------------------------
+
+    CFG_CHIBI                   If defined, the CHIBI wireless stack will be
+                                included during build.  Requires external HW.
+    CFG_CHIBI_MODE              The mode to use when receiving and transmitting
+                                wireless data.  See chb_drvr.h for possible values
+    CFG_CHIBI_POWER             The power level to use when transmitting.  See
+                                chb_drvr.h for possible values
+    CFG_CHIBI_CHANNEL           802.15.4 Channel (0 = 868MHz, 1-10 = 915MHz)
+    CFG_CHIBI_PANID             16-bit PAN Identifier (ex.0x1234)
+    CFG_CHIBI_PROMISCUOUS       Set to 1 to enabled promiscuous mode or
+                                0 to disable it.  If promiscuous mode is
+                                enabled be sure to set CFG_CHIBI_BUFFERSIZE
+                                to an appropriately large value (ex. 1024)
+    CFG_CHIBI_BUFFERSIZE        The size of the message buffer in bytes
+    -----------------------------------------------------------------------*/
+    // #define CFG_CHIBI
+    #define CFG_CHIBI_MODE              (0)                 // OQPSK_868MHZ
+    #define CFG_CHIBI_POWER             (0xE9)              // CHB_PWR_EU2_3DBM
+    #define CFG_CHIBI_CHANNEL           (0)                 // 868-868.6 MHz
+    #define CFG_CHIBI_PANID             (0x1234)
+    #define CFG_CHIBI_PROMISCUOUS       (0)
+    #define CFG_CHIBI_BUFFERSIZE        (256)
+
+    // Pin config settings
+    #define CFG_CHIBI_SPIPORT           (0)  // Must be 0 or 1
+    #define CFG_CHIBI_SSPORT            (0)
+    #define CFG_CHIBI_SSPIN             (0)
+    #define CFG_CHIBI_EINTPORT          (0)
+    #define CFG_CHIBI_EINTPIN           (0)
+    #define CFG_CHIBI_RSTPORT           (0)
+    #define CFG_CHIBI_RSTPIN            (0)
+    #define CFG_CHIBI_SLPTRPORT         (0)
+    #define CFG_CHIBI_SLPTRPIN          (0)
+    #define CFG_CHIBI_CC1190_HGM_PORT   (0)   // Not used
+    #define CFG_CHIBI_CC1190_HGM_PIN    (0)   // Not used
+
+    #ifdef CFG_CHIBI
+      #if !((CFG_CHIBI_SPIPORT == 0) || (CFG_CHIBI_SPIPORT == 1))
+        #error "Invalid SPI port for CFG_CHIBI_SPIPORT"
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PN532/NFC STACK
+    -----------------------------------------------------------------------
+
+    CFG_PN532                      If defined, the PN532/NFC stack will be
+                                   included during build.  Requires
+                                   external HW
+    CFG_PN532_MEM_POOL_SIZE_BYTES  Size of the dynamic memory pool in bytes
+                                   (used by pn532/mem_allocator/ when
+                                   working with NDEF messages)
+    -----------------------------------------------------------------------*/
+    #define CFG_PN532
+    #define CFG_PN532_RSTPD_PORT                      (0)
+    #define CFG_PN532_RSTPD_PIN                       (16)
+    #define CFG_PN532_I2C_IRQPORT                     (0)
+    #define CFG_PN532_I2C_IRQPIN                      (17)
+    #define CFG_PN532_MEM_POOL_SIZE_BYTES             (2048)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    RTC SUPPORT
+    -----------------------------------------------------------------------
+
+    CFG_RTC                     If defined, RTC support will be included.
+                                Requires external HW.
+    -----------------------------------------------------------------------*/
+    // #define CFG_RTC
+
+    #if defined(CFG_RTC) && !defined(CFG_ENABLE_I2C)
+      #error "CFG_ENABLE_I2C must be defined with CFG_RTC"
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    STEPPER MOTOR SUPPORT
+    -----------------------------------------------------------------------
+
+    CFG_STEPPER                 If defined, basic stepper motor support
+                                will be included.  Requires external HW.
+    -----------------------------------------------------------------------*/
+    // #define CFG_STEPPER
+    #define CFG_STEPPER_TIMER32                       (0)
+    #define CFG_STEPPER_IN1_PORT                      (0)
+    #define CFG_STEPPER_IN1_PIN                       (8)
+    #define CFG_STEPPER_IN2_PORT                      (0)
+    #define CFG_STEPPER_IN2_PIN                       (9)
+    #define CFG_STEPPER_IN3_PORT                      (0)
+    #define CFG_STEPPER_IN3_PIN                       (14)
+    #define CFG_STEPPER_IN4_PORT                      (0)
+    #define CFG_STEPPER_IN4_PIN                       (13)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    USB
+
+    CFG_USB_STRING_MANUFACTURER Manufacturer name that will appear in the
+                                device descriptor during USB enumeration
+    CFG_USB_STRING_PRODUCT      Product name that will appear in the
+                                device descriptor during USB enumeration
+    CFG_USB_VENDORID            16-bit USB vendor ID
+    USB_PRODUCT_ID              Define this to set a custom product ID
+                                if you do not wish to use the 'auto'
+                                product ID feature
+    CFG_CDC                     Enable USB CDC support
+    CFG_USB_HID_KEYBOARD        Enable USB HID keyboard emulation
+    CFG_USB_HID_MOUSE           Enable USB HID mouse emulation for a five
+                                button 'Windows' mouse with scroll wheels
+    CFG_USB_HID_GENERIC         Enable USB HID Generic support for custom
+                                in and out reports, with report size set
+                                via CFG_USB_HID_GENERIC_REPORT_SIZE
+    CFG_USB_MSC                 Enable USB Mass Storage support, pointing
+                                to the SD card reader (requires mmc.c from
+                                the FATFS drivers, but doesn't use FATFS)
+
+
+    You can combine more than one USB class below and they will be
+    automatically combined in a USB composite device within the limit of
+    available USB endpoints.  The USB Product ID is calculated automatically
+    based on the combination of classes defined below.
+
+    NOTE: Windows requires the .inf file in '/core/usb' for CDC support
+    -----------------------------------------------------------------------*/
+    #ifdef CFG_ENABLE_USB
+      #define CFG_USB_STRING_MANUFACTURER       "microBuilder.eu"
+      #define CFG_USB_STRING_PRODUCT            "LPCNFC"
+      #define CFG_USB_VENDORID                  (0x1FC9)
+
+      #define CFG_USB_CDC
+
+      // #define CFG_USB_HID_KEYBOARD
+      // #define CFG_USB_HID_MOUSE
+      // #define CFG_USB_HID_GENERIC
+      #define CFG_USB_HID_GENERIC_REPORT_SIZE (64)
+
+      // #define CFG_USB_MSC
+
+      // #define CFG_USB_CUSTOM_CLASS
+
+      #if (defined(CFG_USB_CDC)       || defined(CFG_USB_HID_KEYBOARD) || \
+           defined(CFG_USB_HID_MOUSE) || defined(CFG_USB_HID_GENERIC)  || \
+           defined(CFG_USB_MSC)       || defined(CFG_USB_CUSTOM_CLASS))
+        #define CFG_USB
+        #if defined(CFG_USB_HID_KEYBOARD) || defined(CFG_USB_HID_MOUSE) || defined(CFG_USB_HID_GENERIC)
+          #define CFG_USB_HID
+          #if defined(CFG_USB_HID_GENERIC) && (CFG_USB_HID_GENERIC_REPORT_SIZE > 64)
+            #error "CFG_USB_HID_GENERIC_REPORT_SIZE exceeds the maximum value of 64 bytes (based on USB specs 2.0 for 'Full Speed Interrupt Endpoint Size')"
+          #endif
+        #endif
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    CONFIG FILE VALIDATION
+
+    Basic error checking to make sure that incompatible defines are not
+    enabled at the same time, etc.
+
+    -----------------------------------------------------------------------*/
+    #if defined(CFG_INTERFACE) && !( defined CFG_PRINTF_UART || defined CFG_PRINTF_USBCDC || defined CFG_PRINTF_DEBUG)
+      #error "At least one CFG_PRINTF target must be defined with CFG_INTERFACE"
+    #endif
+
+    #if defined(CFG_PRINTF_UART) && !defined(CFG_ENABLE_UART)
+      #error "CFG_ENABLE_UART must be enabled with CFG_PRINTF_UART"
+    #endif
+
+    #if defined(CFG_PRINTF_USBCDC) && !defined(CFG_USB_CDC)
+      #error "CFG_USB_CDC must be defined with CFG_PRINTF_USBCDC"
+    #endif
+
+    #if defined(CFG_USB_MSC) && !defined(CFG_SDCARD)
+      #error "CFG_USB_MSC must be defined with CFG_SDCARD"
+    #endif
+
+    #if defined(CFG_PROTOCOL)
+      #if defined(CFG_PROTOCOL_VIA_HID) && !defined(CFG_USB_HID_GENERIC)
+        #error "CFG_PROTOCOL_VIA_HID requires CFG_USB_HID_GENERIC"
+      #endif
+
+      #if defined(CFG_PROTOCOL_VIA_BULK) && !defined(CFG_USB_CUSTOM_CLASS)
+        #error "CFG_PROTOCOL_VIA_BULK requires CFG_USB_CUSTOM_CLASS to be defined"
+      #endif
+    #endif
+/*=========================================================================*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/boards/lpcstepper/board_lpcstepper.c b/reform2-lpc-fw/src/boards/lpcstepper/board_lpcstepper.c
new file mode 100644
index 0000000000000000000000000000000000000000..ae97da3362ac0a84dcd2419ecc694f204f8bec41
--- /dev/null
+++ b/reform2-lpc-fw/src/boards/lpcstepper/board_lpcstepper.c
@@ -0,0 +1,206 @@
+/**************************************************************************/
+/*!
+    @file     board_lpcxpresso1347.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section DESCRIPTION
+
+    Common, board-specific files for lpcxpresso LPC1347 boards
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#if defined CFG_BRD_LPCSTEPPER
+
+#include "boards/board.h"
+#include "core/gpio/gpio.h"
+#include "core/delay/delay.h"
+#include "core/eeprom/eeprom.h"
+#include "core/pmu/pmu.h"
+#include "drivers/motor/stepper/stepper.h"
+
+#ifdef CFG_USB
+  #include "core/usb/usbd.h"
+  #ifdef CFG_USB_CDC
+    #include "core/usb/usb_cdc.h"
+  #endif
+#endif
+
+#ifdef CFG_INTERFACE
+  #include "cli/cli.h"
+#endif
+
+#ifdef CFG_ENABLE_UART
+  #include "core/uart/uart.h"
+#endif
+
+#ifdef CFG_SDCARD
+/**************************************************************************/
+/*!
+    Handles timestamp requests for SD cards (adjust depending on if you
+    want to use the RTC, or just return 0, etc.)
+*/
+/**************************************************************************/
+DWORD get_fattime ()
+{
+  DWORD tmr = 0;
+
+  // tmr =  (((DWORD)rtcYear - 80) << 25)
+  //      | ((DWORD)rtcMon << 21)
+  //      | ((DWORD)rtcMday << 16)
+  //      | (WORD)(rtcHour << 11)
+  //      | (WORD)(rtcMin << 5)
+  //      | (WORD)(rtcSec >> 1);
+
+  return tmr;
+}
+#endif
+
+/**************************************************************************/
+/*!
+    @brief Board-specific initialisation function
+*/
+/**************************************************************************/
+void boardInit(void)
+{
+  SystemCoreClockUpdate();
+  delayInit();
+  GPIOInit();
+
+  #ifdef CFG_PRINTF_UART
+    uartInit(CFG_UART_BAUDRATE);
+  #endif
+
+  /* Set pins to GPIO for MOTOR2 (default = JTAG) */
+  LPC_IOCON->TDO_PIO0_13    = (1<<0) | (0<<3) | (1<<7);   // GPIO (not TDO)     no pull-up/down, ADMODE = digital
+  LPC_IOCON->TRST_PIO0_14   = (1<<0) | (0<<3) | (1<<7);   // GPIO (not TRST)    no pull-up/down, ADMODE = digital
+
+  /* Set user LED pin to output and disable it */
+  LPC_GPIO->DIR[CFG_LED_PORT] |= (1 << CFG_LED_PIN);
+  boardLED(CFG_LED_OFF);
+
+  /* Initialise USB */
+  #ifdef CFG_USB
+    delay(500);
+    usb_init();
+  #endif
+
+  /* Start the command line interface */
+  #ifdef CFG_INTERFACE
+    cliInit();
+  #endif
+
+  /* Turn the user LED on after init to indicate that everything is OK */
+  boardLED(CFG_LED_ON);
+}
+
+/**************************************************************************/
+/*!
+    @brief Primary entry point for this project.
+*/
+/**************************************************************************/
+#if !defined(_TEST_)
+int main(void)
+{
+  /* Configure the HW */
+  boardInit();
+
+  stepperInit(200);         // Initialise driver for 200-step motor
+  stepperSetSpeed(60);      // Set speed to 120 rpm (2 revolutions per second)
+
+  while (1)
+  {
+    stepperStep(400);       // Move forward 400 steps
+    stepperStep(-200);      // Move backward 200 steps
+    delay(1000);     // Wait one second
+
+    // Move 'home' after 10 loops (current position = 2000)
+    if (stepperGetPosition() == 2000)
+    {
+      stepperMoveHome();    // Move back to the starting position
+      delay(1000);   // Wait one second
+    }
+
+    #ifdef CFG_INTERFACE
+      cliPoll();
+    #endif
+  }
+
+  while (1)
+  {
+    /* Poll for CLI input if CFG_INTERFACE is enabled */
+    #ifdef CFG_INTERFACE
+      cliPoll();
+    #endif
+  }
+}
+#endif
+
+/**************************************************************************/
+/*!
+    @brief Turns the LED(s) on or off
+*/
+/**************************************************************************/
+void boardLED(uint8_t state)
+{
+  if (state)
+  {
+    LPC_GPIO->SET[CFG_LED_PORT] = (1 << CFG_LED_PIN);
+  }
+  else
+  {
+    LPC_GPIO->CLR[CFG_LED_PORT] = (1 << CFG_LED_PIN);
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Configure the board for low power and enter sleep mode
+*/
+/**************************************************************************/
+void boardSleep(void)
+{
+  // ToDo!
+}
+
+/**************************************************************************/
+/*!
+    @brief  Restores parts and system peripherals to an appropriate
+            state after waking up from sleep mode
+*/
+/**************************************************************************/
+void boardWakeup(void)
+{
+  // ToDo!
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/boards/lpcstepper/board_lpcstepper.h b/reform2-lpc-fw/src/boards/lpcstepper/board_lpcstepper.h
new file mode 100644
index 0000000000000000000000000000000000000000..78ab64b0431bdf4dc180b43f411d1babc5f633bd
--- /dev/null
+++ b/reform2-lpc-fw/src/boards/lpcstepper/board_lpcstepper.h
@@ -0,0 +1,660 @@
+/**************************************************************************/
+/*!
+    @file     board_lpcstepper.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Board file for the LPC1347 stepper driver board (DRV8833)
+    @ingroup  Boards
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013 K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __BOARD_LPCSTEPPER_H__
+#define __BOARD_LPCSTEPPER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sysdefs.h"
+
+/*=========================================================================
+    MCU SELECTION
+
+    Include one of the following definitions depending on if you are
+    using the LPC11U37 or LPC1347.  They're generally interchangeable, but
+    the LPC11Uxx and LPC13xx CMSIS implementations have some differences
+    in naming convention, and occasionally a feature is only available on
+    the M3 (DWT for example).  Selecting the appropriate MCU allows
+    the right code to be included when differences between the CMSIS
+    implementations are present.
+
+    -----------------------------------------------------------------------*/
+    // #define CFG_MCU_LPC11U24FBD48_401
+    // #define CFG_MCU_LPC11U37FBD48_401
+    // #define CFG_MCU_LPC1347FBD48
+    #define CFG_MCU_LPC1347FHN33
+
+    /* Basic error checking */
+    #if !defined CFG_MCU_LPC1347FBD48 && \
+        !defined CFG_MCU_LPC11U37FBD48_401 && \
+        !defined CFG_MCU_LPC11U24FBD48_401 && \
+        !defined CFG_MCU_LPC1347FHN33
+      #error "An MCU must be selected in projectconfig.h (Ex. CFG_MCU_LPC11U37FBD48_401, CFG_MCU_LPC1347FBD48, etc.)"
+    #endif
+
+    /* Set flag to indicate which CMSIS library to use */
+    #if (defined CFG_MCU_LPC1347FBD48 || defined CFG_MCU_LPC1347FHN33)
+      #define CFG_MCU_FAMILY_LPC13UXX
+    #elif (defined CFG_MCU_LPC11U24FBD48_401 || defined CFG_MCU_LPC11U37FBD48_401)
+      #define CFG_MCU_FAMILY_LPC11UXX
+    #endif
+
+    /* Include the correct MCU header file */
+    #if defined CFG_MCU_FAMILY_LPC13UXX
+      #include "LPC13Uxx.h"
+    #endif
+    #if defined CFG_MCU_FAMILY_LPC11UXX
+      #include "LPC11Uxx.h"
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    FIRMWARE VERSION SETTINGS
+    -----------------------------------------------------------------------*/
+    #define CFG_FIRMWARE_VERSION_MAJOR      (0)
+    #define CFG_FIRMWARE_VERSION_MINOR      (0)
+    #define CFG_FIRMWARE_VERSION_REVISION   (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    GPIO INTERRUPTS
+    -----------------------------------------------------------------------
+    This table shows where GPIO interrupts are mapped in this project
+    (Note that the LPC11U and LPC13U use different names for the
+    IRQ Handlers in the standard headers)
+
+    Interrupt                                     Location
+    ------------------------------------------    -------------------------
+    PIN_INT0_IRQHandler - FLEX_INT0_IRQHandler    chb_drvr.c
+    PIN_INT1_IRQHandler - FLEX_INT1_IRQHandler    pcf2129.c
+    PIN_INT2_IRQHandler - FLEX_INT2_IRQHandler
+    PIN_INT3_IRQHandler - FLEX_INT3_IRQHandler
+    PIN_INT4_IRQHandler - FLEX_INT4_IRQHandler
+    PIN_INT5_IRQHandler - FLEX_INT5_IRQHandler
+    PIN_INT6_IRQHandler - FLEX_INT6_IRQHandler
+    PIN_INT7_IRQHandler - FLEX_INT7_IRQHandler
+    GINT0_IRQHandler
+    GINT0_IRQHandler
+    -----------------------------------------------------------------------*/
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SUPPORTED PERIPHERALS
+    -----------------------------------------------------------------------
+    Because all ISRs are referenced in the startup code, GCC typically
+    won't optimise out the ISR functions during compilation even if the
+    ISRs will never be entered, resulting in larger binaries than required
+    (for example if no I2C sensors are used, be sure to disable I2C support
+    since the I2C ISR is quite large).
+
+    Use the defines below to include or exclude support for specific
+    peripherals.
+
+    NOTE: GPIO ISRs are handled separately in GPIO INTERRUPTS below
+    -----------------------------------------------------------------------*/
+    #define CFG_ENABLE_I2C
+    #define CFG_ENABLE_UART
+    #define CFG_ENABLE_USB
+    #define CFG_ENABLE_TIMER32
+/*=========================================================================*/
+
+
+/*=========================================================================
+    EEPROM
+    -----------------------------------------------------------------------
+    EEPROM is used to persist certain user modifiable values to make
+    sure that these changes remain in effect after a reset or hard
+    power-down.  The addresses in EEPROM for these various system
+    settings/values are defined below.  The first 256 bytes of EEPROM
+    are reserved for this (0x0000..0x00FF).
+
+    CFG_EEPROM_SIZE           The number of bytes available on the EEPROM
+    CFG_EEPROM_RESERVED       The last byte of reserved EEPROM memory
+
+          EEPROM Address (0x0000..0x00FF)
+          ===============================
+          0 1 2 3 4 5 6 7 8 9 A B C D E F
+    000x  x x . . x x x x x x x x . . . .   Chibi
+    001x  . . . . . . . . . . . . . . . .
+    002x  . . . . . . . . . . . . . . . .
+    003x  . . . . . . . . . . . . . . . .
+    004x  . . . . . . . . . . . . . . . .
+    005x  . . . . . . . . . . . . . . . .
+    006x  . . . . . . . . . . . . . . . .
+    007x  . . . . . . . . . . . . . . . .
+    008x  . . . . . . . . . . . . . . . .
+    009x  . . . . . . . . . . . . . . . .
+    00Ax  . . . . . . . . . . . . . . . .
+    00Bx  . . . . . . . . . . . . . . . .
+    00Cx  . . . . . . . . . . . . . . . .
+    00Dx  . . . . . . . . . . . . . . . .
+    00Ex  . . . . . . . . . . . . . . . .
+    00Fx  . . . . . . . . . . . . . . . .
+
+    -----------------------------------------------------------------------*/
+    #define CFG_EEPROM_SIZE                   (4032)
+    #define CFG_EEPROM_RESERVED               (0x00FF)              // Protect first 256 bytes of memory
+    #define CFG_EEPROM_CHIBI_NODEADDR         (uint16_t)(0x0000)    // 2
+    #define CFG_EEPROM_CHIBI_IEEEADDR         (uint16_t)(0x0004)    // 8
+/*=========================================================================*/
+
+
+/*=========================================================================
+    ON-BOARD LED
+    -----------------------------------------------------------------------
+
+    CFG_LED_PORT              The port for the on board LED
+    CFG_LED_PIN               The pin for the on board LED
+    CFG_LED_ON                The pin state to turn the LED on (0 = low, 1 = high)
+    CFG_LED_OFF               The pin state to turn the LED off (0 = low, 1 = high)
+
+    -----------------------------------------------------------------------*/
+    #define CFG_LED_PORT                  (0)
+    #define CFG_LED_PIN                   (23)
+    #define CFG_LED_ON                    (0)
+    #define CFG_LED_OFF                   (1)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    ADC
+    -----------------------------------------------------------------------
+
+    CFG_ADC_MODE_LOWPOWER     If set to 1, this will configure the ADC
+                              for low-power operation (LPC1347 only)
+    CFG_ADC_MODE_10BIT        If set to 1, this will configure the ADC
+                              for 10-bit mode (LPC1347 only)
+
+    -----------------------------------------------------------------------*/
+    #define CFG_ADC_MODE_LOWPOWER       (0)
+    #define CFG_ADC_MODE_10BIT          (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    UART
+    -----------------------------------------------------------------------
+
+    CFG_UART_BAUDRATE         The default UART speed.  This value is used
+                              when initialising UART, and should be a
+                              standard value like 57600, 9600, etc.
+                              NOTE: This value may be overridden if
+                              another value is stored in EEPROM!
+    CFG_UART_BUFSIZE          The length in bytes of the UART RX FIFO. This
+                              will determine the maximum number of received
+                              characters to store in memory.
+
+    -----------------------------------------------------------------------*/
+    #define CFG_UART_BAUDRATE           (115200)
+    #define CFG_UART_BUFSIZE            (256)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SPI
+    -----------------------------------------------------------------------
+
+    CFG_SSP_SCK0_LOCATION     The location of the SCK pin for SSP0
+    CFG_SSP_MISO1_LOCATION    The location of the MISO1 pin for SSP1
+    CFG_SSP_MOSI1_LOCATION    The location of the MOSI1 pin for SSP1
+    CFG_SSP_SCK1_LOCATION     The location of the SCK pin for SSP1
+
+    -----------------------------------------------------------------------*/
+    #define CFG_SSP_SCK0_0_6            (6)     // Used by USBConnect
+    #define CFG_SSP_SCK0_0_10           (10)    // Used by SWD
+    #define CFG_SSP_SCK0_1_29           (29)
+
+    #define CFG_SSP_MISO1_0_22          (22)
+    #define CFG_SSP_MISO1_1_21          (21)
+    #define CFG_SSP_MOSI1_0_21          (21)
+    #define CFG_SSP_MOSI1_1_22          (22)
+    #define CFG_SSP_SCK1_1_15           (15)
+    #define CFG_SSP_SCK1_1_20           (20)
+
+    // Select the appropriate pin locations here
+    #define CFG_SSP_SCK0_LOCATION       (CFG_SSP_SCK0_1_29)
+    #define CFG_SSP_MISO1_LOCATION      (CFG_SSP_MISO1_1_21)
+    #define CFG_SSP_MOSI1_LOCATION      (CFG_SSP_MOSI1_1_22)
+    #define CFG_SSP_SCK1_LOCATION       (CFG_SSP_SCK1_1_20)
+
+    // Set the phase and polarity for SSP0 and SSP1
+    #define CFG_SSP_CPOL0               (0)
+    #define CFG_SSP_CPHA0               (0)
+    #define CFG_SSP_CPOL1               (0)
+    #define CFG_SSP_CPHA1               (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PRINTF REDIRECTION
+    -----------------------------------------------------------------------
+
+    CFG_PRINTF_MAXSTRINGSIZE  Maximum size of string buffer for printf
+    CFG_PRINTF_UART           Will cause all printf statements to be
+                              redirected to UART
+    CFG_PRINTF_USBCDC         Will cause all printf statements to be
+                              redirect to USB Serial
+    CFG_PRINTF_NEWLINE        This is typically "\r\n" for Windows or
+                              "\n" for *nix
+
+    Note: If no printf redirection definitions are present, all printf
+    output will be ignored.
+    -----------------------------------------------------------------------*/
+    #define CFG_PRINTF_MAXSTRINGSIZE    (255)
+    // #define CFG_PRINTF_UART
+    #define CFG_PRINTF_USBCDC
+    // #define CFG_PRINTF_DEBUG
+
+    #ifdef CFG_PRINTF_DEBUG
+      #define CFG_PRINTF_NEWLINE          "\n"
+    #else
+      #define CFG_PRINTF_NEWLINE          "\r\n"
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    COMMAND LINE INTERFACE
+    -----------------------------------------------------------------------
+
+    CFG_INTERFACE             If this field is defined the UART or USBCDC
+                              based command-line interface will be included
+    CFG_INTERFACE_MAXMSGSIZE  The maximum number of bytes to accept for an
+                              incoming command
+    CFG_INTERFACE_PROMPT      The command prompt to display at the start
+                              of every new data entry line
+    CFG_INTERFACE_SILENTMODE  If this is set to 1 only text generated in
+                              response to commands will be send to the
+                              output buffer.  The command prompt will not
+                              be displayed and incoming text will not be
+                              echoed back to the output buffer (allowing
+                              you to see the text you have input).  This
+                              is normally only desirable in a situation
+                              where another MCU is communicating with
+                              the LPC1343.
+    CFG_INTERFACE_DROPCR      If this is set to 1 all incoming \r
+                              characters will be dropped
+    CFG_INTERFACE_ENABLEIRQ   If this is set to 1 the IRQ pin will be
+                              set high when a command starts executing
+                              and will go low when the command has
+                              finished executing or the LCD is not busy.
+                              This allows another device to know when a
+                              new command can safely be sent.
+    CFG_INTERFACE_IRQPORT     The gpio port for the IRQ/busy pin
+    CFG_INTERFACE_IRQPIN      The gpio pin number for the IRQ/busy pin
+    CFG_INTERFACE_SHORTERRORS If this is enabled only short 1 character
+                              error messages will be returned (followed
+                              by CFG_PRINTF_NEWLINE), rather than more
+                              verbose error messages.  The specific
+                              characters used are defined below.
+    CFG_INTERFACE_CONFIRMREADY  If this is set to 1 a text confirmation
+                              will be sent when the command prompt is
+                              ready for a new command.  This is in
+                              addition to CFG_INTERFACE_ENABLEIRQ if
+                              this is also enabled.  The character used
+                              is defined below.
+    CFG_INTERFACE_LONGSYSINFO If this is set to 1 extra information will
+                              be included in the Sys Info ('V') command
+                              on the CLI. This can be useful when trying
+                              to debug problems on remote HW, or with
+                              unknown firmware.  It will also use about
+                              0.5KB flash, though, so only enable it is
+                              necessary.
+
+    NOTE:                     The command-line interface will use either
+                              USB-CDC or UART depending on whether
+                              CFG_PRINTF_UART or CFG_PRINTF_USBCDC are
+                              selected.
+    -----------------------------------------------------------------------*/
+    #define CFG_INTERFACE
+    #define CFG_INTERFACE_MAXMSGSIZE    (256)
+    #define CFG_INTERFACE_PROMPT        "LPCSTEPPER >> "
+    #define CFG_INTERFACE_SILENTMODE    (0)
+    #define CFG_INTERFACE_DROPCR        (0)
+    #define CFG_INTERFACE_ENABLEIRQ     (0)
+    #define CFG_INTERFACE_IRQPORT       (0)
+    #define CFG_INTERFACE_IRQPIN        (7)
+    #define CFG_INTERFACE_SHORTERRORS   (0)
+    #define CFG_INTERFACE_CONFIRMREADY  (0)
+    #define CFG_INTERFACE_LONGSYSINFO   (1)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SIMPLE BINARY PROTOCOL
+    -----------------------------------------------------------------------
+
+    CFG_PROTOCOL             If this field is defined the binary command
+                              parser will be included
+    -----------------------------------------------------------------------*/
+    // #define CFG_PROTOCOL
+
+    // #define CFG_PROTOCOL_VIA_HID
+    #define CFG_PROTOCOL_VIA_BULK
+
+    #if defined(CFG_PROTOCOL) && !defined(CFG_PROTOCOL_VIA_HID) && !defined(CFG_PROTOCOL_VIA_BULK)
+        #error CFG_PROTOCOL must be enabled with either CFG_PROTOCOL_VIA_HID or CFG_PROTOCOL_VIA_BULK
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    TFT LCD
+    -----------------------------------------------------------------------
+
+    CFG_TFTLCD                  If defined, this will cause drivers for
+                                a pre-determined LCD screen to be included
+                                during build.  Only one LCD driver can be
+                                included during the build process (for ex.
+                                'drivers/displays/hw/ILI9325.c')
+    CFG_TFTLCD_INCLUDESMALLFONTS If set to 1, smallfont support will be
+                                included for 3x6, 5x8, 7x8 and 8x8 fonts.
+                                This should only be enabled if these small
+                                fonts are required since there is already
+                                support for larger fonts generated with
+                                Dot Factory
+                                http://www.pavius.net/downloads/tools/53-the-dot-factory
+    CFG_TFTLCD_USEAAFONTS       If set to a non-zero value, anti-aliased
+                                fonts will be used instead of regular 1-bit
+                                font.  These result in much higher-
+                                quality text, but the fonts are 2 or 4
+                                times larger than plain bitmap fonts and
+                                take a bit more rendering time to display.
+    CFG_TFTLCD_TS_DEFAULTTHRESHOLD  Default minimum threshold to trigger a
+                                touch event with the touch screen (and exit
+                                from 'tsWaitForEvent' in touchscreen.c).
+                                Should be an 8-bit value somewhere between
+                                8 and 75 in normal circumstances.  This is
+                                the default value and may be overriden by
+                                a value stored in EEPROM.
+    CFG_TFTLCD_TS_KEYPADDELAY   The delay in milliseconds between key
+                                presses in dialogue boxes
+    ----------------------------------------------------------------------*/
+    // #define CFG_TFTLCD
+    #define CFG_TFTLCD_INCLUDESMALLFONTS   (1)
+    #define CFG_TFTLCD_USEAAFONTS          (0)
+    #define CFG_TFTLCD_TS_DEFAULTTHRESHOLD (50)
+    #define CFG_TFTLCD_TS_KEYPADDELAY      (100)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    MICRO-SD CARD
+    -----------------------------------------------------------------------
+
+    CFG_SDCARD                If this field is defined SD Card and FAT32
+                              file system support will be included
+    CFG_SDCARD_SPIPORT        SSP Port used for the SD card (0 or 1)
+    CFG_SDCARD_READONLY       If this is set to 1, all commands to
+                              write to the SD card will be removed
+                              saving some flash space.
+    CFG_SDCARD_CDPORT         The card detect port number
+    CFG_SDCARD_CDPIN          The card detect pin number
+
+    NOTE:                     All config settings for FAT32 are defined
+                              in ffconf.h
+    -----------------------------------------------------------------------*/
+    // #define CFG_SDCARD
+    #define CFG_SDCARD_READONLY         (1)   // Must be 0 or 1
+    #define CFG_SDCARD_SPIPORT          (0)
+    #define CFG_SDCARD_SSELPORT         (0)
+    #define CFG_SDCARD_SSELPIN          (0)
+    #define CFG_SDCARD_CDPORT           (0)
+    #define CFG_SDCARD_CDPIN            (0)
+    #define CFG_SDCARD_ENBLPORT         (0)
+    #define CFG_SDCARD_ENBLPIN          (0)
+
+    #ifdef CFG_SDCARD
+      #if !((CFG_SDCARD_READONLY == 0) || (CFG_SDCARD_READONLY == 1))
+        #error "Invalid value for CFG_SDCARD_READONLY"
+      #endif
+      #if !((CFG_SDCARD_SPIPORT == 0) || (CFG_SDCARD_SPIPORT == 1))
+        #error "Invalid SPI port for CFG_SDCARD_SPIPORT"
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    CHIBI WIRELESS STACK
+    -----------------------------------------------------------------------
+
+    CFG_CHIBI                   If defined, the CHIBI wireless stack will be
+                                included during build.  Requires external HW.
+    CFG_CHIBI_MODE              The mode to use when receiving and transmitting
+                                wireless data.  See chb_drvr.h for possible values
+    CFG_CHIBI_POWER             The power level to use when transmitting.  See
+                                chb_drvr.h for possible values
+    CFG_CHIBI_CHANNEL           802.15.4 Channel (0 = 868MHz, 1-10 = 915MHz)
+    CFG_CHIBI_PANID             16-bit PAN Identifier (ex.0x1234)
+    CFG_CHIBI_PROMISCUOUS       Set to 1 to enabled promiscuous mode or
+                                0 to disable it.  If promiscuous mode is
+                                enabled be sure to set CFG_CHIBI_BUFFERSIZE
+                                to an appropriately large value (ex. 1024)
+    CFG_CHIBI_BUFFERSIZE        The size of the message buffer in bytes
+    -----------------------------------------------------------------------*/
+    // #define CFG_CHIBI
+    #define CFG_CHIBI_MODE              (0)                 // OQPSK_868MHZ
+    #define CFG_CHIBI_POWER             (0xE9)              // CHB_PWR_EU2_3DBM
+    #define CFG_CHIBI_CHANNEL           (0)                 // 868-868.6 MHz
+    #define CFG_CHIBI_PANID             (0x1234)
+    #define CFG_CHIBI_PROMISCUOUS       (0)
+    #define CFG_CHIBI_BUFFERSIZE        (256)
+
+    // Pin config settings
+    #define CFG_CHIBI_SPIPORT           (0)  // Must be 0 or 1
+    #define CFG_CHIBI_SSPORT            (0)
+    #define CFG_CHIBI_SSPIN             (0)
+    #define CFG_CHIBI_EINTPORT          (0)
+    #define CFG_CHIBI_EINTPIN           (0)
+    #define CFG_CHIBI_RSTPORT           (0)
+    #define CFG_CHIBI_RSTPIN            (0)
+    #define CFG_CHIBI_SLPTRPORT         (0)
+    #define CFG_CHIBI_SLPTRPIN          (0)
+    #define CFG_CHIBI_CC1190_HGM_PORT   (0)   // Not used
+    #define CFG_CHIBI_CC1190_HGM_PIN    (0)   // Not used
+
+    #ifdef CFG_CHIBI
+      #if !((CFG_CHIBI_SPIPORT == 0) || (CFG_CHIBI_SPIPORT == 1))
+        #error "Invalid SPI port for CFG_CHIBI_SPIPORT"
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PN532/NFC STACK
+    -----------------------------------------------------------------------
+
+    CFG_PN532                      If defined, the PN532/NFC stack will be
+                                   included during build.  Requires
+                                   external HW
+    CFG_PN532_MEM_POOL_SIZE_BYTES  Size of the dynamic memory pool in bytes
+                                   (used by pn532/mem_allocator/ when
+                                   working with NDEF messages)
+    -----------------------------------------------------------------------*/
+    // #define CFG_PN532
+    #define CFG_PN532_RSTPD_PORT                      (0)
+    #define CFG_PN532_RSTPD_PIN                       (16)
+    #define CFG_PN532_I2C_IRQPORT                     (0)
+    #define CFG_PN532_I2C_IRQPIN                      (17)
+    #define CFG_PN532_MEM_POOL_SIZE_BYTES             (512)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    RTC SUPPORT
+    -----------------------------------------------------------------------
+
+    CFG_RTC                     If defined, RTC support will be included.
+                                Requires external HW.
+    -----------------------------------------------------------------------*/
+    // #define CFG_RTC
+
+    #if defined(CFG_RTC) && !defined(CFG_ENABLE_I2C)
+      #error "CFG_ENABLE_I2C must be defined with CFG_RTC"
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    STEPPER MOTOR SUPPORT
+    -----------------------------------------------------------------------
+
+    CFG_STEPPER                 If defined, basic stepper motor support
+                                will be included.  Requires external HW.
+    -----------------------------------------------------------------------*/
+    #define CFG_STEPPER
+    #define CFG_STEPPER_TIMER32                       (0)
+    #define CFG_STEPPER_IN1_PORT                      (0)
+    #define CFG_STEPPER_IN1_PIN                       (8)
+    #define CFG_STEPPER_IN2_PORT                      (0)
+    #define CFG_STEPPER_IN2_PIN                       (9)
+    #define CFG_STEPPER_IN3_PORT                      (0)
+    #define CFG_STEPPER_IN3_PIN                       (14)
+    #define CFG_STEPPER_IN4_PORT                      (0)
+    #define CFG_STEPPER_IN4_PIN                       (13)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    USB
+
+    CFG_USB_STRING_MANUFACTURER Manufacturer name that will appear in the
+                                device descriptor during USB enumeration
+    CFG_USB_STRING_PRODUCT      Product name that will appear in the
+                                device descriptor during USB enumeration
+    CFG_USB_VENDORID            16-bit USB vendor ID
+    USB_PRODUCT_ID              Define this to set a custom product ID
+                                if you do not wish to use the 'auto'
+                                product ID feature
+    CFG_CDC                     Enable USB CDC support
+    CFG_USB_HID_KEYBOARD        Enable USB HID keyboard emulation
+    CFG_USB_HID_MOUSE           Enable USB HID mouse emulation for a five
+                                button 'Windows' mouse with scroll wheels
+    CFG_USB_HID_GENERIC         Enable USB HID Generic support for custom
+                                in and out reports, with report size set
+                                via CFG_USB_HID_GENERIC_REPORT_SIZE
+    CFG_USB_MSC                 Enable USB Mass Storage support, pointing
+                                to the SD card reader (requires mmc.c from
+                                the FATFS drivers, but doesn't use FATFS)
+
+
+    You can combine more than one USB class below and they will be
+    automatically combined in a USB composite device within the limit of
+    available USB endpoints.  The USB Product ID is calculated automatically
+    based on the combination of classes defined below.
+
+    NOTE: Windows requires the .inf file in '/core/usb' for CDC support
+    -----------------------------------------------------------------------*/
+    #ifdef CFG_ENABLE_USB
+      #define CFG_USB_STRING_MANUFACTURER       "microBuilder.eu"
+      #define CFG_USB_STRING_PRODUCT            "LPCStepper"
+      #define CFG_USB_VENDORID                  (0x1FC9)
+
+      #define CFG_USB_CDC
+
+      // #define CFG_USB_HID_KEYBOARD
+      // #define CFG_USB_HID_MOUSE
+      #define CFG_USB_HID_GENERIC
+      #define CFG_USB_HID_GENERIC_REPORT_SIZE (64)
+
+      // #define CFG_USB_MSC
+
+      // #define CFG_USB_CUSTOM_CLASS
+
+      #if (defined(CFG_USB_CDC)       || defined(CFG_USB_HID_KEYBOARD) || \
+           defined(CFG_USB_HID_MOUSE) || defined(CFG_USB_HID_GENERIC)  || \
+           defined(CFG_USB_MSC)       || defined(CFG_USB_CUSTOM_CLASS))
+        #define CFG_USB
+        #if defined(CFG_USB_HID_KEYBOARD) || defined(CFG_USB_HID_MOUSE) || defined(CFG_USB_HID_GENERIC)
+          #define CFG_USB_HID
+          #if defined(CFG_USB_HID_GENERIC) && (CFG_USB_HID_GENERIC_REPORT_SIZE > 64)
+            #error "CFG_USB_HID_GENERIC_REPORT_SIZE exceeds the maximum value of 64 bytes (based on USB specs 2.0 for 'Full Speed Interrupt Endpoint Size')"
+          #endif
+        #endif
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    CONFIG FILE VALIDATION
+
+    Basic error checking to make sure that incompatible defines are not
+    enabled at the same time, etc.
+
+    -----------------------------------------------------------------------*/
+    #if defined(CFG_INTERFACE) && !( defined CFG_PRINTF_UART || defined CFG_PRINTF_USBCDC || defined CFG_PRINTF_DEBUG)
+      #error "At least one CFG_PRINTF target must be defined with CFG_INTERFACE"
+    #endif
+
+    #if defined(CFG_PRINTF_UART) && !defined(CFG_ENABLE_UART)
+      #error "CFG_ENABLE_UART must be enabled with CFG_PRINTF_UART"
+    #endif
+
+    #if defined(CFG_PRINTF_USBCDC) && !defined(CFG_USB_CDC)
+      #error "CFG_USB_CDC must be defined with CFG_PRINTF_USBCDC"
+    #endif
+
+    #if defined(CFG_USB_MSC) && !defined(CFG_SDCARD)
+      #error "CFG_USB_MSC must be defined with CFG_SDCARD"
+    #endif
+
+    #if defined(CFG_PROTOCOL)
+      #if defined(CFG_PROTOCOL_VIA_HID) && !defined(CFG_USB_HID_GENERIC)
+        #error "CFG_PROTOCOL_VIA_HID requires CFG_USB_HID_GENERIC"
+      #endif
+
+      #if defined(CFG_PROTOCOL_VIA_BULK) && !defined(CFG_USB_CUSTOM_CLASS)
+        #error "CFG_PROTOCOL_VIA_BULK requires CFG_USB_CUSTOM_CLASS to be defined"
+      #endif
+    #endif
+/*=========================================================================*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/boards/lpcxpresso1347/board_lpcxpresso1347.c b/reform2-lpc-fw/src/boards/lpcxpresso1347/board_lpcxpresso1347.c
new file mode 100644
index 0000000000000000000000000000000000000000..a7ad31def5b203e48c89add81c099a6cbd4b2496
--- /dev/null
+++ b/reform2-lpc-fw/src/boards/lpcxpresso1347/board_lpcxpresso1347.c
@@ -0,0 +1,341 @@
+/**************************************************************************/
+/*!
+    @file     board_lpcxpresso1347.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section DESCRIPTION
+
+    Common, board-specific files for lpcxpresso LPC1347 boards
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_BRD_LPCXPRESSO_LPC1347
+
+#include <string.h> /* strlen */
+
+#include "cmsis_os.h"
+#include "boards/board.h"
+#include "core/gpio/gpio.h"
+#include "core/delay/delay.h"
+#include "core/eeprom/eeprom.h"
+#include "core/pmu/pmu.h"
+
+#ifdef CFG_CHIBI
+  #include "messages.h"
+  #include "drivers/rf/802.15.4/chibi/chb.h"
+  #include "drivers/rf/802.15.4/chibi/chb_drvr.h"
+#endif
+
+#ifdef CFG_USB
+  #include "core/usb/usbd.h"
+  #ifdef CFG_USB_CDC
+    #include "core/usb/usb_cdc.h"
+  #endif
+#endif
+
+#ifdef CFG_TFTLCD
+  #include "drivers/displays/graphic/lcd.h"
+#endif
+
+#ifdef CFG_INTERFACE
+  #include "cli/cli.h"
+#endif
+
+#ifdef CFG_PROTOCOL
+  #include "protocol/protocol.h"
+#endif
+
+#ifdef CFG_ENABLE_UART
+  #include "core/uart/uart.h"
+#endif
+
+#ifdef CFG_CMSIS_RTOS
+  #include "RTX_CM_lib.h"
+#endif
+
+#ifdef CFG_CC3000
+  #include "drivers/rf/wifi/cc3000/wifi.h"
+#endif
+
+#ifdef CFG_SDCARD
+/**************************************************************************/
+/*!
+    Handles timestamp requests for SD cards (adjust depending on if you
+    want to use the RTC, or just return 0, etc.)
+*/
+/**************************************************************************/
+DWORD get_fattime ()
+{
+  DWORD tmr = 0;
+
+  // tmr =  (((DWORD)rtcYear - 80) << 25)
+  //      | ((DWORD)rtcMon << 21)
+  //      | ((DWORD)rtcMday << 16)
+  //      | (WORD)(rtcHour << 11)
+  //      | (WORD)(rtcMin << 5)
+  //      | (WORD)(rtcSec >> 1);
+
+  return tmr;
+}
+#endif
+
+/**************************************************************************/
+/*!
+    @brief Board-specific initialisation function
+*/
+/**************************************************************************/
+void boardInit(void)
+{
+  SystemCoreClockUpdate();
+  delayInit();
+  GPIOInit();
+
+  #ifdef CFG_PRINTF_UART
+    uartInit(CFG_UART_BAUDRATE);
+  #endif
+
+  /* Set user LED pin to output and disable it */
+  LPC_GPIO->DIR[CFG_LED_PORT] |= (1 << CFG_LED_PIN);
+  boardLED(CFG_LED_OFF);
+
+  /* Start Chibi */
+  #ifdef CFG_CHIBI
+    /* You may need to write a new address to EEPROM if it doesn't exist */
+    // uint16_t nodeaddr = 0xCAFE;
+    // uint64_t ieeeaddr = 0x123456780000CAFE;
+    // writeEEPROM((uint8_t*)CFG_EEPROM_CHIBI_NODEADDR, (uint8_t*)&nodeaddr, sizeof(nodeaddr));
+    // writeEEPROM((uint8_t*)CFG_EEPROM_CHIBI_IEEEADDR, (uint8_t*)&ieeeaddr, sizeof(ieeeaddr));
+    chb_init();
+  #endif
+
+  /* Initialise USB */
+  #ifdef CFG_USB
+    delay(500);
+    usb_init();
+  #endif
+
+  /* Initialise the LCD if requested */
+  #ifdef CFG_TFTLCD
+    lcdInit();
+  #endif
+
+  /* Start the command line interface */
+  #ifdef CFG_INTERFACE
+    cliInit();
+  #endif
+
+  /* Initialise the CC3000 WiFi module and connect to an AP */
+  #ifdef CFG_CC3000
+    /* Setup the CC3000 pins */
+    LPC_IOCON ->TRST_PIO0_14  &= ~0x07;
+    LPC_IOCON ->TRST_PIO0_14  |= 0x01;
+    LPC_IOCON ->PIO0_17       &= ~0x07;
+    LPC_IOCON ->PIO0_16       &= ~0x1F;
+    LPC_IOCON ->PIO0_16       |= (1<<4);
+  #endif
+
+  /* Turn the user LED on after init to indicate that everything is OK */
+  boardLED(CFG_LED_ON);
+}
+
+/* The following code is used if CMSIS RTOS (RTX) is enabled */
+#ifdef CFG_CMSIS_RTOS
+
+  /* Thread IDs */
+  osThreadId tid_mainthread;      /* ID for main thread   */
+  osThreadId tid_blinkythread;    /* ID for blinky thread */
+
+  /* Function prototypes */
+  void main_thread(void const *argument);
+  void blinky_thread (void const *argument);
+
+  /* Thread definitions */
+  osThreadDef(blinky_thread, osPriorityHigh, 1, 0);
+  osThreadDef(main_thread, osPriorityNormal, 1, 4 * OS_MAINSTKSIZE);
+
+  /**************************************************************************/
+  /*!
+      @brief Blinky thread, high priority, active very 3ms
+  */
+  /**************************************************************************/
+  void blinky_thread (void const *argument)
+  {
+   while (1)
+   {
+     /* Pass control to other tasks for 1s */
+     osDelay(1000);
+     printf ("Thread 1\n");
+   }
+  }
+
+  /**************************************************************************/
+  /*!
+      @brief Main thread, normal priority
+  */
+  /**************************************************************************/
+  void main_thread(void const *argument)
+  {
+    uint32_t currentSecond, lastSecond;
+    currentSecond = lastSecond = 0;
+
+    for (;;)
+    {
+       osDelay(1000);
+       boardLED((currentSecond++) & 1);
+    }
+  }
+
+  /**************************************************************************/
+  /*!
+      @brief RTX code entry point (replaces non-RTOS main further down!)
+  */
+  /**************************************************************************/
+  int main(void)
+  {
+    /* Initiaise the HW */
+    boardInit();
+
+    /* Initialise the RTX kernel */
+    osKernelInitialize();
+
+    /* Create out threads */
+    tid_mainthread = osThreadCreate(osThread(main_thread), NULL);
+    tid_blinkythread = osThreadCreate(osThread(blinky_thread), NULL);
+
+    /* Start the kernel and then go into an endless loop */
+    osKernelStart();
+
+    /* No return */
+    while(1);
+
+    return 1;
+  }
+
+#endif /* CFG_CMSIS_RTOS */
+
+#ifndef _TEST_
+#ifndef CFG_CMSIS_RTOS
+/**************************************************************************/
+/*!
+    @brief Primary (non-RTOS!) entry point for this project.
+*/
+/**************************************************************************/
+volatile uint32_t test[8] = { 0 };
+int main(void)
+{
+  uint32_t currentSecond, lastSecond;
+  currentSecond = lastSecond = 0;
+
+  /* Configure the HW */
+  boardInit();
+
+  while (1)
+  {
+    /* Blinky (1Hz) */
+    currentSecond = delayGetSecondsActive();
+    if (currentSecond != lastSecond)
+    {
+      lastSecond = currentSecond;
+      boardLED(lastSecond % 2);
+    }
+
+    /* Check for binary protocol input if CFG_PROTOCOL is enabled */
+    #ifdef CFG_PROTOCOL
+      prot_task(NULL);
+    #endif
+
+    /* Poll for CLI input if CFG_INTERFACE is enabled */
+    #ifdef CFG_INTERFACE
+      cliPoll();
+    #endif
+
+//    if ( usb_custom_is_ready_to_send() )
+//    {
+//      static uint32_t magic_number = 0;
+//      uint32_t buffer[2][16];  // 2x64 byte in size
+//      buffer[0][0] = magic_number++;
+//      buffer[1][0] = magic_number++;
+//      usb_custom_send(buffer, 64*2);
+//    }
+//
+//    if (custom_recv_magic_number != 0)
+//    {
+//      printf("%d\n", custom_recv_magic_number);
+//      custom_recv_magic_number = 0;
+//    }
+
+    /* Optionally enter high level sleep mode here via WFI */
+  }
+}
+#endif /* !CFG_CMSIS_RTOS */
+#endif /* !_TEST_ */
+
+/**************************************************************************/
+/*!
+    @brief Turns the LED(s) on or off
+*/
+/**************************************************************************/
+void boardLED(uint8_t state)
+{
+  if (state)
+  {
+    LPC_GPIO->SET[CFG_LED_PORT] = (1 << CFG_LED_PIN);
+  }
+  else
+  {
+    LPC_GPIO->CLR[CFG_LED_PORT] = (1 << CFG_LED_PIN);
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Configure the board for low power and enter sleep mode
+*/
+/**************************************************************************/
+void boardSleep(void)
+{
+  // ToDo!
+}
+
+/**************************************************************************/
+/*!
+    @brief  Restores parts and system peripherals to an appropriate
+            state after waking up from sleep mode
+*/
+/**************************************************************************/
+void boardWakeup(void)
+{
+  // ToDo!
+}
+
+#endif /* CFG_BRD_LPCXPRESSO_LPC1347 */
diff --git a/reform2-lpc-fw/src/boards/lpcxpresso1347/board_lpcxpresso1347.h b/reform2-lpc-fw/src/boards/lpcxpresso1347/board_lpcxpresso1347.h
new file mode 100644
index 0000000000000000000000000000000000000000..e90148ae38faf0dc72713064b786695fb8338751
--- /dev/null
+++ b/reform2-lpc-fw/src/boards/lpcxpresso1347/board_lpcxpresso1347.h
@@ -0,0 +1,742 @@
+/**************************************************************************/
+/*!
+    @file     board_lpcxpresso1347.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Board file for the LPC1347 LPCXpresso board from NXP
+    @ingroup  Boards
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012 K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __BOARD_LPCXPRESSO1347_H__
+#define __BOARD_LPCXPRESSO1347_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sysdefs.h"
+
+/*=========================================================================
+    MCU SELECTION
+
+    Include one of the following definitions depending on if you are
+    using the LPC11U37 or LPC1347.  They're generally interchangeable, but
+    the LPC11Uxx and LPC13xx CMSIS implementations have some differences
+    in naming convention, and occasionally a feature is only available on
+    the M3 (DWT for example).  Selecting the appropriate MCU allows
+    the right code to be included when differences between the CMSIS
+    implementations are present.
+
+    -----------------------------------------------------------------------*/
+    // #define CFG_MCU_LPC11U24FBD48_401
+    // #define CFG_MCU_LPC11U37FBD48_401
+    #define CFG_MCU_LPC1347FBD48
+    // #define CFG_MCU_LPC1347FHN33
+
+    /* Basic error checking */
+    #if !defined CFG_MCU_LPC1347FBD48 && \
+        !defined CFG_MCU_LPC11U37FBD48_401 && \
+        !defined CFG_MCU_LPC11U24FBD48_401 && \
+        !defined CFG_MCU_LPC1347FHN33
+      #error "An MCU must be selected in projectconfig.h (Ex. CFG_MCU_LPC11U37FBD48_401, CFG_MCU_LPC1347FBD48, etc.)"
+    #endif
+
+    /* Set flag to indicate which CMSIS library to use */
+    #if (defined CFG_MCU_LPC1347FBD48 || defined CFG_MCU_LPC1347FHN33)
+      #define CFG_MCU_FAMILY_LPC13UXX
+    #elif (defined CFG_MCU_LPC11U24FBD48_401 || defined CFG_MCU_LPC11U37FBD48_401)
+      #define CFG_MCU_FAMILY_LPC11UXX
+    #endif
+
+    /* Include the correct MCU header file */
+    #if defined CFG_MCU_FAMILY_LPC13UXX
+      #include "LPC13Uxx.h"
+    #endif
+    #if defined CFG_MCU_FAMILY_LPC11UXX
+      #include "LPC11Uxx.h"
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    FIRMWARE VERSION SETTINGS
+    -----------------------------------------------------------------------*/
+    #define CFG_FIRMWARE_VERSION_MAJOR      (0)
+    #define CFG_FIRMWARE_VERSION_MINOR      (0)
+    #define CFG_FIRMWARE_VERSION_REVISION   (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PIN USAGE
+    -----------------------------------------------------------------------
+    This table tries to give an indication of which GPIO pins and
+    peripherals are used by the available drivers and SW examples.  Only
+    dedicated GPIO pins available on the LPC1347 Reference Board are shown
+    below.  Any unused peripheral blocks like I2C, SSP, ADC, etc., can
+    also be used as GPIO if they are available.
+
+                PORT 0
+                =========================================================
+                0 1 2 3 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
+
+    HX8340B     . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    HX8347G     . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    CHIBI       . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    SSD1306 I2C . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    FAT32/MMC   . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  X  .  .
+    PN532 I2C   . . . . . . . .  .  .  .  .  .  .  X  X  .  .  .  .  .  .
+    PCF2129A    . . . . . . . .  .  .  .  .  .  .  X  X  .  .  .  .  .  .
+
+                PORT 1
+                ===========================================================================
+                0 1 2 3 4 5 7 8 10 11 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 31
+                + + + + + + + +  +  +              +  +                                   -
+
+    HX8340B     . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  X  X  X  X  X  .
+    HX8347G     . . . . . . . .  .  .  X  X  X  X  .  .  X  X  X  X  X  X  X  X  X  X  .  .
+    CHIBI       . . . . . . . .  .  .  X  X  X  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    SSD1306 I2C . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    FAT32/MMC   . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  X  X  .  .  .  .  .  .
+    PN532 I2C   . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    PCF2129A    . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+
+                TIMERS                   SSP   ADC               UART
+                ======================   ===   ===============   ====
+                16B0  16B1  32B0  32B1   0 1   0 1 2 3 4 5 6 7   0
+
+    HX8340B     .      .    .     .      . .   . . . . . . . .   .
+    HX8347G     .      .    .     .      . .   . . . . . . . .   .
+    CHIBI       .      .    .     .      X .   . . . . . . . .   .
+    SSD1306 I2C .      .    .     .      . .   . . . . . . . .   .
+    FAT32/MMC   .      .    .     .      . X   . . . . . . . .   .
+
+    [+]   Only available on QFP64 package
+    [-]   Only available on QFP48 package
+
+  =========================================================================*/
+
+
+/*=========================================================================
+    GPIO INTERRUPTS
+    -----------------------------------------------------------------------
+    This table shows where GPIO interrupts are mapped in this project
+    (Note that the LPC11U and LPC13U use different names for the
+    IRQ Handlers in the standard headers)
+
+    Interrupt                                     Location
+    ------------------------------------------    -------------------------
+    PIN_INT0_IRQHandler - FLEX_INT0_IRQHandler    chb_drvr.c
+    PIN_INT1_IRQHandler - FLEX_INT1_IRQHandler    pcf2129.c
+    PIN_INT2_IRQHandler - FLEX_INT2_IRQHandler    spi.c (cc3000)
+    PIN_INT3_IRQHandler - FLEX_INT3_IRQHandler
+    PIN_INT4_IRQHandler - FLEX_INT4_IRQHandler
+    PIN_INT5_IRQHandler - FLEX_INT5_IRQHandler
+    PIN_INT6_IRQHandler - FLEX_INT6_IRQHandler
+    PIN_INT7_IRQHandler - FLEX_INT7_IRQHandler
+    GINT0_IRQHandler
+    GINT0_IRQHandler
+    -----------------------------------------------------------------------*/
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SUPPORTED PERIPHERALS
+    -----------------------------------------------------------------------
+    Because all ISRs are referenced in the startup code, GCC typically
+    won't optimise out the ISR functions during compilation even if the
+    ISRs will never be entered, resulting in larger binaries than required
+    (for example if no I2C sensors are used, be sure to disable I2C support
+    since the I2C ISR is quite large).
+
+    Use the defines below to include or exclude support for specific
+    peripherals.
+
+    NOTE: GPIO ISRs are handled separately in GPIO INTERRUPTS below
+    -----------------------------------------------------------------------*/
+    #define CFG_ENABLE_I2C
+    #define CFG_ENABLE_UART
+    #define CFG_ENABLE_USB
+    #define CFG_ENABLE_TIMER32
+/*=========================================================================*/
+
+
+/*=========================================================================
+    ENABLE CMSIS-RTOS
+
+    -----------------------------------------------------------------------*/
+    // #define CFG_CMSIS_RTOS
+
+    #if defined CFG_CMSIS_RTOS
+      #include "board_lpcxpresso1347_rtxconf.h"
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    EEPROM
+    -----------------------------------------------------------------------
+    EEPROM is used to persist certain user modifiable values to make
+    sure that these changes remain in effect after a reset or hard
+    power-down.  The addresses in EEPROM for these various system
+    settings/values are defined below.  The first 256 bytes of EEPROM
+    are reserved for this (0x0000..0x00FF).
+
+    CFG_EEPROM_SIZE           The number of bytes available on the EEPROM
+    CFG_EEPROM_RESERVED       The last byte of reserved EEPROM memory
+
+          EEPROM Address (0x0000..0x00FF)
+          ===============================
+          0 1 2 3 4 5 6 7 8 9 A B C D E F
+    000x  x x . . x x x x x x x x . . . .   Chibi
+    001x  . . . . . . . . . . . . . . . .
+    002x  . . . . . . . . . . . . . . . .
+    003x  . . . . . . . . . . . . . . . .
+    004x  . . . . . . . . . . . . . . . .
+    005x  . . . . . . . . . . . . . . . .
+    006x  . . . . . . . . . . . . . . . .
+    007x  . . . . . . . . . . . . . . . .
+    008x  . . . . . . . . . . . . . . . .
+    009x  . . . . . . . . . . . . . . . .
+    00Ax  . . . . . . . . . . . . . . . .
+    00Bx  . . . . . . . . . . . . . . . .
+    00Cx  . . . . . . . . . . . . . . . .
+    00Dx  . . . . . . . . . . . . . . . .
+    00Ex  . . . . . . . . . . . . . . . .
+    00Fx  . . . . . . . . . . . . . . . .
+
+    -----------------------------------------------------------------------*/
+    #define CFG_EEPROM_SIZE                   (4032)
+    #define CFG_EEPROM_RESERVED               (0x00FF)              // Protect first 256 bytes of memory
+    #define CFG_EEPROM_CHIBI_NODEADDR         (uint16_t)(0x0000)    // 2
+    #define CFG_EEPROM_CHIBI_IEEEADDR         (uint16_t)(0x0004)    // 8
+/*=========================================================================*/
+
+
+/*=========================================================================
+    ON-BOARD LED
+    -----------------------------------------------------------------------
+
+    CFG_LED_PORT              The port for the on board LED
+    CFG_LED_PIN               The pin for the on board LED
+    CFG_LED_ON                The pin state to turn the LED on (0 = low, 1 = high)
+    CFG_LED_OFF               The pin state to turn the LED off (0 = low, 1 = high)
+
+    -----------------------------------------------------------------------*/
+    #define CFG_LED_PORT                  (0)
+    #define CFG_LED_PIN                   (7)
+    #define CFG_LED_ON                    (1)
+    #define CFG_LED_OFF                   (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    ADC
+    -----------------------------------------------------------------------
+
+    CFG_ADC_MODE_LOWPOWER     If set to 1, this will configure the ADC
+                              for low-power operation (LPC1347 only)
+    CFG_ADC_MODE_10BIT        If set to 1, this will configure the ADC
+                              for 10-bit mode (LPC1347 only)
+
+    -----------------------------------------------------------------------*/
+    #define CFG_ADC_MODE_LOWPOWER       (0)
+    #define CFG_ADC_MODE_10BIT          (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    UART
+    -----------------------------------------------------------------------
+
+    CFG_UART_BAUDRATE         The default UART speed.  This value is used
+                              when initialising UART, and should be a
+                              standard value like 57600, 9600, etc.
+                              NOTE: This value may be overridden if
+                              another value is stored in EEPROM!
+    CFG_UART_BUFSIZE          The length in bytes of the UART RX FIFO. This
+                              will determine the maximum number of received
+                              characters to store in memory.
+
+    -----------------------------------------------------------------------*/
+    #define CFG_UART_BAUDRATE           (115200)
+    #define CFG_UART_BUFSIZE            (256)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SPI
+    -----------------------------------------------------------------------
+
+    CFG_SSP_SCK0_LOCATION     The location of the SCK pin for SSP0
+    CFG_SSP_MISO1_LOCATION    The location of the MISO1 pin for SSP1
+    CFG_SSP_MOSI1_LOCATION    The location of the MOSI1 pin for SSP1
+    CFG_SSP_SCK1_LOCATION     The location of the SCK pin for SSP1
+
+    -----------------------------------------------------------------------*/
+    #define CFG_SSP_SCK0_0_6            (6)     // Used by USBConnect
+    #define CFG_SSP_SCK0_0_10           (10)    // Used by SWD
+    #define CFG_SSP_SCK0_1_29           (29)
+
+    #define CFG_SSP_MISO1_0_22          (22)
+    #define CFG_SSP_MISO1_1_21          (21)
+    #define CFG_SSP_MOSI1_0_21          (21)
+    #define CFG_SSP_MOSI1_1_22          (22)
+    #define CFG_SSP_SCK1_1_15           (15)
+    #define CFG_SSP_SCK1_1_20           (20)
+
+    // Select the appropriate pin locations here
+    #define CFG_SSP_SCK0_LOCATION       (CFG_SSP_SCK0_1_29)
+    #define CFG_SSP_MISO1_LOCATION      (CFG_SSP_MISO1_1_21)
+    #define CFG_SSP_MOSI1_LOCATION      (CFG_SSP_MOSI1_1_22)
+    #define CFG_SSP_SCK1_LOCATION       (CFG_SSP_SCK1_1_20)
+
+    // Set the phase and polarity for SSP0 and SSP1
+    #define CFG_SSP_CPOL0               (0)
+    #define CFG_SSP_CPHA0               (1)   /* CC3000 = Mode 1 */
+    #define CFG_SSP_CPOL1               (0)
+    #define CFG_SSP_CPHA1               (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PRINTF REDIRECTION
+    -----------------------------------------------------------------------
+
+    CFG_PRINTF_MAXSTRINGSIZE  Maximum size of string buffer for printf
+    CFG_PRINTF_UART           Will cause all printf statements to be
+                              redirected to UART
+    CFG_PRINTF_USBCDC         Will cause all printf statements to be
+                              redirect to USB Serial
+    CFG_PRINTF_NEWLINE        This is typically "\r\n" for Windows or
+                              "\n" for *nix
+
+    Note: If no printf redirection definitions are present, all printf
+    output will be ignored.
+    -----------------------------------------------------------------------*/
+    #define CFG_PRINTF_MAXSTRINGSIZE    (255)
+
+    // #define CFG_PRINTF_UART
+    #define CFG_PRINTF_USBCDC
+    // #define CFG_PRINTF_DEBUG
+
+    #ifdef CFG_PRINTF_DEBUG
+      #define CFG_PRINTF_NEWLINE          "\n"
+    #else
+      #define CFG_PRINTF_NEWLINE          "\r\n"
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    COMMAND LINE INTERFACE
+    -----------------------------------------------------------------------
+
+    CFG_INTERFACE             If this field is defined the UART or USBCDC
+                              based command-line interface will be included
+    CFG_INTERFACE_MAXMSGSIZE  The maximum number of bytes to accept for an
+                              incoming command
+    CFG_INTERFACE_PROMPT      The command prompt to display at the start
+                              of every new data entry line
+    CFG_INTERFACE_SILENTMODE  If this is set to 1 only text generated in
+                              response to commands will be send to the
+                              output buffer.  The command prompt will not
+                              be displayed and incoming text will not be
+                              echoed back to the output buffer (allowing
+                              you to see the text you have input).  This
+                              is normally only desirable in a situation
+                              where another MCU is communicating with
+                              the LPC1343.
+    CFG_INTERFACE_DROPCR      If this is set to 1 all incoming \r
+                              characters will be dropped
+    CFG_INTERFACE_ENABLEIRQ   If this is set to 1 the IRQ pin will be
+                              set high when a command starts executing
+                              and will go low when the command has
+                              finished executing or the LCD is not busy.
+                              This allows another device to know when a
+                              new command can safely be sent.
+    CFG_INTERFACE_IRQPORT     The gpio port for the IRQ/busy pin
+    CFG_INTERFACE_IRQPIN      The gpio pin number for the IRQ/busy pin
+    CFG_INTERFACE_SHORTERRORS If this is enabled only short 1 character
+                              error messages will be returned (followed
+                              by CFG_PRINTF_NEWLINE), rather than more
+                              verbose error messages.  The specific
+                              characters used are defined below.
+    CFG_INTERFACE_CONFIRMREADY  If this is set to 1 a text confirmation
+                              will be sent when the command prompt is
+                              ready for a new command.  This is in
+                              addition to CFG_INTERFACE_ENABLEIRQ if
+                              this is also enabled.  The character used
+                              is defined below.
+    CFG_INTERFACE_LONGSYSINFO If this is set to 1 extra information will
+                              be included in the Sys Info ('V') command
+                              on the CLI. This can be useful when trying
+                              to debug problems on remote HW, or with
+                              unknown firmware.  It will also use about
+                              0.5KB flash, though, so only enable it is
+                              necessary.
+
+    NOTE:                     The command-line interface will use either
+                              USB-CDC or UART depending on whether
+                              CFG_PRINTF_UART or CFG_PRINTF_USBCDC are
+                              selected.
+    -----------------------------------------------------------------------*/
+    #define CFG_INTERFACE
+    #define CFG_INTERFACE_MAXMSGSIZE    (256)
+    #define CFG_INTERFACE_PROMPT        "LPC1347 >> "
+    #define CFG_INTERFACE_SILENTMODE    (0)
+    #define CFG_INTERFACE_DROPCR        (0)
+    #define CFG_INTERFACE_ENABLEIRQ     (0)
+    #define CFG_INTERFACE_IRQPORT       (0)
+    #define CFG_INTERFACE_IRQPIN        (7)
+    #define CFG_INTERFACE_SHORTERRORS   (0)
+    #define CFG_INTERFACE_CONFIRMREADY  (0)
+    #define CFG_INTERFACE_LONGSYSINFO   (1)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SIMPLE BINARY PROTOCOL
+    -----------------------------------------------------------------------
+
+    CFG_PROTOCOL             If this field is defined the binary command
+                              parser will be included
+    -----------------------------------------------------------------------*/
+    #define CFG_PROTOCOL
+
+    #define CFG_PROTOCOL_VIA_HID
+    // #define CFG_PROTOCOL_VIA_BULK
+
+    #if defined(CFG_PROTOCOL) && !defined(CFG_PROTOCOL_VIA_HID) && !defined(CFG_PROTOCOL_VIA_BULK)
+        #error CFG_PROTOCOL must be enabled with either CFG_PROTOCOL_VIA_HID or CFG_PROTOCOL_VIA_BULK
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    TFT LCD
+    -----------------------------------------------------------------------
+
+    CFG_TFTLCD                  If defined, this will cause drivers for
+                                a pre-determined LCD screen to be included
+                                during build.  Only one LCD driver can be
+                                included during the build process (for ex.
+                                'drivers/displays/hw/ILI9325.c')
+    CFG_TFTLCD_INCLUDESMALLFONTS If set to 1, smallfont support will be
+                                included for 3x6, 5x8, 7x8 and 8x8 fonts.
+                                This should only be enabled if these small
+                                fonts are required since there is already
+                                support for larger fonts generated with
+                                Dot Factory
+                                http://www.pavius.net/downloads/tools/53-the-dot-factory
+    CFG_TFTLCD_USEAAFONTS       If set to a non-zero value, anti-aliased
+                                fonts will be used instead of regular 1-bit
+                                font.  These result in much higher-
+                                quality text, but the fonts are 2 or 4
+                                times larger than plain bitmap fonts and
+                                take a bit more rendering time to display.
+    CFG_TFTLCD_TS_DEFAULTTHRESHOLD  Default minimum threshold to trigger a
+                                touch event with the touch screen (and exit
+                                from 'tsWaitForEvent' in touchscreen.c).
+                                Should be an 8-bit value somewhere between
+                                8 and 75 in normal circumstances.  This is
+                                the default value and may be overriden by
+                                a value stored in EEPROM.
+    CFG_TFTLCD_TS_KEYPADDELAY   The delay in milliseconds between key
+                                presses in dialogue boxes
+    ----------------------------------------------------------------------*/
+    // #define CFG_TFTLCD
+    #define CFG_TFTLCD_INCLUDESMALLFONTS   (1)
+    #define CFG_TFTLCD_USEAAFONTS          (0)
+    #define CFG_TFTLCD_TS_DEFAULTTHRESHOLD (50)
+    #define CFG_TFTLCD_TS_KEYPADDELAY      (100)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    MICRO-SD CARD
+    -----------------------------------------------------------------------
+
+    CFG_SDCARD                If this field is defined SD Card and FAT32
+                              file system support will be included
+    CFG_SDCARD_SPIPORT        SSP Port used for the SD card (0 or 1)
+    CFG_SDCARD_READONLY       If this is set to 1, all commands to
+                              write to the SD card will be removed
+                              saving some flash space.
+    CFG_SDCARD_CDPORT         The card detect port number
+    CFG_SDCARD_CDPIN          The card detect pin number
+
+    NOTE:                     All config settings for FAT32 are defined
+                              in ffconf.h
+    -----------------------------------------------------------------------*/
+    // #define CFG_SDCARD
+    #define CFG_SDCARD_READONLY         (1)   // Must be 0 or 1
+    #define CFG_SDCARD_SPIPORT          (0)
+    #define CFG_SDCARD_SSELPORT         (0)
+    #define CFG_SDCARD_SSELPIN          (0)
+    #define CFG_SDCARD_CDPORT           (0)
+    #define CFG_SDCARD_CDPIN            (0)
+    #define CFG_SDCARD_ENBLPORT         (0)
+    #define CFG_SDCARD_ENBLPIN          (0)
+
+    #ifdef CFG_SDCARD
+      #if !((CFG_SDCARD_READONLY == 0) || (CFG_SDCARD_READONLY == 1))
+        #error "Invalid value for CFG_SDCARD_READONLY"
+      #endif
+      #if !((CFG_SDCARD_SPIPORT == 0) || (CFG_SDCARD_SPIPORT == 1))
+        #error "Invalid SPI port for CFG_SDCARD_SPIPORT"
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    CHIBI WIRELESS STACK
+    -----------------------------------------------------------------------
+
+    CFG_CHIBI                   If defined, the CHIBI wireless stack will be
+                                included during build.  Requires external HW.
+    CFG_CHIBI_MODE              The mode to use when receiving and transmitting
+                                wireless data.  See chb_drvr.h for possible values
+    CFG_CHIBI_POWER             The power level to use when transmitting.  See
+                                chb_drvr.h for possible values
+    CFG_CHIBI_CHANNEL           802.15.4 Channel (0 = 868MHz, 1-10 = 915MHz)
+    CFG_CHIBI_PANID             16-bit PAN Identifier (ex.0x1234)
+    CFG_CHIBI_PROMISCUOUS       Set to 1 to enabled promiscuous mode or
+                                0 to disable it.  If promiscuous mode is
+                                enabled be sure to set CFG_CHIBI_BUFFERSIZE
+                                to an appropriately large value (ex. 1024)
+    CFG_CHIBI_BUFFERSIZE        The size of the message buffer in bytes
+    -----------------------------------------------------------------------*/
+    // #define CFG_CHIBI
+    #define CFG_CHIBI_MODE              (0)                 // OQPSK_868MHZ
+    #define CFG_CHIBI_POWER             (0xE9)              // CHB_PWR_EU2_3DBM
+    #define CFG_CHIBI_CHANNEL           (0)                 // 868-868.6 MHz
+    #define CFG_CHIBI_PANID             (0x1234)
+    #define CFG_CHIBI_PROMISCUOUS       (0)
+    #define CFG_CHIBI_BUFFERSIZE        (256)
+
+    // Pin config settings
+    #define CFG_CHIBI_SPIPORT           (0)  // Must be 0 or 1
+    #define CFG_CHIBI_SSPORT            (0)
+    #define CFG_CHIBI_SSPIN             (0)
+    #define CFG_CHIBI_EINTPORT          (0)
+    #define CFG_CHIBI_EINTPIN           (0)
+    #define CFG_CHIBI_RSTPORT           (0)
+    #define CFG_CHIBI_RSTPIN            (0)
+    #define CFG_CHIBI_SLPTRPORT         (0)
+    #define CFG_CHIBI_SLPTRPIN          (0)
+    #define CFG_CHIBI_CC1190_HGM_PORT   (0)   // Not used
+    #define CFG_CHIBI_CC1190_HGM_PIN    (0)   // Not used
+
+    #ifdef CFG_CHIBI
+      #if !((CFG_CHIBI_SPIPORT == 0) || (CFG_CHIBI_SPIPORT == 1))
+        #error "Invalid SPI port for CFG_CHIBI_SPIPORT"
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    CC3000 WIFI MODULES
+    -----------------------------------------------------------------------
+
+    CFG_CC3000                     If defined, CC3000 support will be
+                                   included during build.  Requires
+                                   external HW
+    -----------------------------------------------------------------------*/
+    // #define CFG_CC3000
+    #define CFG_CC3000_SPI_PORT         (0)
+    #define CFG_CC3000_EN_PORT          (0)
+    #define CFG_CC3000_EN_PIN           (14)
+    #define CFG_CC3000_IRQ_PORT         (0)
+    #define CFG_CC3000_IRQ_PIN          (16)
+    #define CFG_CC3000_CS_PORT          (0)
+    #define CFG_CC3000_CS_PIN           (17)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PN532/NFC STACK
+    -----------------------------------------------------------------------
+
+    CFG_PN532                      If defined, the PN532/NFC stack will be
+                                   included during build.  Requires
+                                   external HW
+    CFG_PN532_MEM_POOL_SIZE_BYTES  Size of the dynamic memory pool in bytes
+                                   (used by pn532/mem_allocator/ when
+                                   working with NDEF messages)
+    -----------------------------------------------------------------------*/
+    // #define CFG_PN532
+    #define CFG_PN532_RSTPD_PORT                      (0)
+    #define CFG_PN532_RSTPD_PIN                       (16)
+    #define CFG_PN532_I2C_IRQPORT                     (0)
+    #define CFG_PN532_I2C_IRQPIN                      (17)
+    #define CFG_PN532_MEM_POOL_SIZE_BYTES             (512)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    RTC SUPPORT
+    -----------------------------------------------------------------------
+
+    CFG_RTC                     If defined, RTC support will be included.
+                                Requires external HW.
+    -----------------------------------------------------------------------*/
+    // #define CFG_RTC
+
+    #if defined(CFG_RTC) && !defined(CFG_ENABLE_I2C)
+      #error "CFG_ENABLE_I2C must be defined with CFG_RTC"
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    STEPPER MOTOR SUPPORT
+    -----------------------------------------------------------------------
+
+    CFG_STEPPER                 If defined, basic stepper motor support
+                                will be included.  Requires external HW.
+    -----------------------------------------------------------------------*/
+    // #define CFG_STEPPER
+    #define CFG_STEPPER_TIMER32                       (0)
+    #define CFG_STEPPER_IN1_PORT                      (0)
+    #define CFG_STEPPER_IN1_PIN                       (8)
+    #define CFG_STEPPER_IN2_PORT                      (0)
+    #define CFG_STEPPER_IN2_PIN                       (9)
+    #define CFG_STEPPER_IN3_PORT                      (0)
+    #define CFG_STEPPER_IN3_PIN                       (14)
+    #define CFG_STEPPER_IN4_PORT                      (0)
+    #define CFG_STEPPER_IN4_PIN                       (13)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    USB
+
+    CFG_USB_STRING_MANUFACTURER Manufacturer name that will appear in the
+                                device descriptor during USB enumeration
+    CFG_USB_STRING_PRODUCT      Product name that will appear in the
+                                device descriptor during USB enumeration
+    CFG_USB_VENDORID            16-bit USB vendor ID
+    USB_PRODUCT_ID              Define this to set a custom product ID
+                                if you do not wish to use the 'auto'
+                                product ID feature
+    CFG_CDC                     Enable USB CDC support
+    CFG_USB_HID_KEYBOARD        Enable USB HID keyboard emulation
+    CFG_USB_HID_MOUSE           Enable USB HID mouse emulation for a five
+                                button 'Windows' mouse with scroll wheels
+    CFG_USB_HID_GENERIC         Enable USB HID Generic support for custom
+                                in and out reports, with report size set
+                                via CFG_USB_HID_GENERIC_REPORT_SIZE
+    CFG_USB_MSC                 Enable USB Mass Storage support, pointing
+                                to the SD card reader (requires mmc.c from
+                                the FATFS drivers, but doesn't use FATFS)
+
+
+    You can combine more than one USB class below and they will be
+    automatically combined in a USB composite device within the limit of
+    available USB endpoints.  The USB Product ID is calculated automatically
+    based on the combination of classes defined below.
+
+    NOTE: Windows requires the .inf file in '/core/usb' for CDC support
+    -----------------------------------------------------------------------*/
+    #ifdef CFG_ENABLE_USB
+      #define CFG_USB_STRING_MANUFACTURER       "microBuilder.eu"
+      #define CFG_USB_STRING_PRODUCT            "LPC1347 LPCXpresso"
+      #define CFG_USB_VENDORID                  (0x1FC9)
+
+      #define CFG_USB_CDC
+
+      // #define CFG_USB_HID_KEYBOARD
+      // #define CFG_USB_HID_MOUSE
+      #define CFG_USB_HID_GENERIC
+      #define CFG_USB_HID_GENERIC_REPORT_SIZE (64)
+
+      // #define CFG_USB_MSC
+
+      // #define CFG_USB_CUSTOM_CLASS
+
+      #if (defined(CFG_USB_CDC)       || defined(CFG_USB_HID_KEYBOARD) || \
+           defined(CFG_USB_HID_MOUSE) || defined(CFG_USB_HID_GENERIC)  || \
+           defined(CFG_USB_MSC)       || defined(CFG_USB_CUSTOM_CLASS))
+        #define CFG_USB
+        #if defined(CFG_USB_HID_KEYBOARD) || defined(CFG_USB_HID_MOUSE) || defined(CFG_USB_HID_GENERIC)
+          #define CFG_USB_HID
+          #if defined(CFG_USB_HID_GENERIC) && (CFG_USB_HID_GENERIC_REPORT_SIZE > 64)
+            #error "CFG_USB_HID_GENERIC_REPORT_SIZE exceeds the maximum value of 64 bytes (based on USB specs 2.0 for 'Full Speed Interrupt Endpoint Size')"
+          #endif
+        #endif
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    CONFIG FILE VALIDATION
+
+    Basic error checking to make sure that incompatible defines are not
+    enabled at the same time, etc.
+
+    -----------------------------------------------------------------------*/
+    #if defined(CFG_INTERFACE) && !( defined CFG_PRINTF_UART || defined CFG_PRINTF_USBCDC || defined CFG_PRINTF_DEBUG)
+      #error "At least one CFG_PRINTF target must be defined with CFG_INTERFACE"
+    #endif
+
+    #if defined(CFG_PRINTF_UART) && !defined(CFG_ENABLE_UART)
+      #error "CFG_ENABLE_UART must be enabled with CFG_PRINTF_UART"
+    #endif
+
+    #if defined(CFG_PRINTF_USBCDC) && !defined(CFG_USB_CDC)
+      #error "CFG_USB_CDC must be defined with CFG_PRINTF_USBCDC"
+    #endif
+
+    #if defined(CFG_USB_MSC) && !defined(CFG_SDCARD)
+      #error "CFG_USB_MSC must be defined with CFG_SDCARD"
+    #endif
+
+    #if defined(CFG_PROTOCOL)
+      #if defined(CFG_PROTOCOL_VIA_HID) && !defined(CFG_USB_HID_GENERIC)
+        #error "CFG_PROTOCOL_VIA_HID requires CFG_USB_HID_GENERIC"
+      #endif
+
+      #if defined(CFG_PROTOCOL_VIA_BULK) && !defined(CFG_USB_CUSTOM_CLASS)
+        #error "CFG_PROTOCOL_VIA_BULK requires CFG_USB_CUSTOM_CLASS to be defined"
+      #endif
+    #endif
+/*=========================================================================*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/boards/lpcxpresso1347/board_lpcxpresso1347_rtxconf.h b/reform2-lpc-fw/src/boards/lpcxpresso1347/board_lpcxpresso1347_rtxconf.h
new file mode 100644
index 0000000000000000000000000000000000000000..d617e6ce15a61cc2719f85d23adae480e9bba0a5
--- /dev/null
+++ b/reform2-lpc-fw/src/boards/lpcxpresso1347/board_lpcxpresso1347_rtxconf.h
@@ -0,0 +1,213 @@
+/*----------------------------------------------------------------------------
+ *      RL-ARM - RTX
+ *----------------------------------------------------------------------------
+ *      Name:    board_lpcxpresso1347_rtxconf.h
+ *      Purpose: Configuration of CMSIS RTX Kernel for Cortex-M
+ *      Rev.:    V4.70
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "projectconfig.h"
+
+#if defined CFG_BRD_LPCXPRESSO_LPC1347
+#include "cmsis_os.h"
+
+/*----------------------------------------------------------------------------
+ *      RTX User configuration part BEGIN
+ *---------------------------------------------------------------------------*/
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
+//
+// <h>Thread Configuration
+// =======================
+//
+//   <o>Number of concurrent running threads <0-250>
+//   <i> Defines max. number of threads that will run at the same time.
+//   <i> Default: 6
+#ifndef OS_TASKCNT
+ #define OS_TASKCNT     3
+#endif
+
+//   <o>Default Thread stack size [bytes] <64-4096:8><#/4>
+//   <i> Defines default stack size for threads with osThreadDef stacksz = 0
+//   <i> Default: 200
+#ifndef OS_STKSIZE
+ #define OS_STKSIZE     150
+#endif
+
+//   <o>Main Thread stack size [bytes] <64-4096:8><#/4>
+//   <i> Defines stack size for main thread.
+//   <i> Default: 200
+#ifndef OS_MAINSTKSIZE
+ #define OS_MAINSTKSIZE 200
+#endif
+
+//   <o>Number of threads with user-provided stack size <0-250>
+//   <i> Defines the number of threads with user-provided stack size.
+//   <i> Default: 0
+#ifndef OS_PRIVCNT
+ #define OS_PRIVCNT     0
+#endif
+
+//   <o>Total stack size [bytes] for threads with user-provided stack size <0-4096:8><#/4>
+//   <i> Defines the combined stack size for threads with user-provided stack size.
+//   <i> Default: 0
+#ifndef OS_PRIVSTKSIZE
+ #define OS_PRIVSTKSIZE 0
+#endif
+
+// <q>Check for stack overflow
+// <i> Includes the stack checking code for stack overflow.
+// <i> Note that additional code reduces the Kernel performance.
+#ifndef OS_STKCHECK
+ #define OS_STKCHECK    1
+#endif
+
+// <o>Processor mode for thread execution
+//   <0=> Unprivileged mode
+//   <1=> Privileged mode
+// <i> Default: Privileged mode
+#ifndef OS_RUNPRIV
+ #define OS_RUNPRIV     1
+#endif
+
+// </h>
+
+// <h>RTX Kernel Timer Tick Configuration
+// ======================================
+// <q> Use Cortex-M SysTick timer as RTX Kernel Timer
+// <i> Use the Cortex-M SysTick timer as a time-base for RTX.
+#ifndef OS_SYSTICK
+ #define OS_SYSTICK     1
+#endif
+//
+//   <o>Timer clock value [Hz] <1-1000000000>
+//   <i> Defines the timer clock value.
+//   <i> Default: 12000000  (12MHz)
+#ifndef OS_CLOCK
+ #define OS_CLOCK       48000000
+#endif
+
+//   <o>Timer tick value [us] <1-1000000>
+//   <i> Defines the timer tick value.
+//   <i> Default: 1000  (1ms)
+#ifndef OS_TICK
+ #define OS_TICK        1000
+#endif
+
+// </h>
+
+// <h>System Configuration
+// =======================
+//
+// <e>Round-Robin Thread switching
+// ===============================
+//
+// <i> Enables Round-Robin Thread switching.
+#ifndef OS_ROBIN
+ #define OS_ROBIN       1
+#endif
+
+//   <o>Round-Robin Timeout [ticks] <1-1000>
+//   <i> Defines how long a thread will execute before a thread switch.
+//   <i> Default: 5
+#ifndef OS_ROBINTOUT
+ #define OS_ROBINTOUT   5
+#endif
+
+// </e>
+
+// <e>User Timers
+// ==============
+//   <i> Enables user Timers
+#ifndef OS_TIMERS
+ #define OS_TIMERS      0
+#endif
+
+//   <o>Timer Thread Priority
+//                        <1=> Low
+//     <2=> Below Normal  <3=> Normal  <4=> Above Normal
+//                        <5=> High
+//                        <6=> Realtime (highest)
+//   <i> Defines priority for Timer Thread
+//   <i> Default: High
+#ifndef OS_TIMERPRIO
+ #define OS_TIMERPRIO   5
+#endif
+
+//   <o>Timer Thread stack size [bytes] <64-4096:8><#/4>
+//   <i> Defines stack size for Timer thread.
+//   <i> Default: 200
+#ifndef OS_TIMERSTKSZ
+ #define OS_TIMERSTKSZ  50
+#endif
+
+//   <o>Timer Callback Queue size <1-32>
+//   <i> Number of concurrent active timer callback functions.
+//   <i> Default: 4
+#ifndef OS_TIMERCBQS
+ #define OS_TIMERCBQS   4
+#endif
+
+// </e>
+
+//   <o>ISR FIFO Queue size<4=>   4 entries  <8=>   8 entries
+//                         <12=> 12 entries  <16=> 16 entries
+//                         <24=> 24 entries  <32=> 32 entries
+//                         <48=> 48 entries  <64=> 64 entries
+//                         <96=> 96 entries
+//   <i> ISR functions store requests to this buffer,
+//   <i> when they are called from the interrupt handler.
+//   <i> Default: 16 entries
+#ifndef OS_FIFOSZ
+ #define OS_FIFOSZ      16
+#endif
+
+// </h>
+
+//------------- <<< end of configuration section >>> -----------------------
+
+// Standard library system mutexes
+// ===============================
+//  Define max. number system mutexes that are used to protect
+//  the arm standard runtime library. For microlib they are not used.
+#ifndef OS_MUTEXCNT
+ #define OS_MUTEXCNT    8
+#endif
+
+/*----------------------------------------------------------------------------
+ *      RTX User configuration part END
+ *---------------------------------------------------------------------------*/
+
+#define OS_TRV          ((uint32_t)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1)
+
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+#endif
diff --git a/reform2-lpc-fw/src/boards/reform2/board_reform2.c b/reform2-lpc-fw/src/boards/reform2/board_reform2.c
new file mode 100644
index 0000000000000000000000000000000000000000..70172ceeec58001c4af2f387ed661662f456e434
--- /dev/null
+++ b/reform2-lpc-fw/src/boards/reform2/board_reform2.c
@@ -0,0 +1,663 @@
+#include "projectconfig.h"
+
+#ifdef CFG_BRD_REFORM2
+
+#include <string.h> /* strlen */
+
+#include "boards/board.h"
+#include "core/gpio/gpio.h"
+#include "core/delay/delay.h"
+#include "core/eeprom/eeprom.h"
+#include "core/pmu/pmu.h"
+#include "core/i2c/i2c.h"
+#include "core/ssp1/ssp1.h"
+#include "core/uart/uart.h"
+
+#ifdef CFG_USB
+  #include "core/usb/usbd.h"
+  #ifdef CFG_USB_CDC
+    #include "core/usb/usb_cdc.h"
+  #endif
+#endif
+
+#ifdef CFG_INTERFACE
+  #include "cli/cli.h"
+#endif
+
+#ifdef CFG_PROTOCOL
+  #include "protocol/protocol.h"
+#endif
+
+//#define REF2_DEBUG 0
+
+#define INA260_ADDRESS 0x4e
+#define LTC4162F_ADDRESS 0x68
+#define I2C_READ 1
+
+#define ST_EXPECT_DIGIT_0 0
+#define ST_EXPECT_DIGIT_1 1
+#define ST_EXPECT_DIGIT_2 2
+#define ST_EXPECT_DIGIT_3 3
+#define ST_EXPECT_CMD     4
+#define ST_SYNTAX_ERROR   5
+#define ST_EXPECT_RETURN  6
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+err_t i2c_write8(uint8_t i2c_addr, uint8_t reg, uint8_t value)
+{
+  I2CWriteLength = 3;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = i2c_addr << 1;
+  I2CMasterBuffer[1] = reg;
+  I2CMasterBuffer[2] = value;
+  i2cEngine();
+
+  return ERROR_NONE;
+}
+
+int16_t i2c_read16_le(uint8_t i2c_addr, uint8_t reg)
+{
+  I2CWriteLength = 2;
+  I2CReadLength = 2;
+  I2CMasterBuffer[0] = i2c_addr << 1;
+  I2CMasterBuffer[1] = reg;
+  I2CMasterBuffer[2] = (i2c_addr << 1) | I2C_READ;
+  i2cEngine();
+
+  int16_t value = (I2CSlaveBuffer[0] << 8) | I2CSlaveBuffer[1];
+  return value;
+}
+
+int16_t i2c_read16_be(uint8_t i2c_addr, uint8_t reg)
+{
+  I2CWriteLength = 2;
+  I2CReadLength = 2;
+  I2CMasterBuffer[0] = i2c_addr << 1;
+  I2CMasterBuffer[1] = reg;
+  I2CMasterBuffer[2] = (i2c_addr << 1) | I2C_READ;
+  i2cEngine();
+
+  int16_t value = (I2CSlaveBuffer[1] << 8) | I2CSlaveBuffer[0];
+  return value;
+}
+
+err_t i2c_write16_be(uint8_t i2c_addr, uint8_t reg, uint16_t value)
+{
+  I2CWriteLength = 4;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = i2c_addr << 1;
+  I2CMasterBuffer[1] = reg;
+  I2CMasterBuffer[2] = value&0xff;
+  I2CMasterBuffer[3] = value>>8;
+  i2cEngine();
+
+  return ERROR_NONE;
+}
+
+// see https://www.analog.com/media/en/technical-documentation/data-sheets/680324fa.pdf
+// default = 0x41
+uint8_t calc_pec(uint8_t d, uint8_t pec) {
+  //uint8_t pec = 0x41; // 0100 0001
+
+  for (int i=0; i<8; i++) {
+    uint8_t bit = (d>>7)&1; // pop off upper bit
+    d = d<<1;
+    uint8_t in0 = bit ^ (pec>>7);
+    uint8_t in1 = (pec & 1) ^ in0;
+    uint8_t in2 = ((pec & 2)>>1) ^ in0;
+    pec = (pec<<1)&0xf8;
+    pec |= in2<<2;
+    pec |= in1<<1;
+    pec |= in0;
+  }
+
+  return pec;
+}
+
+
+enum state_t {
+              ST_CHARGE,
+              ST_OVERVOLTED,
+              ST_UNDERVOLTED,
+              ST_MISSING
+};
+
+// charging state machine
+int state = ST_CHARGE;
+int cycles_in_state = 0;
+int charge_current = 1;
+uint32_t cur_second = 0;
+uint32_t last_second = 0;
+
+float ampSecs = 10*3600.0;
+float volts = 0;
+float current = 0;
+unsigned long lastTime = 0;
+char uartBuffer[255] = {0};
+float cells_v[8] = {0,0,0,0,0,0,0,0};
+int num_undervolted_cells = 0;
+int num_overvolted_cells = 0;
+int num_missing_cells = 0;
+uint16_t discharge_bits = 0;
+uint16_t overvoltage_bits = 0;
+uint16_t undervoltage_bits = 0;
+uint16_t missing_bits = 0;
+uint8_t spir[64];
+
+#define OVERVOLTAGE_START_VALUE 3.61
+#define OVERVOLTAGE_STOP_VALUE 3.55
+#define UNDERVOLTAGE_VALUE 2.6
+#define MISSING_VALUE 5
+
+void measure_cell_voltages_and_control_discharge() {
+  // delay is measured in "ticks", which are basically ms?
+
+  // 0x10: WRCFG, write config
+  spir[0] = 0x01;
+  spir[1] = 0xc7;
+
+  spir[2] = 0xe1; // set cdc to 2 = continuous measurement
+  spir[3] = discharge_bits&0xff; // first 8 bits of discharge switches
+  spir[4] = (discharge_bits&0xf00)>>8; // last 4 bits of discharge switches
+  
+  spir[5] = 0x0;
+  spir[6] = 0x0;
+  spir[7] = 0x0;
+
+  if (state == ST_CHARGE) {
+    // we're in normal charge mode, so remove charge current limit
+    LPC_GPIO->SET[1] |= (1 << 25);
+  } else {
+    // we're discharging (balancing), so limit charge current
+    // also don't charge if we have missing cells
+    LPC_GPIO->CLR[1] |= (1 << 25);
+  }
+
+  uint8_t pec = 0x41;
+  for (int i=2; i<=7; i++) {
+    pec = calc_pec(spir[i], pec);
+  }
+  spir[8] = pec;
+  
+  LPC_GPIO->CLR[1] = (1 << 23);
+  ssp1Send(spir, 9);
+  LPC_GPIO->SET[1] = (1 << 23);
+
+  // 0x10: STCVDC, start adc
+  spir[0] = 0x60;
+  spir[1] = 0xe7;
+  LPC_GPIO->CLR[1] = (1 << 23);
+  ssp1Send(spir, 2);
+  LPC_GPIO->SET[1] = (1 << 23);
+
+  delay(50); // FIXME tunable
+
+  // 0x4: RDCV, read all cell voltages
+  spir[0] = 0x4;
+  spir[1] = 0xdc;
+  
+  LPC_GPIO->CLR[1] = (1 << 23);
+  ssp1Send(spir, 2);
+  memset(spir, 0, 32);
+  ssp1Receive(spir, 19);
+  LPC_GPIO->SET[1] = (1 << 23);
+
+  int j=0;
+  for (int i=0; i<8; i+=2) {
+    cells_v[i]   = ((float)((spir[j]|((spir[j+1]&0xf)<<8))-512)) * 1.5 / 1000.0;
+    cells_v[i+1] = ((float)((spir[j+1]&0xf0)>>4|(spir[j+2]<<4))-512) * 1.5 / 1000.0;
+    j+=3;
+
+#ifdef REF2_DEBUG
+    sprintf(uartBuffer,"cell %d: %fV cell %d: %fV\r\n",
+                            i, cells_v[i], i+1, cells_v[i+1]);
+    uartSend((uint8_t *)uartBuffer, strlen(uartBuffer));
+#endif
+  }
+
+  num_missing_cells = 0;
+  num_undervolted_cells = 0;
+  num_overvolted_cells = 0;
+
+  missing_bits = 0;
+  undervoltage_bits = 0;
+  overvoltage_bits = 0;
+  for (int i=0; i<8; i++) {
+    if (cells_v[i] >= MISSING_VALUE || cells_v[i]<0.5) {
+      missing_bits |= (1<<i);
+      num_missing_cells++;
+    }
+    else if ((state == ST_OVERVOLTED && cells_v[i] >= OVERVOLTAGE_STOP_VALUE) ||
+             (state != ST_OVERVOLTED && cells_v[i] >= OVERVOLTAGE_START_VALUE)) {
+      overvoltage_bits |= (1<<i);
+      num_overvolted_cells++;
+    }
+    else if (cells_v[i] < UNDERVOLTAGE_VALUE) {
+      undervoltage_bits |= (1<<i);
+      num_undervolted_cells++;
+    }
+  }
+  
+  // 0x2: RDCFG, read config registers
+  /*spir[0] = 0x2;
+  spir[1] = 0xce;
+  
+  LPC_GPIO->CLR[1] = (1 << 23);
+  delay(2);
+  ssp1Send(spir, 2);
+  memset(spir, 0, 32);
+  ssp1Receive(spir, 7);
+  delay(2);
+  LPC_GPIO->SET[1] = (1 << 23);
+
+  sprintf(uartBuffer,"CFG00 %02x %02x %02x %02x %02x %02x %02x %02x\r\n",
+          spir[0], spir[1], spir[2], spir[3], spir[4], spir[5], spir[6], spir[7]);
+          uartSend((uint8_t *)uartBuffer, strlen(uartBuffer));*/
+}
+
+void discharge_overvolted_cells() {
+  discharge_bits = overvoltage_bits;
+}
+
+void reset_discharge_bits() {
+  discharge_bits = 0;
+}
+
+// using INA260 current monitor, count amp-secs going in and out of battery
+// (battery gauge)
+void measure_and_accumulate_current() {
+  float raw_volts   = (float)i2c_read16_le(INA260_ADDRESS, 0x2);
+  float raw_current = (float)i2c_read16_le(INA260_ADDRESS, 0x1);
+
+  volts   = raw_volts * 0.00125;
+  current = raw_current * 0.001;
+
+  if (current>-0.02 && current<0.02) current = 0; // clamp to zero
+
+  unsigned long thisTime = delayGetSecondsActive();
+  if (lastTime>0 && thisTime>lastTime) {
+    unsigned long secondsPassed = thisTime - lastTime;
+
+    if (secondsPassed >= 1) {
+      lastTime = thisTime;
+      
+      // decrease estimated battery capacity
+      ampSecs -= current*(secondsPassed);
+    }
+  } else {
+    // timer uninitialized or timer wrap
+    lastTime = thisTime;
+  }
+
+#ifdef REF2_DEBUG
+  sprintf(uartBuffer,"\033[H\033[2JINA Ah: %f V: %f A: %f\r\n",ampSecs/3600,volts,current);
+  uartSend((uint8_t *)uartBuffer, strlen(uartBuffer));
+#endif
+}
+
+uint16_t charger_state;
+uint16_t charge_status;
+uint16_t system_status;
+uint16_t limit_alerts;
+uint16_t charger_alerts;
+uint16_t status_alerts;
+float chg_vin;
+float chg_vbat;
+
+void configure_charger(int charge_current) {
+}
+
+void turn_som_power_on(void) {
+  LPC_GPIO->SET[1] = (1 << 16); // 3v3, high = on
+  // FIXME this turns 1v5 off :/
+  LPC_GPIO->SET[0] = (1 << 20); // PCIe, low = on
+  LPC_GPIO->SET[1] = (1 << 15); // 5v, high = on
+  LPC_GPIO->SET[1] = (1 << 19); // 1v2, high = on
+}
+
+void turn_som_power_off(void) {
+  LPC_GPIO->CLR[1] = (1 << 19); // 1v2, high = on
+  LPC_GPIO->CLR[1] = (1 << 15); // 5v, high = on
+  LPC_GPIO->CLR[0] = (1 << 20); // PCIe, low = on
+  LPC_GPIO->CLR[1] = (1 << 16); // 3v3, high = on
+
+  // FIXME experiment: temp. disable charger to reset its timers
+  configure_charger(0);
+}
+
+void brownout_setup(void) {
+  // Set brownout threshold to 2.63-2.71V (highest level)
+  // and enable brownout reset
+  LPC_SYSCON->BODCTRL = 0x3 | (1<<4);
+}
+
+void watchdog_feed(void) {
+  LPC_WWDT->FEED = 0xAA;
+  LPC_WWDT->FEED = 0x55;
+}
+
+#define WWDT_WDMOD_WDEN             ((uint32_t) (1 << 0))
+#define WWDT_WDMOD_WDRESET          ((uint32_t) (1 << 1))
+
+void watchdog_setup(void) {
+  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<15); // WWDT enable
+  
+  LPC_SYSCON->WDTOSCCTRL = 
+    (1<<5) | // FREQSEL 0.6MHz
+    31; // DIVSEL 64 (31+1)*2
+  
+  LPC_SYSCON->PDRUNCFG &= ~(1<<6); // WDTOSC_PD disable
+  
+  LPC_WWDT->CLKSEL = 1; // WDOSC
+
+  LPC_WWDT->TC = 0xffff/5; // timeout counter, ~5 seconds
+
+  LPC_WWDT->MOD = 0;
+  LPC_WWDT->MOD |= WWDT_WDMOD_WDRESET; // enable WDRESET (watchdog resets system)
+  LPC_WWDT->MOD |= WWDT_WDMOD_WDEN; // watchdog enable
+  
+  watchdog_feed();
+}
+
+void boardInit(void)
+{
+  SystemCoreClockUpdate();
+  GPIOInit();
+  delayInit();
+
+  // 5V regulator on/off
+  LPC_GPIO->DIR[1] |= (1 << 15);
+  // 3V3 rail transistor on/off
+  LPC_GPIO->DIR[1] |= (1 << 16);
+  // 1V2 regulator on/off
+  LPC_GPIO->DIR[1] |= (1 << 19);
+  // PCIe 1 power supply transistor
+  LPC_GPIO->DIR[0] |= (1 << 20);  
+  // RNG/SS pin of LTC4020: control/limit charge current
+  LPC_GPIO->DIR[1] |= (1 << 25);
+
+  // start with low charge current
+  LPC_GPIO->CLR[1] |= (1 << 25);
+  
+  turn_som_power_on();
+  
+  uartInit(CFG_UART_BAUDRATE);
+  i2cInit(I2CMASTER);
+  ssp1Init();
+  ssp1ClockSlow();
+  
+  LPC_GPIO->DIR[1] |= (1 << 31);
+  LPC_GPIO->DIR[1] |= (1 << 25);
+
+  // SPI chip select
+  LPC_GPIO->DIR[1] |= (1 << 23);
+  LPC_GPIO->SET[1] =  (1 << 23); // active low
+  
+#ifdef REF2_DEBUG
+  sprintf(uartBuffer, "\r\nMNT Reform 2.0 MCU initialized.\r\n");
+  uartSend((uint8_t*)uartBuffer, strlen(uartBuffer));
+#endif
+}
+
+char remote_cmd = 0;
+uint8_t remote_arg = 0;
+unsigned char cmd_state = ST_EXPECT_DIGIT_0;
+unsigned int cmd_number = 0;
+int cmd_echo = 0;
+
+void handle_commands() {
+  if (!uartRxBufferDataPending()) return;
+
+  char chr = uartRxBufferRead();
+
+  if (cmd_echo) {
+    sprintf(uartBuffer, "%c", chr);
+    uartSend((uint8_t*)uartBuffer, strlen(uartBuffer));
+  }
+
+  // states:
+  // 0-3 digits of optional command argument
+  // 4   command letter expected
+  // 5   syntax error (unexpected character)
+  // 6   command letter entered
+
+  // TODO get cell voltage
+  // TODO get charger state
+  // TODO get charger status / mode
+  
+  if (cmd_state>=ST_EXPECT_DIGIT_0 && cmd_state<=ST_EXPECT_DIGIT_3) {
+    // read number or command
+    if (chr >= '0' && chr <= '9') {
+      cmd_number*=10;
+      cmd_number+=(chr-'0');
+      cmd_state++;
+    } else if ((chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z')) {
+      // command entered instead of digit
+      remote_cmd = chr;
+      cmd_state = ST_EXPECT_RETURN;
+    } else if (chr == '\n' || chr == ' ') {
+      // ignore newlines or spaces
+    } else if (chr == '\r') {
+      sprintf(uartBuffer, "error:syntax\r\n");
+      uartSend((uint8_t*)uartBuffer, strlen(uartBuffer));
+      cmd_state = ST_EXPECT_DIGIT_0;
+      cmd_number = 0;
+    } else {
+      // syntax error
+      cmd_state = ST_SYNTAX_ERROR;
+    }
+  }
+  else if (cmd_state == ST_EXPECT_CMD) {
+    // read command
+    if ((chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z')) {
+      remote_cmd = chr;
+      cmd_state = ST_EXPECT_RETURN;
+    } else {
+      cmd_state = ST_SYNTAX_ERROR;
+    }
+  }
+  else if (cmd_state == ST_SYNTAX_ERROR) {
+    // syntax error
+    if (chr == '\r') {
+      sprintf(uartBuffer, "error:syntax\r\n");
+      uartSend((uint8_t*)uartBuffer, strlen(uartBuffer));
+      cmd_state = ST_EXPECT_DIGIT_0;
+      cmd_number = 0;
+    }
+  }
+  else if (cmd_state == ST_EXPECT_RETURN) {
+    if (chr == '\n' || chr == ' ') {
+      // ignore newlines or spaces
+    }
+    else if (chr == '\r') {
+      if (cmd_echo) {
+        // FIXME
+        sprintf(uartBuffer,"\n");
+        uartSend((uint8_t*)uartBuffer, strlen(uartBuffer));
+      }
+      
+      // execute
+      if (remote_cmd == 'p') {
+        // toggle system 5V power
+        if (cmd_number == 0) {
+          turn_som_power_off();
+          sprintf(uartBuffer,"system: off\r\n");
+          uartSend((uint8_t*)uartBuffer, strlen(uartBuffer));
+        } else {
+          turn_som_power_on();
+          sprintf(uartBuffer,"system: on\r\n");
+          uartSend((uint8_t*)uartBuffer, strlen(uartBuffer));
+        }
+      }
+      else if (remote_cmd == 'a') {
+        // get system current (mA)
+        sprintf(uartBuffer,"%d\r\n",(int)(current*1000.0));
+        uartSend((uint8_t*)uartBuffer, strlen(uartBuffer));
+      }
+      else if (remote_cmd == 'v' && cmd_number>=0 && cmd_number<=7) {
+        // get cell voltage
+        sprintf(uartBuffer,"%d\r\n",(int)(cells_v[cmd_number]*1000.0));
+        uartSend((uint8_t*)uartBuffer, strlen(uartBuffer));
+      }
+      else if (remote_cmd == 'V') {
+        // get system voltage
+        sprintf(uartBuffer,"%d\r\n",(int)(volts*1000.0));
+        uartSend((uint8_t*)uartBuffer, strlen(uartBuffer));
+      }
+      else if (remote_cmd == 's') {
+        // get charger system state
+        if (state == ST_CHARGE) {
+          sprintf(uartBuffer,"idle/charging [%d]\r",cycles_in_state);
+        } else if (state == ST_OVERVOLTED) {
+          sprintf(uartBuffer,"balancing [%d]\r",cycles_in_state);
+        } else if (state == ST_UNDERVOLTED) {
+          sprintf(uartBuffer,"undervolt [%d]\r",cycles_in_state);
+        } else if (state == ST_MISSING) {
+          sprintf(uartBuffer,"cell missing [%d]\r",cycles_in_state);
+        } else if (state == ST_MISSING) {
+          sprintf(uartBuffer,"unknown [%d]\r",cycles_in_state);
+        }
+        uartSend((uint8_t*)uartBuffer, strlen(uartBuffer));
+      }
+      else if (remote_cmd == 'c' && cmd_number>=0 && cmd_number<=7) {
+        // get cell status
+        int n = cmd_number;
+        sprintf(uartBuffer,"%c%c%c%c\r\n",
+                missing_bits      &(1<<n)?'m':'.',
+                undervoltage_bits &(1<<n)?'u':'.',
+                overvoltage_bits  &(1<<n)?'o':'.',
+                discharge_bits    &(1<<n)?'d':'.');
+        
+        uartSend((uint8_t*)uartBuffer, strlen(uartBuffer));
+      }
+      else if (remote_cmd == 'S') {
+        // get charger system cycles in current state
+        sprintf(uartBuffer, "%d\r\n", cycles_in_state);
+        uartSend((uint8_t*)uartBuffer, strlen(uartBuffer));
+      }
+      else if (remote_cmd == 'C') {
+        // set/get battery capacity (mAh)
+        if (cmd_number>0) {
+          ampSecs = ((float)cmd_number)*3.6;
+        }
+        sprintf(uartBuffer,"%d\r\n",(int)(ampSecs/3.6));
+        uartSend((uint8_t*)uartBuffer, strlen(uartBuffer));
+      }
+      else if (remote_cmd == 'e') {
+        // toggle serial echo
+        cmd_echo = cmd_number?1:0;
+      }
+      else {
+        sprintf(uartBuffer, "error:command\r\n");
+        uartSend((uint8_t*)uartBuffer, strlen(uartBuffer));
+      }
+    
+      cmd_state = ST_EXPECT_DIGIT_0;
+      cmd_number = 0;
+    } else {
+      cmd_state = ST_SYNTAX_ERROR;
+    }
+  }
+}
+
+int main(void)
+{
+  boardInit();
+  reset_discharge_bits();
+  
+  state = ST_CHARGE;
+  cycles_in_state = 0;
+
+  last_second = delayGetSecondsActive();
+
+  // WIP, not yet tested
+  //watchdog_setup();
+  //sprintf(uartBuffer, "\r\nwatchdog_setup() completed.\r\n");
+  //uartSend((uint8_t*)uartBuffer, strlen(uartBuffer));
+  
+  while (1)
+  {
+    // algorithm idea:
+    // - check all cell voltages
+    // - charging state: if a cell voltage is higher than nominal, do not charge, enter balancing state
+    //   - option 1: suspend_charger (CONFIG_BITS_REG, 0x14, bit [5])
+    //   - option 2: charge_current_setting (0x1A) to a low level
+    // - charging state: if cell voltages are on average lower than nominal, enter charging state
+    // - balancing state: discharge the cell with highest voltage (enable discharge switch)
+    // - idle state: if one cell voltages is below undervoltage threshold, enter alert state
+    // - alert state: constantly signal undervoltage alert to host. after timeout, switch off 5v rail and 3v3 rail
+
+    // charge current 2: ~0.2A
+
+    //watchdog_feed();
+
+    measure_and_accumulate_current();
+    measure_cell_voltages_and_control_discharge();
+
+    if (state == ST_CHARGE) {
+      //configure_charger(charge_current);
+      
+      if (cycles_in_state > 5) {
+        // some cool-off time
+        if (num_missing_cells > 0) {
+          state = ST_MISSING;
+          cycles_in_state = 0;
+        }
+        else if (num_undervolted_cells > 0) {
+          state = ST_UNDERVOLTED;
+          cycles_in_state = 0;
+        }
+        else if (num_overvolted_cells > 0) {
+          state = ST_OVERVOLTED;
+          cycles_in_state = 0;
+        }
+      }
+    }
+    else if (state == ST_UNDERVOLTED) {
+      // TODO: issue alert -- switch off system if critical
+      reset_discharge_bits();
+      turn_som_power_off();
+
+      if (cycles_in_state > 5) {
+        state = ST_CHARGE;
+        cycles_in_state = 0;
+      }
+    }
+    else if (state == ST_OVERVOLTED) {
+      discharge_overvolted_cells();
+
+      // discharge
+      if (cycles_in_state > 10 && (num_overvolted_cells==0 || num_undervolted_cells>0)) {
+        reset_discharge_bits();
+        state = ST_CHARGE;
+        cycles_in_state = 0;
+      }
+    }
+    else if (state == ST_MISSING) {
+      reset_discharge_bits();
+      
+      if (cycles_in_state > 5) {
+        if (num_missing_cells < 1) {
+          state = ST_CHARGE;
+          cycles_in_state = 0;
+        }
+      }
+    }
+    
+    handle_commands();
+    cur_second = delayGetSecondsActive();
+
+    if (last_second != cur_second) {
+      if (cur_second-last_second<10) {
+        // prevent rollovers
+        cycles_in_state += cur_second-last_second;
+      }
+      last_second = cur_second;
+    }
+  }
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/boards/reform2/board_reform2.h b/reform2-lpc-fw/src/boards/reform2/board_reform2.h
new file mode 100644
index 0000000000000000000000000000000000000000..a85b3e85facc9dd484c68503568d472b48100da9
--- /dev/null
+++ b/reform2-lpc-fw/src/boards/reform2/board_reform2.h
@@ -0,0 +1,659 @@
+/**************************************************************************/
+/*!
+    @file     board_lpcxpresso1347.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Board file for the LPC1347 LPCXpresso board from NXP
+    @ingroup  Boards
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012 K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __BOARD_REFORM2_H__
+#define __BOARD_REFORM2_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sysdefs.h"
+
+/*=========================================================================
+    MCU SELECTION
+
+    Include one of the following definitions depending on if you are
+    using the LPC11U37 or LPC1347.  They're generally interchangeable, but
+    the LPC11Uxx and LPC13xx CMSIS implementations have some differences
+    in naming convention, and occasionally a feature is only available on
+    the M3 (DWT for example).  Selecting the appropriate MCU allows
+    the right code to be included when differences between the CMSIS
+    implementations are present.
+
+    -----------------------------------------------------------------------*/
+    #define CFG_MCU_LPC11U24FBD48_401
+    // #define CFG_MCU_LPC11U37FBD48_401
+    // #define CFG_MCU_LPC1347FBD48
+    // #define CFG_MCU_LPC1347FHN33
+
+    /* Basic error checking */
+    #if !defined CFG_MCU_LPC1347FBD48 && \
+        !defined CFG_MCU_LPC11U37FBD48_401 && \
+        !defined CFG_MCU_LPC11U24FBD48_401 && \
+        !defined CFG_MCU_LPC1347FHN33
+      #error "An MCU must be selected in projectconfig.h (Ex. CFG_MCU_LPC11U37FBD48_401, CFG_MCU_LPC1347FBD48, etc.)"
+    #endif
+
+    /* Set flag to indicate which CMSIS library to use */
+    #if (defined CFG_MCU_LPC1347FBD48 || defined CFG_MCU_LPC1347FHN33)
+      #define CFG_MCU_FAMILY_LPC13UXX
+    #elif (defined CFG_MCU_LPC11U24FBD48_401 || defined CFG_MCU_LPC11U37FBD48_401)
+      #define CFG_MCU_FAMILY_LPC11UXX
+    #endif
+
+    /* Include the correct MCU header file */
+    #if defined CFG_MCU_FAMILY_LPC13UXX
+      #include "LPC13Uxx.h"
+    #endif
+    #if defined CFG_MCU_FAMILY_LPC11UXX
+      #include "LPC11Uxx.h"
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    FIRMWARE VERSION SETTINGS
+    -----------------------------------------------------------------------*/
+    #define CFG_FIRMWARE_VERSION_MAJOR      (0)
+    #define CFG_FIRMWARE_VERSION_MINOR      (0)
+    #define CFG_FIRMWARE_VERSION_REVISION   (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PIN USAGE
+    -----------------------------------------------------------------------
+    This table tries to give an indication of which GPIO pins and
+    peripherals are used by the available drivers and SW examples.  Only
+    dedicated GPIO pins available on the LPC1347 Reference Board are shown
+    below.  Any unused peripheral blocks like I2C, SSP, ADC, etc., can
+    also be used as GPIO if they are available.
+
+                PORT 0
+                =========================================================
+                0 1 2 3 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
+
+    HX8340B     . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    HX8347G     . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    CHIBI       . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    SSD1306 I2C . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    FAT32/MMC   . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  X  .  .
+    PN532 I2C   . . . . . . . .  .  .  .  .  .  .  X  X  .  .  .  .  .  .
+    PCF2129A    . . . . . . . .  .  .  .  .  .  .  X  X  .  .  .  .  .  .
+
+                PORT 1
+                ===========================================================================
+                0 1 2 3 4 5 7 8 10 11 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 31
+                + + + + + + + +  +  +              +  +                                   -
+
+    HX8340B     . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  X  X  X  X  X  .
+    HX8347G     . . . . . . . .  .  .  X  X  X  X  .  .  X  X  X  X  X  X  X  X  X  X  .  .
+    CHIBI       . . . . . . . .  .  .  X  X  X  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    SSD1306 I2C . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    FAT32/MMC   . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  X  X  .  .  .  .  .  .
+    PN532 I2C   . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    PCF2129A    . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+
+                TIMERS                   SSP   ADC               UART
+                ======================   ===   ===============   ====
+                16B0  16B1  32B0  32B1   0 1   0 1 2 3 4 5 6 7   0
+
+    HX8340B     .      .    .     .      . .   . . . . . . . .   .
+    HX8347G     .      .    .     .      . .   . . . . . . . .   .
+    CHIBI       .      .    .     .      X .   . . . . . . . .   .
+    SSD1306 I2C .      .    .     .      . .   . . . . . . . .   .
+    FAT32/MMC   .      .    .     .      . X   . . . . . . . .   .
+
+    [+]   Only available on QFP64 package
+    [-]   Only available on QFP48 package
+
+  =========================================================================*/
+
+
+/*=========================================================================
+    GPIO INTERRUPTS
+    -----------------------------------------------------------------------
+    This table shows where GPIO interrupts are mapped in this project
+    (Note that the LPC11U and LPC13U use different names for the
+    IRQ Handlers in the standard headers)
+
+    Interrupt                                     Location
+    ------------------------------------------    -------------------------
+    PIN_INT0_IRQHandler - FLEX_INT0_IRQHandler    chb_drvr.c
+    PIN_INT1_IRQHandler - FLEX_INT1_IRQHandler    pcf2129.c
+    PIN_INT2_IRQHandler - FLEX_INT2_IRQHandler    spi.c (cc3000)
+    PIN_INT3_IRQHandler - FLEX_INT3_IRQHandler
+    PIN_INT4_IRQHandler - FLEX_INT4_IRQHandler
+    PIN_INT5_IRQHandler - FLEX_INT5_IRQHandler
+    PIN_INT6_IRQHandler - FLEX_INT6_IRQHandler
+    PIN_INT7_IRQHandler - FLEX_INT7_IRQHandler
+    GINT0_IRQHandler
+    GINT0_IRQHandler
+    -----------------------------------------------------------------------*/
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SUPPORTED PERIPHERALS
+    -----------------------------------------------------------------------
+    Because all ISRs are referenced in the startup code, GCC typically
+    won't optimise out the ISR functions during compilation even if the
+    ISRs will never be entered, resulting in larger binaries than required
+    (for example if no I2C sensors are used, be sure to disable I2C support
+    since the I2C ISR is quite large).
+
+    Use the defines below to include or exclude support for specific
+    peripherals.
+
+    NOTE: GPIO ISRs are handled separately in GPIO INTERRUPTS below
+    -----------------------------------------------------------------------*/
+    #define CFG_ENABLE_I2C
+    #define CFG_ENABLE_UART
+  //#define CFG_ENABLE_USB
+    #define CFG_ENABLE_TIMER32
+/*=========================================================================*/
+
+/*=========================================================================
+    EEPROM
+    -----------------------------------------------------------------------
+    EEPROM is used to persist certain user modifiable values to make
+    sure that these changes remain in effect after a reset or hard
+    power-down.  The addresses in EEPROM for these various system
+    settings/values are defined below.  The first 256 bytes of EEPROM
+    are reserved for this (0x0000..0x00FF).
+
+    CFG_EEPROM_SIZE           The number of bytes available on the EEPROM
+    CFG_EEPROM_RESERVED       The last byte of reserved EEPROM memory
+
+          EEPROM Address (0x0000..0x00FF)
+          ===============================
+          0 1 2 3 4 5 6 7 8 9 A B C D E F
+    000x  x x . . x x x x x x x x . . . .   Chibi
+    001x  . . . . . . . . . . . . . . . .
+    002x  . . . . . . . . . . . . . . . .
+    003x  . . . . . . . . . . . . . . . .
+    004x  . . . . . . . . . . . . . . . .
+    005x  . . . . . . . . . . . . . . . .
+    006x  . . . . . . . . . . . . . . . .
+    007x  . . . . . . . . . . . . . . . .
+    008x  . . . . . . . . . . . . . . . .
+    009x  . . . . . . . . . . . . . . . .
+    00Ax  . . . . . . . . . . . . . . . .
+    00Bx  . . . . . . . . . . . . . . . .
+    00Cx  . . . . . . . . . . . . . . . .
+    00Dx  . . . . . . . . . . . . . . . .
+    00Ex  . . . . . . . . . . . . . . . .
+    00Fx  . . . . . . . . . . . . . . . .
+
+    -----------------------------------------------------------------------*/
+    #define CFG_EEPROM_SIZE                   (4032)
+    #define CFG_EEPROM_RESERVED               (0x00FF)              // Protect first 256 bytes of memory
+    #define CFG_EEPROM_CHIBI_NODEADDR         (uint16_t)(0x0000)    // 2
+    #define CFG_EEPROM_CHIBI_IEEEADDR         (uint16_t)(0x0004)    // 8
+/*=========================================================================*/
+
+
+/*=========================================================================
+    ON-BOARD LED
+    -----------------------------------------------------------------------
+
+    CFG_LED_PORT              The port for the on board LED
+    CFG_LED_PIN               The pin for the on board LED
+    CFG_LED_ON                The pin state to turn the LED on (0 = low, 1 = high)
+    CFG_LED_OFF               The pin state to turn the LED off (0 = low, 1 = high)
+
+    -----------------------------------------------------------------------*/
+    #define CFG_LED_PORT                  (0)
+    #define CFG_LED_PIN                   (7)
+    #define CFG_LED_ON                    (1)
+    #define CFG_LED_OFF                   (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    ADC
+    -----------------------------------------------------------------------
+
+    CFG_ADC_MODE_LOWPOWER     If set to 1, this will configure the ADC
+                              for low-power operation (LPC1347 only)
+    CFG_ADC_MODE_10BIT        If set to 1, this will configure the ADC
+                              for 10-bit mode (LPC1347 only)
+
+    -----------------------------------------------------------------------*/
+    #define CFG_ADC_MODE_LOWPOWER       (0)
+    #define CFG_ADC_MODE_10BIT          (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    UART
+    -----------------------------------------------------------------------
+
+    CFG_UART_BAUDRATE         The default UART speed.  This value is used
+                              when initialising UART, and should be a
+                              standard value like 57600, 9600, etc.
+                              NOTE: This value may be overridden if
+                              another value is stored in EEPROM!
+    CFG_UART_BUFSIZE          The length in bytes of the UART RX FIFO. This
+                              will determine the maximum number of received
+                              characters to store in memory.
+
+    -----------------------------------------------------------------------*/
+    #define CFG_UART_BAUDRATE           (57600)
+    #define CFG_UART_BUFSIZE            (256)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SPI
+    -----------------------------------------------------------------------
+
+    CFG_SSP_SCK0_LOCATION     The location of the SCK pin for SSP0
+    CFG_SSP_MISO1_LOCATION    The location of the MISO1 pin for SSP1
+    CFG_SSP_MOSI1_LOCATION    The location of the MOSI1 pin for SSP1
+    CFG_SSP_SCK1_LOCATION     The location of the SCK pin for SSP1
+
+    -----------------------------------------------------------------------*/
+    #define CFG_SSP_SCK0_0_6            (6)     // Used by USBConnect
+    #define CFG_SSP_SCK0_0_10           (10)    // Used by SWD
+    #define CFG_SSP_SCK0_1_29           (29)
+
+    #define CFG_SSP_MISO1_0_22          (22)
+    #define CFG_SSP_MISO1_1_21          (21)
+    #define CFG_SSP_MOSI1_0_21          (21)
+    #define CFG_SSP_MOSI1_1_22          (22)
+    #define CFG_SSP_SCK1_1_15           (15)
+    #define CFG_SSP_SCK1_1_20           (20)
+
+    // Select the appropriate pin locations here
+    #define CFG_SSP_SCK0_LOCATION       (CFG_SSP_SCK0_1_29)
+    #define CFG_SSP_MISO1_LOCATION      (CFG_SSP_MISO1_1_21)
+    #define CFG_SSP_MOSI1_LOCATION      (CFG_SSP_MOSI1_1_22)
+    #define CFG_SSP_SCK1_LOCATION       (CFG_SSP_SCK1_1_20)
+
+    // Set the phase and polarity for SSP0 and SSP1
+    #define CFG_SSP_CPOL0               (0)
+    #define CFG_SSP_CPHA0               (1)
+    #define CFG_SSP_CPOL1               (1)
+    #define CFG_SSP_CPHA1               (1)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PRINTF REDIRECTION
+    -----------------------------------------------------------------------
+
+    CFG_PRINTF_MAXSTRINGSIZE  Maximum size of string buffer for printf
+    CFG_PRINTF_UART           Will cause all printf statements to be
+                              redirected to UART
+    CFG_PRINTF_USBCDC         Will cause all printf statements to be
+                              redirect to USB Serial
+    CFG_PRINTF_NEWLINE        This is typically "\r\n" for Windows or
+                              "\n" for *nix
+
+    Note: If no printf redirection definitions are present, all printf
+    output will be ignored.
+    -----------------------------------------------------------------------*/
+    #define CFG_PRINTF_MAXSTRINGSIZE    (255)
+
+    #define CFG_PRINTF_UART
+    //#define CFG_PRINTF_USBCDC
+    // #define CFG_PRINTF_DEBUG
+
+    #define CFG_PRINTF_NEWLINE          "\n"
+    
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SIMPLE BINARY PROTOCOL
+    -----------------------------------------------------------------------
+
+    CFG_PROTOCOL             If this field is defined the binary command
+                              parser will be included
+    -----------------------------------------------------------------------*/
+  //#define CFG_PROTOCOL
+
+  //#define CFG_PROTOCOL_VIA_HID
+    // #define CFG_PROTOCOL_VIA_BULK
+
+    #if defined(CFG_PROTOCOL) && !defined(CFG_PROTOCOL_VIA_HID) && !defined(CFG_PROTOCOL_VIA_BULK)
+        #error CFG_PROTOCOL must be enabled with either CFG_PROTOCOL_VIA_HID or CFG_PROTOCOL_VIA_BULK
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    TFT LCD
+    -----------------------------------------------------------------------
+
+    CFG_TFTLCD                  If defined, this will cause drivers for
+                                a pre-determined LCD screen to be included
+                                during build.  Only one LCD driver can be
+                                included during the build process (for ex.
+                                'drivers/displays/hw/ILI9325.c')
+    CFG_TFTLCD_INCLUDESMALLFONTS If set to 1, smallfont support will be
+                                included for 3x6, 5x8, 7x8 and 8x8 fonts.
+                                This should only be enabled if these small
+                                fonts are required since there is already
+                                support for larger fonts generated with
+                                Dot Factory
+                                http://www.pavius.net/downloads/tools/53-the-dot-factory
+    CFG_TFTLCD_USEAAFONTS       If set to a non-zero value, anti-aliased
+                                fonts will be used instead of regular 1-bit
+                                font.  These result in much higher-
+                                quality text, but the fonts are 2 or 4
+                                times larger than plain bitmap fonts and
+                                take a bit more rendering time to display.
+    CFG_TFTLCD_TS_DEFAULTTHRESHOLD  Default minimum threshold to trigger a
+                                touch event with the touch screen (and exit
+                                from 'tsWaitForEvent' in touchscreen.c).
+                                Should be an 8-bit value somewhere between
+                                8 and 75 in normal circumstances.  This is
+                                the default value and may be overriden by
+                                a value stored in EEPROM.
+    CFG_TFTLCD_TS_KEYPADDELAY   The delay in milliseconds between key
+                                presses in dialogue boxes
+    ----------------------------------------------------------------------*/
+    // #define CFG_TFTLCD
+    #define CFG_TFTLCD_INCLUDESMALLFONTS   (1)
+    #define CFG_TFTLCD_USEAAFONTS          (0)
+    #define CFG_TFTLCD_TS_DEFAULTTHRESHOLD (50)
+    #define CFG_TFTLCD_TS_KEYPADDELAY      (100)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    MICRO-SD CARD
+    -----------------------------------------------------------------------
+
+    CFG_SDCARD                If this field is defined SD Card and FAT32
+                              file system support will be included
+    CFG_SDCARD_SPIPORT        SSP Port used for the SD card (0 or 1)
+    CFG_SDCARD_READONLY       If this is set to 1, all commands to
+                              write to the SD card will be removed
+                              saving some flash space.
+    CFG_SDCARD_CDPORT         The card detect port number
+    CFG_SDCARD_CDPIN          The card detect pin number
+
+    NOTE:                     All config settings for FAT32 are defined
+                              in ffconf.h
+    -----------------------------------------------------------------------*/
+    // #define CFG_SDCARD
+    #define CFG_SDCARD_READONLY         (1)   // Must be 0 or 1
+    #define CFG_SDCARD_SPIPORT          (0)
+    #define CFG_SDCARD_SSELPORT         (0)
+    #define CFG_SDCARD_SSELPIN          (0)
+    #define CFG_SDCARD_CDPORT           (0)
+    #define CFG_SDCARD_CDPIN            (0)
+    #define CFG_SDCARD_ENBLPORT         (0)
+    #define CFG_SDCARD_ENBLPIN          (0)
+
+    #ifdef CFG_SDCARD
+      #if !((CFG_SDCARD_READONLY == 0) || (CFG_SDCARD_READONLY == 1))
+        #error "Invalid value for CFG_SDCARD_READONLY"
+      #endif
+      #if !((CFG_SDCARD_SPIPORT == 0) || (CFG_SDCARD_SPIPORT == 1))
+        #error "Invalid SPI port for CFG_SDCARD_SPIPORT"
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    CHIBI WIRELESS STACK
+    -----------------------------------------------------------------------
+
+    CFG_CHIBI                   If defined, the CHIBI wireless stack will be
+                                included during build.  Requires external HW.
+    CFG_CHIBI_MODE              The mode to use when receiving and transmitting
+                                wireless data.  See chb_drvr.h for possible values
+    CFG_CHIBI_POWER             The power level to use when transmitting.  See
+                                chb_drvr.h for possible values
+    CFG_CHIBI_CHANNEL           802.15.4 Channel (0 = 868MHz, 1-10 = 915MHz)
+    CFG_CHIBI_PANID             16-bit PAN Identifier (ex.0x1234)
+    CFG_CHIBI_PROMISCUOUS       Set to 1 to enabled promiscuous mode or
+                                0 to disable it.  If promiscuous mode is
+                                enabled be sure to set CFG_CHIBI_BUFFERSIZE
+                                to an appropriately large value (ex. 1024)
+    CFG_CHIBI_BUFFERSIZE        The size of the message buffer in bytes
+    -----------------------------------------------------------------------*/
+    // #define CFG_CHIBI
+    #define CFG_CHIBI_MODE              (0)                 // OQPSK_868MHZ
+    #define CFG_CHIBI_POWER             (0xE9)              // CHB_PWR_EU2_3DBM
+    #define CFG_CHIBI_CHANNEL           (0)                 // 868-868.6 MHz
+    #define CFG_CHIBI_PANID             (0x1234)
+    #define CFG_CHIBI_PROMISCUOUS       (0)
+    #define CFG_CHIBI_BUFFERSIZE        (256)
+
+    // Pin config settings
+    #define CFG_CHIBI_SPIPORT           (0)  // Must be 0 or 1
+    #define CFG_CHIBI_SSPORT            (0)
+    #define CFG_CHIBI_SSPIN             (0)
+    #define CFG_CHIBI_EINTPORT          (0)
+    #define CFG_CHIBI_EINTPIN           (0)
+    #define CFG_CHIBI_RSTPORT           (0)
+    #define CFG_CHIBI_RSTPIN            (0)
+    #define CFG_CHIBI_SLPTRPORT         (0)
+    #define CFG_CHIBI_SLPTRPIN          (0)
+    #define CFG_CHIBI_CC1190_HGM_PORT   (0)   // Not used
+    #define CFG_CHIBI_CC1190_HGM_PIN    (0)   // Not used
+
+    #ifdef CFG_CHIBI
+      #if !((CFG_CHIBI_SPIPORT == 0) || (CFG_CHIBI_SPIPORT == 1))
+        #error "Invalid SPI port for CFG_CHIBI_SPIPORT"
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    CC3000 WIFI MODULES
+    -----------------------------------------------------------------------
+
+    CFG_CC3000                     If defined, CC3000 support will be
+                                   included during build.  Requires
+                                   external HW
+    -----------------------------------------------------------------------*/
+    // #define CFG_CC3000
+    #define CFG_CC3000_SPI_PORT         (0)
+    #define CFG_CC3000_EN_PORT          (0)
+    #define CFG_CC3000_EN_PIN           (14)
+    #define CFG_CC3000_IRQ_PORT         (0)
+    #define CFG_CC3000_IRQ_PIN          (16)
+    #define CFG_CC3000_CS_PORT          (0)
+    #define CFG_CC3000_CS_PIN           (17)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PN532/NFC STACK
+    -----------------------------------------------------------------------
+
+    CFG_PN532                      If defined, the PN532/NFC stack will be
+                                   included during build.  Requires
+                                   external HW
+    CFG_PN532_MEM_POOL_SIZE_BYTES  Size of the dynamic memory pool in bytes
+                                   (used by pn532/mem_allocator/ when
+                                   working with NDEF messages)
+    -----------------------------------------------------------------------*/
+    // #define CFG_PN532
+    #define CFG_PN532_RSTPD_PORT                      (0)
+    #define CFG_PN532_RSTPD_PIN                       (16)
+    #define CFG_PN532_I2C_IRQPORT                     (0)
+    #define CFG_PN532_I2C_IRQPIN                      (17)
+    #define CFG_PN532_MEM_POOL_SIZE_BYTES             (512)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    RTC SUPPORT
+    -----------------------------------------------------------------------
+
+    CFG_RTC                     If defined, RTC support will be included.
+                                Requires external HW.
+    -----------------------------------------------------------------------*/
+    // #define CFG_RTC
+
+    #if defined(CFG_RTC) && !defined(CFG_ENABLE_I2C)
+      #error "CFG_ENABLE_I2C must be defined with CFG_RTC"
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    STEPPER MOTOR SUPPORT
+    -----------------------------------------------------------------------
+
+    CFG_STEPPER                 If defined, basic stepper motor support
+                                will be included.  Requires external HW.
+    -----------------------------------------------------------------------*/
+    // #define CFG_STEPPER
+    #define CFG_STEPPER_TIMER32                       (0)
+    #define CFG_STEPPER_IN1_PORT                      (0)
+    #define CFG_STEPPER_IN1_PIN                       (8)
+    #define CFG_STEPPER_IN2_PORT                      (0)
+    #define CFG_STEPPER_IN2_PIN                       (9)
+    #define CFG_STEPPER_IN3_PORT                      (0)
+    #define CFG_STEPPER_IN3_PIN                       (14)
+    #define CFG_STEPPER_IN4_PORT                      (0)
+    #define CFG_STEPPER_IN4_PIN                       (13)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    USB
+
+    CFG_USB_STRING_MANUFACTURER Manufacturer name that will appear in the
+                                device descriptor during USB enumeration
+    CFG_USB_STRING_PRODUCT      Product name that will appear in the
+                                device descriptor during USB enumeration
+    CFG_USB_VENDORID            16-bit USB vendor ID
+    USB_PRODUCT_ID              Define this to set a custom product ID
+                                if you do not wish to use the 'auto'
+                                product ID feature
+    CFG_CDC                     Enable USB CDC support
+    CFG_USB_HID_KEYBOARD        Enable USB HID keyboard emulation
+    CFG_USB_HID_MOUSE           Enable USB HID mouse emulation for a five
+                                button 'Windows' mouse with scroll wheels
+    CFG_USB_HID_GENERIC         Enable USB HID Generic support for custom
+                                in and out reports, with report size set
+                                via CFG_USB_HID_GENERIC_REPORT_SIZE
+    CFG_USB_MSC                 Enable USB Mass Storage support, pointing
+                                to the SD card reader (requires mmc.c from
+                                the FATFS drivers, but doesn't use FATFS)
+
+
+    You can combine more than one USB class below and they will be
+    automatically combined in a USB composite device within the limit of
+    available USB endpoints.  The USB Product ID is calculated automatically
+    based on the combination of classes defined below.
+
+    NOTE: Windows requires the .inf file in '/core/usb' for CDC support
+    -----------------------------------------------------------------------*/
+    #ifdef CFG_ENABLE_USB
+      #define CFG_USB_STRING_MANUFACTURER       "microBuilder.eu"
+      #define CFG_USB_STRING_PRODUCT            "LPC1347 LPCXpresso"
+      #define CFG_USB_VENDORID                  (0x1FC9)
+
+      #define CFG_USB_CDC
+
+      // #define CFG_USB_HID_KEYBOARD
+      // #define CFG_USB_HID_MOUSE
+      #define CFG_USB_HID_GENERIC
+      #define CFG_USB_HID_GENERIC_REPORT_SIZE (64)
+
+      // #define CFG_USB_MSC
+
+      // #define CFG_USB_CUSTOM_CLASS
+
+      #if (defined(CFG_USB_CDC)       || defined(CFG_USB_HID_KEYBOARD) || \
+           defined(CFG_USB_HID_MOUSE) || defined(CFG_USB_HID_GENERIC)  || \
+           defined(CFG_USB_MSC)       || defined(CFG_USB_CUSTOM_CLASS))
+        #define CFG_USB
+        #if defined(CFG_USB_HID_KEYBOARD) || defined(CFG_USB_HID_MOUSE) || defined(CFG_USB_HID_GENERIC)
+          #define CFG_USB_HID
+          #if defined(CFG_USB_HID_GENERIC) && (CFG_USB_HID_GENERIC_REPORT_SIZE > 64)
+            #error "CFG_USB_HID_GENERIC_REPORT_SIZE exceeds the maximum value of 64 bytes (based on USB specs 2.0 for 'Full Speed Interrupt Endpoint Size')"
+          #endif
+        #endif
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    CONFIG FILE VALIDATION
+
+    Basic error checking to make sure that incompatible defines are not
+    enabled at the same time, etc.
+
+    -----------------------------------------------------------------------*/
+    #if defined(CFG_INTERFACE) && !( defined CFG_PRINTF_UART || defined CFG_PRINTF_USBCDC || defined CFG_PRINTF_DEBUG)
+      #error "At least one CFG_PRINTF target must be defined with CFG_INTERFACE"
+    #endif
+
+    #if defined(CFG_PRINTF_UART) && !defined(CFG_ENABLE_UART)
+      #error "CFG_ENABLE_UART must be enabled with CFG_PRINTF_UART"
+    #endif
+
+    #if defined(CFG_PRINTF_USBCDC) && !defined(CFG_USB_CDC)
+      #error "CFG_USB_CDC must be defined with CFG_PRINTF_USBCDC"
+    #endif
+
+    #if defined(CFG_USB_MSC) && !defined(CFG_SDCARD)
+      #error "CFG_USB_MSC must be defined with CFG_SDCARD"
+    #endif
+
+    #if defined(CFG_PROTOCOL)
+      #if defined(CFG_PROTOCOL_VIA_HID) && !defined(CFG_USB_HID_GENERIC)
+        #error "CFG_PROTOCOL_VIA_HID requires CFG_USB_HID_GENERIC"
+      #endif
+
+      #if defined(CFG_PROTOCOL_VIA_BULK) && !defined(CFG_USB_CUSTOM_CLASS)
+        #error "CFG_PROTOCOL_VIA_BULK requires CFG_USB_CUSTOM_CLASS to be defined"
+      #endif
+    #endif
+/*=========================================================================*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/boards/rf1ghznode/board_rf1ghznode.c b/reform2-lpc-fw/src/boards/rf1ghznode/board_rf1ghznode.c
new file mode 100644
index 0000000000000000000000000000000000000000..bdf4c0d1a8c5972c751ddeca15bc2ee30a25b4ea
--- /dev/null
+++ b/reform2-lpc-fw/src/boards/rf1ghznode/board_rf1ghznode.c
@@ -0,0 +1,711 @@
+/**************************************************************************/
+/*!
+    @file     board_rf1ghznode.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section DESCRIPTION
+
+    Common, board-specific files for the AT86RF2xx wireless boards
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#if defined CFG_BRD_RF1GHZNODE
+
+#include "cmsis_os.h"
+#include "boards/board.h"
+#include "core/gpio/gpio.h"
+#include "core/delay/delay.h"
+#include "core/eeprom/eeprom.h"
+#include "core/pmu/pmu.h"
+#include "core/adc/adc.h"
+
+#ifdef CFG_CHIBI
+  #include "drivers/rf/802.15.4/chibi/chb.h"
+  #include "drivers/rf/802.15.4/chibi/chb_drvr.h"
+  #include "drivers/rf/802.15.4/chibi/messages.h"
+  static chb_rx_data_t rx_data;
+#endif
+
+#ifdef CFG_USB
+  #include "core/usb/usbd.h"
+  #ifdef CFG_USB_CDC
+    #include "core/usb/usb_cdc.h"
+  #endif
+#endif
+
+#ifdef CFG_TFTLCD
+  #include "drivers/displays/graphic/lcd.h"
+#endif
+
+#ifdef CFG_SDCARD
+  #include "drivers/storage/fatfs/diskio.h"
+  #include "drivers/storage/fatfs/ff.h"
+#endif
+
+#ifdef CFG_INTERFACE
+  #include "cli/cli.h"
+#endif
+
+#ifdef CFG_PROTOCOL
+  #include "protocol/protocol.h"
+#endif
+
+#ifdef CFG_ENABLE_UART
+  #include "core/uart/uart.h"
+#endif
+
+#ifdef CFG_RTC
+  #include "drivers/rtc/pcf2129/pcf2129.h"
+#endif
+
+#include "drivers/sensors/accelerometers/lsm303accel.h"
+
+#define PINS_VREGVSEL_PORT      (1)
+#define PINS_VREGVSEL_PIN       (16)
+#define PINS_VINADC_EN_PORT     (0)
+#define PINS_VINADC_EN_PIN      (20)
+#define PINS_VINADC_INPUT_PORT  (0)
+#define PINS_VINADC_INPUT_PIN   (11)
+#define PINS_I2C_PULLUPS_PORT   (0)
+#define PINS_I2C_PULLUPS_PIN    (23)
+
+/* VIN resistor divider multiplier is 3.12766 */
+#define RF1GHZNODE_VINADC_MULTIPLIER_FIXED10K (31277)
+
+#ifdef CFG_CMSIS_RTOS
+  #include "RTX_CM_lib.h"
+#endif
+
+#ifdef CFG_SDCARD
+/**************************************************************************/
+/*!
+    Handles timestamp requests for SD cards (adjust depending on if you
+    want to use the RTC, or just return 0, etc.)
+*/
+/**************************************************************************/
+DWORD get_fattime ()
+{
+  DWORD tmr = 0;
+
+  // tmr =  (((DWORD)rtcYear - 80) << 25)
+  //      | ((DWORD)rtcMon << 21)
+  //      | ((DWORD)rtcMday << 16)
+  //      | (WORD)(rtcHour << 11)
+  //      | (WORD)(rtcMin << 5)
+  //      | (WORD)(rtcSec >> 1);
+
+  return tmr;
+}
+#endif
+
+#ifdef CFG_CHIBI
+/**************************************************************************/
+/*!
+    Converts the ED (Energy Detection) value to dBm using the following
+    formula: dBm = RSSI_BASE_VAL + 1.03 * ED
+
+    For more information see section 6.5 of the AT86RF212 datasheet
+*/
+/**************************************************************************/
+int edToDBM(uint32_t ed)
+{
+  #if CFG_CHIBI_MODE == 0 || CFG_CHIBI_MODE == 1 || CFG_CHIBI_MODE == 2
+    // Calculate for OQPSK (RSSI Base Value = -100)
+    int dbm = (103 * ed - 10000);
+  #else
+    // Calculate for BPSK (RSSI Base Value = -98)
+    int dbm = (103 * ed - 9800);
+  #endif
+
+  return dbm / 100;
+}
+
+/**************************************************************************/
+/*!
+    Sends a test message over the air
+*/
+/**************************************************************************/
+void sendMessage(void)
+{
+  uint8_t msgbuf[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+  if(msgSend(0xFFFF, MSG_MESSAGETYPE_NONE, msgbuf, 10))
+  {
+    printf("Message TX failure%s", CFG_PRINTF_NEWLINE);
+  }
+}
+
+/**************************************************************************/
+/*!
+    Sends a test message over the air
+*/
+/**************************************************************************/
+void sendSensorEvent(void)
+{
+  err_t error;
+  sensors_event_t event;
+
+  // Change this to whatever sensor you want/have!
+  error = lsm303accelGetSensorEvent(&event);
+
+  if (!error)
+  {
+    // Serialize the data before transmitting
+    uint8_t msgbuf[sizeof(event)];
+    sensorsSerializeSensorsEvent(msgbuf, &event);
+
+    // Broadcast the sensor event data over the air
+    if(msgSend(0xFFFF, MSG_MESSAGETYPE_SENSOREVENT, msgbuf, sizeof(event)))
+    {
+      printf("Message TX failure%s", CFG_PRINTF_NEWLINE);
+    }
+  }
+}
+
+/**************************************************************************/
+/*!
+    Checks if any incmoing messages were received over the air
+*/
+/**************************************************************************/
+void checkForMessages(void)
+{
+  chb_pcb_t *pcb = chb_get_pcb();
+
+  while (pcb->data_rcv)
+  {
+    // Enable LED to indicate message reception
+    boardLED(CFG_LED_ON);
+    // get the length of the data
+    rx_data.len = chb_read(&rx_data);
+    // make sure the length is nonzero
+    if (rx_data.len)
+    {
+      int dbm = edToDBM(pcb->ed);
+      // printf("Message received from node %02X: %s, len=%d, dBm=%d.%s", rx_data.src_addr, rx_data.data, rx_data.len, dbm, CFG_PRINTF_NEWLINE);
+      printf("Message received from node 0x%04X (len=%d, dBm=%d):%s", rx_data.src_addr, rx_data.len, dbm, CFG_PRINTF_NEWLINE);
+      printf("  Message ID:   0x%04X%s", *(uint16_t*)&rx_data.data[0], CFG_PRINTF_NEWLINE);
+      printf("  Message Type: 0x%02X%s", *(uint8_t*)&rx_data.data[2], CFG_PRINTF_NEWLINE);
+      printf("  Timestamp:    %u%s", *(unsigned int*)&rx_data.data[3], CFG_PRINTF_NEWLINE);
+      printf("  Payload:      %u bytes%s", *(uint8_t*)&rx_data.data[8], CFG_PRINTF_NEWLINE);
+      if (rx_data.data[8])
+      {
+        uint8_t i;
+        printf("%s", CFG_PRINTF_NEWLINE);
+        for (i = 0; i < rx_data.data[8]; i++)
+        {
+          printf("0x%02X ", *(uint8_t*)&rx_data.data[9+i]);
+        }
+      }
+      printf("%s", CFG_PRINTF_NEWLINE);
+    }
+    // Disable LED
+    boardLED(CFG_LED_OFF);
+  }
+}
+#endif
+
+/**************************************************************************/
+/*!
+    @brief Board-specific initialisation function
+*/
+/**************************************************************************/
+void boardInit(void)
+{
+  SystemCoreClockUpdate();
+  delayInit();
+  GPIOInit();
+
+  #ifdef CFG_PRINTF_UART
+    uartInit(CFG_UART_BAUDRATE);
+  #endif
+
+  /* Power down unused blocks */
+  uint32_t pdrunconfig = ((0x1<<0)  |  // IRCOUT powered down
+                          (0x1<<1)  |  // IRC powered down
+                          (0x0<<2)  |  // FLASH powered up
+                          (0x1<<3)  |  // BOD powered down
+                          (0x1<<4)  |  // ADC powered down
+                          (0x0<<5)  |  // SYSOSC powered up
+                          (0x1<<6)  |  // WDTOSC powered down
+                          (0x0<<7)  |  // SYSPLL powered up
+                          (0x0<<8)  |  // USBPLL powered up
+                          (0x0<<9)  |  // RESERVED ... set as 0
+                          (0x0<<10) |  // USBPAD powered up
+                          (0x1<<11) |  // RESERVED ... set as 1
+                          (0x0<<12) |  // RESERVED ... set as 0
+                          (0x0<<13) |  // RESERVED ... set as 1
+                          (0x0<<14) |  // RESERVED ... set as 1
+                          (0x0<<15));  // RESERVED ... set as 1
+  LPC_SYSCON->PDRUNCFG = pdrunconfig;
+
+  /* Explicitly set all pin functions to a known state and disable any
+     unnecessary pull-ups to save some power.  It's important to setup
+     unbonded pins as well since they are still available on the die,
+     and can save some power setting them to output low, and disabling
+     their internal resistors (this cut ~350µA off the sleep current
+     in initial testing)
+
+  Pin                       Pin Config Bits               Selected Function     Notes
+  =======================   ==========================    ===================   ============== */
+  LPC_IOCON->RESET_PIO0_0   = (0<<0) | (0<<3);            // RESET              no pull-up/down
+  LPC_IOCON->PIO0_1         = (0<<0) | (2<<3);            // GPIO               pull-up (ISP)
+  LPC_IOCON->PIO0_2         = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->PIO0_3         = (1<<0) | (0<<3);            // USBVBUS            no pull-up/down
+  LPC_IOCON->PIO0_4         = (1<<0);                     // I2C-SCL            I2C = standard mode
+  LPC_IOCON->PIO0_5         = (1<<0);                     // I2C-SDA            I2C = standard mode
+  LPC_IOCON->PIO0_6         = (1<<0) | (0<<3);            // USBConnect         no pull-up/down
+  LPC_IOCON->PIO0_7         = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->PIO0_8         = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->PIO0_9         = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->SWCLK_PIO0_10  = (0<<0) | (2<<3);            // SWCLK              pull-up (SWCLK)
+  LPC_IOCON->TDI_PIO0_11    = (1<<0) | (0<<3) | (1<<7);   // GPIO (not TDI)     no pull-up/down, ADMODE = digital
+  LPC_IOCON->TMS_PIO0_12    = (1<<0) | (0<<3) | (1<<7);   // GPIO (not TMS)     no pull-up/down, ADMODE = digital
+  LPC_IOCON->TDO_PIO0_13    = (1<<0) | (0<<3) | (1<<7);   // GPIO (not TDO)     no pull-up/down, ADMODE = digital
+  LPC_IOCON->TRST_PIO0_14   = (1<<0) | (0<<3) | (1<<7);   // GPIO (not TRST)    no pull-up/down, ADMODE = digital
+  LPC_IOCON->SWDIO_PIO0_15  = (0<<0) | (2<<3) | (1<<7);   // SWDIO              pull-up (SWDIO), ADMODE = digital
+  LPC_IOCON->PIO0_16        = (0<<0) | (0<<3) | (1<<7);   // GPIO               no pull-up/down, ADMODE = digital
+  LPC_IOCON->PIO0_17        = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  #if defined CFG_PRINTF_UART
+  LPC_IOCON->PIO0_18        = (1<<0) | (0<<3);            // RXD                no pull-up/down
+  LPC_IOCON->PIO0_19        = (1<<0) | (0<<3);            // TXD                no pull-up/down
+  #else
+  LPC_IOCON->PIO0_18        = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->PIO0_19        = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  #endif
+  LPC_IOCON->PIO0_20        = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->PIO0_21        = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->PIO0_22        = (0<<0) | (0<<3) | (1<<7);   // GPIO               no pull-up/down, ADMODE = digital
+  LPC_IOCON->PIO0_23        = (0<<0) | (0<<3) | (1<<7);   // GPIO               no pull-up/down, ADMODE = digital
+
+  LPC_IOCON->PIO1_0         = (0<<0) | (0<<3) | (1<<7);   // GPIO               no pull-up/down, ADMODE = digital (pin not present on QFP48)
+  LPC_IOCON->PIO1_1         = (0<<0) | (0<<3) | (1<<7);   // GPIO               no pull-up/down, ADMODE = digital (pin not present on QFP48)
+  LPC_IOCON->PIO1_2         = (0<<0) | (0<<3) | (1<<7);   // GPIO               no pull-up/down, ADMODE = digital (pin not present on QFP48)
+  LPC_IOCON->PIO1_3         = (0<<0) | (0<<3) | (1<<7);   // GPIO               no pull-up/down, ADMODE = digital (pin not present on QFP48)
+  LPC_IOCON->PIO1_4         = (0<<0) | (0<<3) | (1<<7);   // GPIO               no pull-up/down, ADMODE = digital (pin not present on QFP48)
+  LPC_IOCON->PIO1_5         = (0<<0) | (0<<3) | (1<<7);   // GPIO               no pull-up/down, ADMODE = digital (pin not present on QFP48)
+  LPC_IOCON->PIO1_6         = (0<<0) | (0<<3) | (1<<7);   // GPIO               no pull-up/down, ADMODE = digital (pin not present on QFP48)
+  LPC_IOCON->PIO1_7         = (0<<0) | (0<<3) | (1<<7);   // GPIO               no pull-up/down, ADMODE = digital (pin not present on QFP48)
+  LPC_IOCON->PIO1_8         = (0<<0) | (0<<3) | (1<<7);   // GPIO               no pull-up/down, ADMODE = digital (pin not present on QFP48)
+  LPC_IOCON->PIO1_9         = (0<<0) | (0<<3) | (1<<7);   // GPIO               no pull-up/down, ADMODE = digital (pin not present on QFP48)
+  LPC_IOCON->PIO1_10        = (0<<0) | (0<<3) | (1<<7);   // GPIO               no pull-up/down, ADMODE = digital (pin not present on QFP48)
+  LPC_IOCON->PIO1_11        = (0<<0) | (0<<3) | (1<<7);   // GPIO               no pull-up/down, ADMODE = digital (pin not present on QFP48)
+  LPC_IOCON->PIO1_12        = (0<<0) | (0<<3) | (1<<7);   // GPIO               no pull-up/down, ADMODE = digital (pin not present on QFP48)
+  LPC_IOCON->PIO1_13        = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->PIO1_14        = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->PIO1_15        = (0<<0) | (2<<3);            // GPIO               pull-up (SLP_TR)
+  LPC_IOCON->PIO1_16        = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->PIO1_17        = (0<<0) | (0<<3);            // GPIO               no pull-up/down (pin not present on QFP48)
+  LPC_IOCON->PIO1_18        = (0<<0) | (0<<3);            // GPIO               no pull-up/down (pin not present on QFP48)
+  LPC_IOCON->PIO1_19        = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->PIO1_20        = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->PIO1_21        = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->PIO1_22        = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->PIO1_23        = (0<<0) | (2<<3);            // GPIO               pull-up (SD_DETECT)
+  LPC_IOCON->PIO1_24        = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->PIO1_25        = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->PIO1_26        = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->PIO1_27        = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->PIO1_28        = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->PIO1_29        = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+  LPC_IOCON->PIO1_30        = (0<<0) | (0<<3);            // GPIO               no pull-up/down (pin not present on QFP48)
+  LPC_IOCON->PIO1_31        = (0<<0) | (0<<3);            // GPIO               no pull-up/down
+
+  /* Set pins to output where possible */
+  LPC_GPIO->DIR[0] = ~( (1<<1) );         /* 0.1  = ISP (used as wakeup pin) */
+  LPC_GPIO->DIR[1] = 0xFFFFFFFF;
+
+  /* Set user LED pin to output and disable it */
+  LPC_GPIO->DIR[CFG_LED_PORT] |= (1 << CFG_LED_PIN);
+  boardLED(CFG_LED_OFF);
+
+  /* Enable I2C pullups by default */
+  LPC_GPIO->DIR[PINS_I2C_PULLUPS_PORT] |= (1 << PINS_I2C_PULLUPS_PIN);
+  LPC_GPIO->CLR[PINS_I2C_PULLUPS_PORT] = (1 << PINS_I2C_PULLUPS_PIN);
+
+  /* Set VREG voltage selection pin to output and switch to 3.3V */
+  LPC_GPIO->DIR[PINS_VREGVSEL_PORT] |= (1 << PINS_VREGVSEL_PIN);
+  boardSetVREG3V3();
+
+  /* Turn the SD card off by default */
+  LPC_GPIO->DIR[CFG_SDCARD_ENBLPORT] |= (1 << CFG_SDCARD_ENBLPIN);
+  LPC_GPIO->SET[CFG_SDCARD_ENBLPORT] = (1 << CFG_SDCARD_ENBLPIN);
+
+  /* Turn the VIN ADC off by default */
+  LPC_GPIO->DIR[PINS_VINADC_EN_PORT] |= (1 << PINS_VINADC_EN_PIN);
+  LPC_GPIO->SET[PINS_VINADC_EN_PORT] = (1 << PINS_VINADC_EN_PIN);
+  LPC_GPIO->DIR[PINS_VINADC_INPUT_PORT] |= (1 << PINS_VINADC_INPUT_PIN);
+  LPC_GPIO->CLR[PINS_VINADC_INPUT_PORT] = (1 << PINS_VINADC_INPUT_PIN);
+
+  /* Start Chibi */
+  #ifdef CFG_CHIBI
+    /* You may need to write a new address to EEPROM if it doesn't exist */
+    // uint16_t nodeaddr = 0xDADA;
+    // uint64_t ieeeaddr = 0x123456780000DADA;
+    // writeEEPROM((uint8_t*)CFG_EEPROM_CHIBI_NODEADDR, (uint8_t*)&nodeaddr, sizeof(nodeaddr));
+    // writeEEPROM((uint8_t*)CFG_EEPROM_CHIBI_IEEEADDR, (uint8_t*)&ieeeaddr, sizeof(ieeeaddr));
+    chb_init();
+  #endif
+
+  /* Initialise the SD Card? */
+  #ifdef CFG_SDCARD
+    // DSTATUS stat = disk_initialize(0);
+  #endif
+
+  /* Initialise USB */
+  #ifdef CFG_USB
+    delay(500);
+    usb_init();
+  #endif
+
+  /* Initialise the LCD */
+  #ifdef CFG_TFTLCD
+    lcdInit();
+  #endif
+
+  /* Initialise the RTC */
+  #ifdef CFG_RTC
+    /* ToDo: check if this throws an error! */
+    pcf2129Init();
+  #endif
+
+  /* Start the command line interface */
+  #ifdef CFG_INTERFACE
+    cliInit();
+  #endif
+
+  /* Turn the user LED on after init to indicate that everything is OK */
+  boardLED(CFG_LED_ON);
+}
+
+#if defined CFG_CMSIS_RTOS
+  /* Thread IDs */
+  osThreadId tid_mainthread;      /* ID for main thread   */
+  osThreadId tid_blinkythread;    /* ID for blinky thread */
+
+  /* Function prototypes */
+  void main_thread(void const *argument);
+  void blinky_thread (void const *argument);
+
+  /* Thread definitions */
+  osThreadDef(blinky_thread, osPriorityHigh, 1, 0);
+  osThreadDef(main_thread, osPriorityNormal, 1, 4 * OS_MAINSTKSIZE);
+
+  /**************************************************************************/
+  /*!
+      @brief Blinky thread, high priority, active very 3ms
+  */
+  /**************************************************************************/
+  void blinky_thread (void const *argument)
+  {
+   while (1)
+   {
+     /* Pass control to other tasks for 1s */
+     osDelay(1000);
+     printf ("Thread 1\n");
+   }
+  }
+
+  /**************************************************************************/
+  /*!
+      @brief Main thread, normal priority
+  */
+  /**************************************************************************/
+  void main_thread(void const *argument)
+  {
+    uint32_t currentSecond, lastSecond;
+    currentSecond = lastSecond = 0;
+
+    for (;;)
+    {
+       osDelay(1000);
+       boardLED((currentSecond++) & 1);
+    }
+  }
+
+  /**************************************************************************/
+  /*!
+      @brief RTX code entry point (replaces non-RTOS main further down!)
+  */
+  /**************************************************************************/
+  int main(void)
+  {
+    /* Initiaise the HW */
+    boardInit();
+
+    /* Initialise the RTX kernel */
+    osKernelInitialize();
+
+    /* Create out threads */
+    tid_mainthread = osThreadCreate(osThread(main_thread), NULL);
+    tid_blinkythread = osThreadCreate(osThread(blinky_thread), NULL);
+
+    /* Start the kernel and then go into an endless loop */
+    osKernelStart();
+
+    /* No return */
+    while(1);
+
+    return 1;
+  }
+#endif
+
+/**************************************************************************/
+/*!
+    @brief Primary entry point for this project.
+*/
+/**************************************************************************/
+#if !defined(_TEST_)
+#ifndef CFG_CMSIS_RTOS
+int main(void)
+{
+  uint32_t currentSecond, lastSecond;
+  currentSecond = lastSecond = 0;
+
+  boardInit();
+
+  while (1)
+  {
+    currentSecond = delayGetSecondsActive();
+    if (currentSecond != lastSecond)
+    {
+      lastSecond = currentSecond;
+
+      /* Send a test message over the air */
+      #ifdef CFG_CHIBI
+        // sendMessage();
+      #endif
+    }
+
+    #ifdef CFG_PROTOCOL
+      prot_task(NULL);
+    #endif
+
+    /* Poll for CLI input if CFG_INTERFACE is enabled */
+    #ifdef CFG_INTERFACE
+      cliPoll();
+    #endif
+
+    /* Check for incoming wireless messages */
+    #ifdef CFG_CHIBI
+      // checkForMessages();
+    #endif
+  }
+}
+#endif
+#endif
+
+/**************************************************************************/
+/*!
+    @brief Turns the LED(s) on or off
+*/
+/**************************************************************************/
+void boardLED(uint8_t state)
+{
+  if (state)
+  {
+    LPC_GPIO->SET[CFG_LED_PORT] = (1 << CFG_LED_PIN);
+  }
+  else
+  {
+    LPC_GPIO->CLR[CFG_LED_PORT] = (1 << CFG_LED_PIN);
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Configure the board for low power and enter sleep mode
+*/
+/**************************************************************************/
+void boardSleep(void)
+{
+  /* Configure ISP switch as a wakeup source (pin 0.1 = input)  */
+  LPC_IOCON->PIO0_1 = (0<<0) | (2<<3);
+  LPC_GPIO->DIR[0] &= ~(1 << 1);
+  GPIOSetPinInterrupt(CHANNEL0, 0, 1, 0, 0);
+  LPC_SYSCON->STARTERP0 = 0x1<<0;
+
+  #ifdef CFG_CHIBI
+    /* What about leaving the AT86RF212 awake, and setting up the the IRQ
+       pin to wake the MCU up on incoming message? */
+    chb_sleep(TRUE);
+  #endif
+
+  #ifdef CFG_SDCARD
+    /* Note: The pins on the SD card will cause phantom current
+       to be drawn through to the SD card, and need to be set
+       to GPIO output and low to prevent this from happening.
+       Can save up to 1mA of current when a card is inserted. */
+    LPC_GPIO->DIR[CFG_SDCARD_ENBLPORT] |= (1 << CFG_SDCARD_ENBLPIN);  // SD_EN
+    LPC_GPIO->SET[CFG_SDCARD_ENBLPORT] = (1 << CFG_SDCARD_ENBLPIN);
+    LPC_GPIO->DIR[CFG_SDCARD_CDPORT] |= (1 << CFG_SDCARD_CDPIN);      // SD_DETECT
+    LPC_GPIO->CLR[CFG_SDCARD_CDPORT] = (1 << CFG_SDCARD_CDPIN);
+    LPC_GPIO->DIR[CFG_SDCARD_SSELPORT] |= (1 << CFG_SDCARD_SSELPIN);  // SD_CS
+    LPC_GPIO->CLR[CFG_SDCARD_SSELPORT] = (1 << CFG_SDCARD_SSELPIN);
+
+    LPC_IOCON->PIO1_20 = (0<<0) | (0<<3);                             // SCK1  -> GPIO
+    LPC_IOCON->PIO1_21 = (0<<0) | (0<<3);                             // MISO1 -> GPIO
+    LPC_IOCON->PIO1_22 = (0<<0) | (0<<3);                             // MOSI1 -> GPIO
+
+    LPC_GPIO->DIR[1] |= (1 << 20);
+    LPC_GPIO->CLR[1]  = (1 << 20);
+    LPC_GPIO->DIR[1] |= (1 << 21);
+    LPC_GPIO->CLR[1]  = (1 << 21);
+    LPC_GPIO->DIR[1] |= (1 << 22);
+    LPC_GPIO->CLR[1]  = (1 << 22);
+  #endif
+
+  /* Turn the VIN voltage divider off */
+  LPC_GPIO->SET[PINS_VINADC_EN_PORT] = (1 << PINS_VINADC_EN_PIN);
+  LPC_GPIO->DIR[PINS_VINADC_INPUT_PORT] |= (1 << PINS_VINADC_INPUT_PIN);
+  LPC_GPIO->CLR[PINS_VINADC_INPUT_PORT] = (1 << PINS_VINADC_INPUT_PIN);
+
+  /* Disable I2C pullups */
+  LPC_GPIO->SET[PINS_I2C_PULLUPS_PORT] = (1 << PINS_I2C_PULLUPS_PIN);
+
+  /* Turn the user LED off */
+  boardLED(CFG_LED_OFF);
+
+  /* Set SWCLK to GPIO (comment out to maintain SWD connection) */
+  LPC_IOCON->SWCLK_PIO0_10 = (1<<0) | (0<<3);
+  LPC_GPIO->DIR[0] |= (1 << 10);
+  LPC_GPIO->CLR[0]  = (1 << 10);
+
+  /* Set SWDIO to GPIO (comment out to maintain SWD connection) */
+  LPC_IOCON->SWDIO_PIO0_15 = (1<<0) | (0<<3) | (1<<7);
+  LPC_GPIO->DIR[0] |= (1 << 15);
+  LPC_GPIO->CLR[0]  = (1 << 15);
+
+  /* Set USBConnect to GPIO output low */
+  LPC_IOCON->PIO0_6 = (0<<0) | (0<<3);
+  LPC_GPIO->DIR[0] |= (1 << 6);
+  LPC_GPIO->CLR[0]  = (1 << 6);
+
+  /* Switch to 2.2V supply (less leakage current, etc.) */
+  boardSetVREG2V2();
+
+  /* Enter power down mode (Disable BOD and WDT oscillator) */
+  PMU_Sleep(MCU_POWER_DOWN, BOD_PD | WDT_OSC_PD);
+
+  /* Reconfigure the board post-wakeup */
+  boardWakeup();
+}
+
+/**************************************************************************/
+/*!
+    @brief  Restores parts and system peripherals to an appropriate
+            state after waking up from sleep mode
+*/
+/**************************************************************************/
+void boardWakeup(void)
+{
+  /* Set power back to main voltage if dual output supply is being used */
+  boardSetVREG3V3();
+
+  /* Switch I2C pullups back on */
+  LPC_GPIO->CLR[PINS_I2C_PULLUPS_PORT] = (1 << PINS_I2C_PULLUPS_PIN);
+
+  /* ToDo: Reconfigure SPI pins or reinitialize SPI, etc.? */
+
+  #ifdef CFG_CHIBI
+    /* Wakeup Chibi/Transceiver */
+    chb_sleep(FALSE);
+  #endif
+}
+
+/**************************************************************************/
+/*!
+    @brief Sets the output of the TPS780 to 3.3V
+*/
+/**************************************************************************/
+void boardSetVREG3V3(void)
+{
+  LPC_GPIO->CLR[PINS_VREGVSEL_PORT] = (1 << PINS_VREGVSEL_PIN);
+}
+
+/**************************************************************************/
+/*!
+    @brief Sets the output of the TPS780 to 2.2V
+*/
+/**************************************************************************/
+void boardSetVREG2V2(void)
+{
+  LPC_GPIO->SET[PINS_VREGVSEL_PORT] = (1 << PINS_VREGVSEL_PIN);
+}
+
+/**************************************************************************/
+/*!
+    @brief Reads the current VIN level using the on-chip ADC
+
+    @returns A fixed point voltage level where 3176 = 3.176V
+*/
+/**************************************************************************/
+uint32_t boardGetVIN(void)
+{
+  uint32_t vraw, vcomp, vref, i;
+
+  /* Indicate the ADC range */
+  #if ADC_MODE_10BIT
+  uint32_t adcRange = 1024;
+  #else
+  uint32_t adcRange = 4096;
+  #endif
+
+  /* Delay ADC init until now to save power */
+  adcInit();
+
+  /* Enable the VIN ADC resistor-divider and setup the ADC pin */
+  LPC_GPIO->CLR[PINS_VINADC_EN_PORT] = (1 << PINS_VINADC_EN_PIN);
+  LPC_IOCON->TDI_PIO0_11 = (2<<0) | (0<<7);
+
+  /* We need a small delay for everything to stabilise with the FET + R/D */
+  /* ToDo: Check this on a scope to see how long stabilisation takes */
+  for (i=0;i<1000;i++)
+  {
+    __NOP();
+  }
+
+  /* Get the raw ADC value taking into account range, adc ref, and r/d multiplier */
+  vref = GPIOGetPinValue(PINS_VREGVSEL_PORT, PINS_VREGVSEL_PIN) ? 2200 : 3300;
+  vraw = (((adcRead(0) * 1000) / adcRange) * vref) / 1000;
+  vcomp = (vraw * RF1GHZNODE_VINADC_MULTIPLIER_FIXED10K) / 10000;
+
+  /* Turn everything back off to save power */
+  LPC_GPIO->SET[PINS_VINADC_EN_PORT] = (1 << PINS_VINADC_EN_PIN);
+  LPC_GPIO->DIR[PINS_VINADC_INPUT_PORT] = (1 << PINS_VINADC_INPUT_PIN);
+  LPC_GPIO->CLR[PINS_VINADC_INPUT_PORT] = (1 << PINS_VINADC_INPUT_PIN);
+  LPC_IOCON->TDI_PIO0_11 = (1<<0) | (0<<3) | (1<<7);
+
+  /* Return fixed point value (3157 = 3.157V) */
+  return vcomp;
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/boards/rf1ghznode/board_rf1ghznode.h b/reform2-lpc-fw/src/boards/rf1ghznode/board_rf1ghznode.h
new file mode 100644
index 0000000000000000000000000000000000000000..66175724ae94c8f4d080387cceb8fb6a1e08427b
--- /dev/null
+++ b/reform2-lpc-fw/src/boards/rf1ghznode/board_rf1ghznode.h
@@ -0,0 +1,738 @@
+/**************************************************************************/
+/*!
+    @file     board_rf1ghznode.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Board-specific files for the microBuilder LPC11U37/LPC1347
+              AT86RF212 stand-alone board
+    @ingroup  Boards
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012 K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __BOARD_RF1GHZNODE_H__
+#define __BOARD_RF1GHZNODE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sysdefs.h"
+
+/*=========================================================================
+    MCU SELECTION
+
+    Include one of the following definitions depending on if you are
+    using the LPC11U37 or LPC1347.  They're generally interchangeable, but
+    the LPC11Uxx and LPC13xx CMSIS implementations have some differences
+    in naming convention, and occasionally a feature is only available on
+    the M3 (DWT for example).  Selecting the appropriate MCU allows
+    the right code to be included when differences between the CMSIS
+    implementations are present.
+
+    -----------------------------------------------------------------------*/
+    // #define CFG_MCU_LPC11U24FBD48_401
+    #define CFG_MCU_LPC11U37FBD48_401
+    // #define CFG_MCU_LPC1347FBD48
+    // #define CFG_MCU_LPC1347FHN33
+
+    /* Basic error checking */
+    #if !defined CFG_MCU_LPC1347FBD48 && \
+        !defined CFG_MCU_LPC11U37FBD48_401 && \
+        !defined CFG_MCU_LPC11U24FBD48_401 && \
+        !defined CFG_MCU_LPC1347FHN33
+      #error "An MCU must be selected in projectconfig.h (Ex. CFG_MCU_LPC11U37FBD48_401, CFG_MCU_LPC1347FBD48, etc.)"
+    #endif
+
+    /* Set flag to indicate which CMSIS library to use */
+    #if (defined CFG_MCU_LPC1347FBD48 || defined CFG_MCU_LPC1347FHN33)
+      #define CFG_MCU_FAMILY_LPC13UXX
+    #elif (defined CFG_MCU_LPC11U24FBD48_401 || defined CFG_MCU_LPC11U37FBD48_401)
+      #define CFG_MCU_FAMILY_LPC11UXX
+    #endif
+
+    /* Include the correct MCU header file */
+    #if defined CFG_MCU_FAMILY_LPC13UXX
+      #include "LPC13Uxx.h"
+    #endif
+    #if defined CFG_MCU_FAMILY_LPC11UXX
+      #include "LPC11Uxx.h"
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    FIRMWARE VERSION SETTINGS
+    -----------------------------------------------------------------------*/
+    #define CFG_FIRMWARE_VERSION_MAJOR      (0)
+    #define CFG_FIRMWARE_VERSION_MINOR      (0)
+    #define CFG_FIRMWARE_VERSION_REVISION   (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PIN USAGE
+    -----------------------------------------------------------------------
+    This table tries to give an indication of which GPIO pins and
+    peripherals are used by the available drivers and SW examples.  Only
+    dedicated GPIO pins available on the LPC1347 Reference Board are shown
+    below.  Any unused peripheral blocks like I2C, SSP, ADC, etc., can
+    also be used as GPIO if they are available.
+
+                PORT 0
+                =========================================================
+                0 1 2 3 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
+
+    HX8340B     . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    HX8347G     . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    CHIBI       . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    SSD1306 I2C . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    FAT32/MMC   . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  X  .  .
+    PN532 I2C   . . . . . . . .  .  .  .  .  .  .  X  X  .  .  .  .  .  .
+    PCF2129A    . . . . . . . .  .  .  .  .  .  .  X  X  .  .  .  .  .  .
+
+                PORT 1
+                ===========================================================================
+                0 1 2 3 4 5 7 8 10 11 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 31
+                + + + + + + + +  +  +              +  +                                   -
+
+    HX8340B     . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  X  X  X  X  X  .
+    HX8347G     . . . . . . . .  .  .  X  X  X  X  .  .  X  X  X  X  X  X  X  X  X  X  .  .
+    CHIBI       . . . . . . . .  .  .  X  X  X  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    SSD1306 I2C . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    FAT32/MMC   . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  X  X  .  .  .  .  .  .
+    PN532 I2C   . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    PCF2129A    . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+
+                TIMERS                   SSP   ADC               UART
+                ======================   ===   ===============   ====
+                16B0  16B1  32B0  32B1   0 1   0 1 2 3 4 5 6 7   0
+
+    HX8340B     .      .    .     .      . .   . . . . . . . .   .
+    HX8347G     .      .    .     .      . .   . . . . . . . .   .
+    CHIBI       .      .    .     .      X .   . . . . . . . .   .
+    SSD1306 I2C .      .    .     .      . .   . . . . . . . .   .
+    FAT32/MMC   .      .    .     .      . X   . . . . . . . .   .
+
+    [+]   Only available on QFP64 package
+    [-]   Only available on QFP48 package
+
+  =========================================================================*/
+
+
+/*=========================================================================
+    GPIO INTERRUPTS
+    -----------------------------------------------------------------------
+    This table shows where GPIO interrupts are mapped in this project
+    (Note that the LPC11U and LPC13U use different names for the
+    IRQ Handlers in the standard headers)
+
+    Interrupt                                     Location
+    ------------------------------------------    -------------------------
+    PIN_INT0_IRQHandler - FLEX_INT0_IRQHandler    chb_drvr.c
+    PIN_INT1_IRQHandler - FLEX_INT1_IRQHandler    pcf2129.c
+    PIN_INT2_IRQHandler - FLEX_INT2_IRQHandler    cc3000 (spi.c)
+    PIN_INT3_IRQHandler - FLEX_INT3_IRQHandler
+    PIN_INT4_IRQHandler - FLEX_INT4_IRQHandler
+    PIN_INT5_IRQHandler - FLEX_INT5_IRQHandler
+    PIN_INT6_IRQHandler - FLEX_INT6_IRQHandler
+    PIN_INT7_IRQHandler - FLEX_INT7_IRQHandler
+    GINT0_IRQHandler
+    GINT0_IRQHandler
+    -----------------------------------------------------------------------*/
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SUPPORTED PERIPHERALS
+    -----------------------------------------------------------------------
+    Because all ISRs are referenced in the startup code, GCC typically
+    won't optimise out the ISR functions during compilation even if the
+    ISRs will never be entered, resulting in larger binaries than required
+    (for example if no I2C sensors are used, be sure to disable I2C support
+    since the I2C ISR is quite large).
+
+    Use the defines below to include or exclude support for specific
+    peripherals.
+
+    NOTE: GPIO ISRs are handled seperately in GPIO INTERRUPTS below
+    -----------------------------------------------------------------------*/
+    #define CFG_ENABLE_I2C
+    #define CFG_ENABLE_UART
+    #define CFG_ENABLE_USB
+    #define CFG_ENABLE_TIMER32
+/*=========================================================================*/
+
+
+/*=========================================================================
+    ENABLE CMSIS-RTOS
+
+    -----------------------------------------------------------------------*/
+    // #define CFG_CMSIS_RTOS
+
+    #if defined CFG_CMSIS_RTOS
+      #include "board_rf1ghznode_rtxconf.h"
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    EEPROM
+    -----------------------------------------------------------------------
+    EEPROM is used to persist certain user modifiable values to make
+    sure that these changes remain in effect after a reset or hard
+    power-down.  The addresses in EEPROM for these various system
+    settings/values are defined below.  The first 256 bytes of EEPROM
+    are reserved for this (0x0000..0x00FF).
+
+    CFG_EEPROM_SIZE           The number of bytes available on the EEPROM
+    CFG_EEPROM_RESERVED       The last byte of reserved EEPROM memory
+
+          EEPROM Address (0x0000..0x00FF)
+          ===============================
+          0 1 2 3 4 5 6 7 8 9 A B C D E F
+    000x  x x . . x x x x x x x x . . . .   Chibi
+    001x  . . . . . . . . . . . . . . . .
+    002x  . . . . . . . . . . . . . . . .
+    003x  . . . . . . . . . . . . . . . .
+    004x  . . . . . . . . . . . . . . . .
+    005x  . . . . . . . . . . . . . . . .
+    006x  . . . . . . . . . . . . . . . .
+    007x  . . . . . . . . . . . . . . . .
+    008x  . . . . . . . . . . . . . . . .
+    009x  . . . . . . . . . . . . . . . .
+    00Ax  . . . . . . . . . . . . . . . .
+    00Bx  . . . . . . . . . . . . . . . .
+    00Cx  . . . . . . . . . . . . . . . .
+    00Dx  . . . . . . . . . . . . . . . .
+    00Ex  . . . . . . . . . . . . . . . .
+    00Fx  . . . . . . . . . . . . . . . .
+
+    -----------------------------------------------------------------------*/
+    #define CFG_EEPROM_SIZE                 (4032)
+    #define CFG_EEPROM_RESERVED             (0x00FF)              // Protect first 256 bytes of memory
+    #define CFG_EEPROM_CHIBI_NODEADDR       (uint16_t)(0x0000)    // 2
+    #define CFG_EEPROM_CHIBI_IEEEADDR       (uint16_t)(0x0004)    // 8
+/*=========================================================================*/
+
+
+/*=========================================================================
+    ON-BOARD LED
+    -----------------------------------------------------------------------
+
+    CFG_LED_PORT              The port for the on board LED
+    CFG_LED_PIN               The pin for the on board LED
+    CFG_LED_ON                The pin state to turn the LED on (0 = low, 1 = high)
+    CFG_LED_OFF               The pin state to turn the LED off (0 = low, 1 = high)
+
+    -----------------------------------------------------------------------*/
+    #define CFG_LED_PORT                    (1)
+    #define CFG_LED_PIN                     (31)
+    #define CFG_LED_ON                      (0)
+    #define CFG_LED_OFF                     (1)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    ADC
+    -----------------------------------------------------------------------
+
+    CFG_ADC_MODE_LOWPOWER     If set to 1, this will configure the ADC
+                              for low-power operation (LPC1347 only)
+    CFG_ADC_MODE_10BIT        If set to 1, this will configure the ADC
+                              for 10-bit mode (LPC1347 only)
+
+    -----------------------------------------------------------------------*/
+    #define CFG_ADC_MODE_LOWPOWER       (0)
+    #define CFG_ADC_MODE_10BIT          (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    UART
+    -----------------------------------------------------------------------
+
+    CFG_UART_BAUDRATE         The default UART speed.  This value is used
+                              when initialising UART, and should be a
+                              standard value like 57600, 9600, etc.
+                              NOTE: This value may be overridden if
+                              another value is stored in EEPROM!
+    CFG_UART_BUFSIZE          The length in bytes of the UART RX FIFO. This
+                              will determine the maximum number of received
+                              characters to store in memory.
+
+    -----------------------------------------------------------------------*/
+    #define CFG_UART_BAUDRATE               (115200)
+    #define CFG_UART_BUFSIZE                (256)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SPI
+    -----------------------------------------------------------------------
+
+    CFG_SSP_SCK0_LOCATION     The location of the SCK pin for SSP0
+    CFG_SSP_MISO1_LOCATION    The location of the MISO1 pin for SSP1
+    CFG_SSP_MOSI1_LOCATION    The location of the MOSI1 pin for SSP1
+    CFG_SSP_SCK1_LOCATION     The location of the SCK pin for SSP1
+
+    -----------------------------------------------------------------------*/
+    #define CFG_SSP_SCK0_0_6                (6)     // Used by USBConnect
+    #define CFG_SSP_SCK0_0_10               (10)    // Used by SWD
+    #define CFG_SSP_SCK0_1_29               (29)
+
+    #define CFG_SSP_MISO1_0_22              (22)
+    #define CFG_SSP_MISO1_1_21              (21)
+    #define CFG_SSP_MOSI1_0_21              (21)
+    #define CFG_SSP_MOSI1_1_22              (22)
+    #define CFG_SSP_SCK1_1_15               (15)
+    #define CFG_SSP_SCK1_1_20               (20)
+
+    // Select the appropriate pin locations here
+    #define CFG_SSP_SCK0_LOCATION           (CFG_SSP_SCK0_1_29)
+    #define CFG_SSP_MISO1_LOCATION          (CFG_SSP_MISO1_1_21)
+    #define CFG_SSP_MOSI1_LOCATION          (CFG_SSP_MOSI1_1_22)
+    #define CFG_SSP_SCK1_LOCATION           (CFG_SSP_SCK1_1_20)
+
+    // Set the phase and polarity for SSP0 and SSP1
+    #define CFG_SSP_CPOL0               (0)
+    #define CFG_SSP_CPHA0               (0)
+    #define CFG_SSP_CPOL1               (0)
+    #define CFG_SSP_CPHA1               (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PRINTF REDIRECTION
+    -----------------------------------------------------------------------
+
+    CFG_PRINTF_MAXSTRINGSIZE  Maximum size of string buffer for printf
+    CFG_PRINTF_NEWLINE        This is typically "\r\n" for Windows or
+                              "\n" for *nix
+    CFG_PRINTF_UART           Will cause all printf statements to be
+                              redirected to UART
+    CFG_PRINTF_USBCDC         Will cause all printf statements to be
+                              redirect to USB Serial
+    CFG_PRINTF_DEBUG          Use the debug interface for printf
+
+    Note: If no printf redirection definitions are present, all printf
+    output will be ignored.
+    -----------------------------------------------------------------------*/
+    #define CFG_PRINTF_MAXSTRINGSIZE        (255)
+    #define CFG_PRINTF_NEWLINE              "\n"
+
+    // #define CFG_PRINTF_UART
+    #define CFG_PRINTF_USBCDC
+    // #define CFG_PRINTF_DEBUG
+/*=========================================================================*/
+
+
+/*=========================================================================
+    COMMAND LINE INTERFACE
+    -----------------------------------------------------------------------
+
+    CFG_INTERFACE             If this field is defined the UART or USBCDC
+                              based command-line interface will be included
+    CFG_INTERFACE_MAXMSGSIZE  The maximum number of bytes to accept for an
+                              incoming command
+    CFG_INTERFACE_PROMPT      The command prompt to display at the start
+                              of every new data entry line
+    CFG_INTERFACE_SILENTMODE  If this is set to 1 only text generated in
+                              response to commands will be send to the
+                              output buffer.  The command prompt will not
+                              be displayed and incoming text will not be
+                              echoed back to the output buffer (allowing
+                              you to see the text you have input).  This
+                              is normally only desirable in a situation
+                              where another MCU is communicating with
+                              the LPC1343.
+    CFG_INTERFACE_DROPCR      If this is set to 1 all incoming \r
+                              characters will be dropped
+    CFG_INTERFACE_ENABLEIRQ   If this is set to 1 the IRQ pin will be
+                              set high when a command starts executing
+                              and will go low when the command has
+                              finished executing or the LCD is not busy.
+                              This allows another device to know when a
+                              new command can safely be sent.
+    CFG_INTERFACE_IRQPORT     The gpio port for the IRQ/busy pin
+    CFG_INTERFACE_IRQPIN      The gpio pin number for the IRQ/busy pin
+    CFG_INTERFACE_SHORTERRORS If this is enabled only short 1 character
+                              error messages will be returned (followed
+                              by CFG_PRINTF_NEWLINE), rather than more
+                              verbose error messages.  The specific
+                              characters used are defined below.
+    CFG_INTERFACE_CONFIRMREADY  If this is set to 1 a text confirmation
+                              will be sent when the command prompt is
+                              ready for a new command.  This is in
+                              addition to CFG_INTERFACE_ENABLEIRQ if
+                              this is also enabled.  The character used
+                              is defined below.
+    CFG_INTERFACE_LONGSYSINFO If this is set to 1 extra information will
+                              be included in the Sys Info ('V') command
+                              on the CLI. This can be useful when trying
+                              to debug problems on remote HW, or with
+                              unknown firmware.  It will also use about
+                              0.5KB flash, though, so only enable it is
+                              necessary.
+
+    NOTE:                     The command-line interface will use either
+                              USB-CDC or UART depending on whether
+                              CFG_PRINTF_UART or CFG_PRINTF_USBCDC are
+                              selected.
+    -----------------------------------------------------------------------*/
+    #define CFG_INTERFACE
+    #define CFG_INTERFACE_MAXMSGSIZE        (256)
+    #define CFG_INTERFACE_PROMPT            "LPC1347 >> "
+    #define CFG_INTERFACE_SILENTMODE        (0)
+    #define CFG_INTERFACE_DROPCR            (0)
+    #define CFG_INTERFACE_ENABLEIRQ         (0)
+    #define CFG_INTERFACE_IRQPORT           (0)
+    #define CFG_INTERFACE_IRQPIN            (7)
+    #define CFG_INTERFACE_SHORTERRORS       (0)
+    #define CFG_INTERFACE_CONFIRMREADY      (0)
+    #define CFG_INTERFACE_LONGSYSINFO       (1)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SIMPLE BINARY PROTOCOL
+    -----------------------------------------------------------------------
+
+    CFG_PROTOCOL             If this field is defined the binary command
+                              parser will be included
+    -----------------------------------------------------------------------*/
+    // #define CFG_PROTOCOL
+
+    // #define CFG_PROTOCOL_VIA_HID
+    #define CFG_PROTOCOL_VIA_BULK
+
+    #if defined(CFG_PROTOCOL) && !defined(CFG_PROTOCOL_VIA_HID) && !defined(CFG_PROTOCOL_VIA_BULK)
+      #error CFG_PROTOCOL must be enabled with either CFG_PROTOCOL_VIA_HID or CFG_PROTOCOL_VIA_BULK
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    TFT LCD
+    -----------------------------------------------------------------------
+
+    CFG_TFTLCD                  If defined, this will cause drivers for
+                                a pre-determined LCD screen to be included
+                                during build.  Only one LCD driver can be
+                                included during the build process (for ex.
+                                'drivers/displays/hw/ILI9325.c')
+    CFG_TFTLCD_INCLUDESMALLFONTS If set to 1, smallfont support will be
+                                included for 3x6, 5x8, 7x8 and 8x8 fonts.
+                                This should only be enabled if these small
+                                fonts are required since there is already
+                                support for larger fonts generated with
+                                Dot Factory
+                                http://www.pavius.net/downloads/tools/53-the-dot-factory
+    CFG_TFTLCD_USEAAFONTS       If set to a non-zero value, anti-aliased
+                                fonts will be used instead of regular 1-bit
+                                font.  These result in much higher-
+                                quality text, but the fonts are 2 or 4
+                                times larger than plain bitmap fonts and
+                                take a bit more rendering time to display.
+    CFG_TFTLCD_TS_DEFAULTTHRESHOLD  Default minimum threshold to trigger a
+                                touch event with the touch screen (and exit
+                                from 'tsWaitForEvent' in touchscreen.c).
+                                Should be an 8-bit value somewhere between
+                                8 and 75 in normal circumstances.  This is
+                                the default value and may be overriden by
+                                a value stored in EEPROM.
+    CFG_TFTLCD_TS_KEYPADDELAY   The delay in milliseconds between key
+                                presses in dialogue boxes
+   -----------------------------------------------------------------------*/
+    // #define CFG_TFTLCD
+    #define CFG_TFTLCD_INCLUDESMALLFONTS    (1)
+    #define CFG_TFTLCD_USEAAFONTS           (0)
+    #define CFG_TFTLCD_TS_DEFAULTTHRESHOLD  (50)
+    #define CFG_TFTLCD_TS_KEYPADDELAY       (100)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    MICRO-SD CARD
+    -----------------------------------------------------------------------
+
+    CFG_SDCARD                If this field is defined SD Card and FAT32
+                              file system support will be included
+    CFG_SDCARD_SPIPORT        SSP Port used for the SD card (0 or 1)
+    CFG_SDCARD_READONLY       If this is set to 1, all commands to
+                              write to the SD card will be removed
+                              saving some flash space.
+    CFG_SDCARD_CDPORT         The card detect port number
+    CFG_SDCARD_CDPIN          The card detect pin number
+
+    NOTE:                     All config settings for FAT32 are defined
+                              in ffconf.h
+    -----------------------------------------------------------------------*/
+    #define CFG_SDCARD
+    #define CFG_SDCARD_READONLY             (0)   // Must be 0 or 1
+    #define CFG_SDCARD_SPIPORT              (1)
+    #define CFG_SDCARD_SSELPORT             (0)
+    #define CFG_SDCARD_SSELPIN              (21)
+    #define CFG_SDCARD_CDPORT               (1)
+    #define CFG_SDCARD_CDPIN                (23)
+    #define CFG_SDCARD_ENBLPORT             (1)
+    #define CFG_SDCARD_ENBLPIN              (24)
+
+    #ifdef CFG_SDCARD
+      #if !((CFG_SDCARD_READONLY == 0) || (CFG_SDCARD_READONLY == 1))
+        #error "Invalid value for CFG_SDCARD_READONLY"
+      #endif
+      #if !((CFG_SDCARD_SPIPORT == 0) || (CFG_SDCARD_SPIPORT == 1))
+        #error "Invalid SPI port for CFG_SDCARD_SPIPORT"
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    CHIBI WIRELESS STACK
+    -----------------------------------------------------------------------
+
+    CFG_CHIBI                   If defined, the CHIBI wireless stack will be
+                                included during build.  Requires external HW.
+    CFG_CHIBI_MODE              The mode to use when receiving and transmitting
+                                wireless data.  See chb_drvr.h for possible values
+    CFG_CHIBI_POWER             The power level to use when transmitting.  See
+                                chb_drvr.h for possible values
+    CFG_CHIBI_CHANNEL           802.15.4 Channel (0 = 868MHz, 1-10 = 915MHz)
+    CFG_CHIBI_PANID             16-bit PAN Identifier (ex.0x1234)
+    CFG_CHIBI_PROMISCUOUS       Set to 1 to enabled promiscuous mode or
+                                0 to disable it.  If promiscuous mode is
+                                enabled be sure to set CFG_CHIBI_BUFFERSIZE
+                                to an appropriately large value (ex. 1024)
+    CFG_CHIBI_BUFFERSIZE        The size of the message buffer in bytes
+    -----------------------------------------------------------------------*/
+    #define CFG_CHIBI
+    #define CFG_CHIBI_MODE                  (0)       // OQPSK_868MHZ
+    #define CFG_CHIBI_POWER                 (0xE9)    // CHB_PWR_EU2_3DBM
+    #define CFG_CHIBI_CHANNEL               (0)       // 868-868.6 MHz
+    #define CFG_CHIBI_PANID                 (0x1234)
+    #define CFG_CHIBI_PROMISCUOUS           (0)
+    #define CFG_CHIBI_BUFFERSIZE            (256)
+
+    #define CFG_CHIBI_SPIPORT               (0)       // Must be 0 or 1
+    #define CFG_CHIBI_SSPORT                (0)
+    #define CFG_CHIBI_SSPIN                 (2)
+    #define CFG_CHIBI_EINTPORT              (1)
+    #define CFG_CHIBI_EINTPIN               (13)
+    #define CFG_CHIBI_RSTPORT               (1)
+    #define CFG_CHIBI_RSTPIN                (14)
+    #define CFG_CHIBI_SLPTRPORT             (1)
+    #define CFG_CHIBI_SLPTRPIN              (15)
+    #define CFG_CHIBI_CC1190_HGM_PORT       (1)
+    #define CFG_CHIBI_CC1190_HGM_PIN        (11)
+
+    #ifdef CFG_CHIBI
+      #if !((CFG_CHIBI_SPIPORT == 0) || (CFG_CHIBI_SPIPORT == 1))
+        #error "Invalid SPI port for CFG_CHIBI_SPIPORT"
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    CC3000 WIFI MODULES
+    -----------------------------------------------------------------------
+
+    CFG_CC3000                     If defined, CC3000 support will be
+                                   included during build.  Requires
+                                   external HW
+    -----------------------------------------------------------------------*/
+    // #define CFG_CC3000
+    #define CFG_CC3000_SPI_PORT         (1)
+    #define CFG_CC3000_EN_PORT          (0)
+    #define CFG_CC3000_EN_PIN           (14)
+    #define CFG_CC3000_IRQ_PORT         (0)
+    #define CFG_CC3000_IRQ_PIN          (16)
+    #define CFG_CC3000_CS_PORT          (0)
+    #define CFG_CC3000_CS_PIN           (17)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PN532/NFC STACK
+    -----------------------------------------------------------------------
+
+    CFG_PN532                      If defined, the PN532/NFC stack will be
+                                   included during build.  Requires
+                                   external HW
+    CFG_PN532_MEM_POOL_SIZE_BYTES  Size of the dynamic memory pool in bytes
+                                   (used by pn532/mem_allocator/ when
+                                   working with NDEF messages)
+    -----------------------------------------------------------------------*/
+    // #define CFG_PN532
+    #define CFG_PN532_RSTPD_PORT                      (0)
+    #define CFG_PN532_RSTPD_PIN                       (16)
+    #define CFG_PN532_I2C_IRQPORT                     (0)
+    #define CFG_PN532_I2C_IRQPIN                      (17)
+    #define CFG_PN532_MEM_POOL_SIZE_BYTES             (512)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    RTC SUPPORT
+    -----------------------------------------------------------------------
+
+    CFG_RTC                     If defined, RTC support will be included.
+                                Requires external HW.
+    -----------------------------------------------------------------------*/
+    // #define CFG_RTC
+
+    #if defined(CFG_RTC) && !defined(CFG_ENABLE_I2C)
+      #error "CFG_ENABLE_I2C must be defined with CFG_RTC"
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    STEPPER MOTOR SUPPORT
+    -----------------------------------------------------------------------
+
+    CFG_STEPPER                 If defined, basic stepper motor support
+                                will be included.  Requires external HW.
+    -----------------------------------------------------------------------*/
+    // #define CFG_STEPPER
+    #define CFG_STEPPER_TIMER32                       (0)
+    #define CFG_STEPPER_IN1_PORT                      (0)
+    #define CFG_STEPPER_IN1_PIN                       (8)
+    #define CFG_STEPPER_IN2_PORT                      (0)
+    #define CFG_STEPPER_IN2_PIN                       (9)
+    #define CFG_STEPPER_IN3_PORT                      (0)
+    #define CFG_STEPPER_IN3_PIN                       (14)
+    #define CFG_STEPPER_IN4_PORT                      (0)
+    #define CFG_STEPPER_IN4_PIN                       (13)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    USB
+
+    CFG_USB_STRING_MANUFACTURER Manufacturer name that will appear in the
+                                device descriptor during USB enumeration
+    CFG_USB_STRING_PRODUCT      Product name that will appear in the
+                                device descriptor during USB enumeration
+    CFG_USB_VENDORID            16-bit USB vendor ID
+    CFG_CDC                     Enable USB CDC support
+    CFG_USB_HID_KEYBOARD        Enable USB HID keyboard emulation
+    CFG_USB_HID_MOUSE           Enable USB HID mouse emulation for a five
+                                button 'Windows' mouse with scroll wheels
+    CFG_USB_HID_GENERIC         Enable USB HID Generic support for custom
+                                in and out reports, with report size set
+                                via CFG_USB_HID_GENERIC_REPORT_SIZE
+    CFG_USB_MSC                 Enable USB Mass Storage support, pointing
+                                to the SD card reader (requires mmc.c from
+                                the FATFS drivers, but doesn't use FATFS)
+
+    You can combine more than one USB class below and they will be
+    automatically combined in a USB composite device within the limit of
+    available USB endpoints.  The USB Product ID is calculated automatically
+    based on the combination of classes defined below.
+
+    NOTE: Windows requires the .inf file in '/core/usb' for CDC support
+    -----------------------------------------------------------------------*/
+    #ifdef CFG_ENABLE_USB
+      #define CFG_USB_STRING_MANUFACTURER   "microBuilder.eu"
+      #define CFG_USB_STRING_PRODUCT        "RF1GHZNODE"
+      #define CFG_USB_VENDORID              (0x1FC9)
+
+      #define CFG_USB_CDC
+
+      // #define CFG_USB_HID_KEYBOARD
+      // #define CFG_USB_HID_MOUSE
+      // #define CFG_USB_HID_GENERIC
+      // #define CFG_USB_HID_GENERIC_REPORT_SIZE (64)
+
+      // #define CFG_USB_MSC
+
+      // #define CFG_USB_CUSTOM_CLASS
+
+      #if (defined(CFG_USB_CDC)       || defined(CFG_USB_HID_KEYBOARD) || \
+           defined(CFG_USB_HID_MOUSE) || defined(CFG_USB_HID_GENERIC)  || \
+           defined(CFG_USB_MSC)       || defined(CFG_USB_CUSTOM_CLASS))
+        #define CFG_USB
+        #if defined(CFG_USB_HID_KEYBOARD) || defined(CFG_USB_HID_MOUSE) || defined(CFG_USB_HID_GENERIC)
+          #define CFG_USB_HID
+          #if defined(CFG_USB_HID_GENERIC) && (CFG_USB_HID_GENERIC_REPORT_SIZE > 64)
+            #error "CFG_USB_HID_GENERIC_REPORT_SIZE exceeds the maximum value of 64 bytes (based on USB specs 2.0 for 'Full Speed Interrupt Endpoint Size')"
+          #endif
+        #endif
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    CONFIG FILE VALIDATION
+
+    Basic error checking to make sure that incompatible defines are not
+    enabled at the same time, etc.
+
+    -----------------------------------------------------------------------*/
+    #if defined(CFG_INTERFACE) && !( defined CFG_PRINTF_UART || defined CFG_PRINTF_USBCDC || defined CFG_PRINTF_DEBUG)
+      #error "At least one CFG_PRINTF target must be defined with CFG_INTERFACE"
+    #endif
+
+    #if defined(CFG_PRINTF_UART) && !defined(CFG_ENABLE_UART)
+      #error "CFG_ENABLE_UART must be enabled with CFG_PRINTF_UART"
+    #endif
+
+    #if defined(CFG_PRINTF_USBCDC) && !defined(CFG_USB_CDC)
+      #error "CFG_USB_CDC must be defined with CFG_PRINTF_USBCDC"
+    #endif
+
+    #if defined(CFG_USB_MSC) && !defined(CFG_SDCARD)
+      #error "CFG_USB_MSC must be defined with CFG_SDCARD"
+    #endif
+
+    #if defined(CFG_PROTOCOL)
+      #if defined(CFG_PROTOCOL_VIA_HID) && !defined(CFG_USB_HID_GENERIC)
+        #error "CFG_PROTOCOL_VIA_HID requires CFG_USB_HID_GENERIC"
+      #endif
+
+      #if defined(CFG_PROTOCOL_VIA_BULK) && !defined(CFG_USB_CUSTOM_CLASS)
+        #error "CFG_PROTOCOL_VIA_BULK requires CFG_USB_CUSTOM_CLASS to be defined"
+      #endif
+    #endif
+/*=========================================================================*/
+
+void     boardSetVREG3V3 ( void );
+void     boardSetVREG2V2 ( void );
+uint32_t boardGetVIN ( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/boards/rf1ghznode/board_rf1ghznode_rtxconf.h b/reform2-lpc-fw/src/boards/rf1ghznode/board_rf1ghznode_rtxconf.h
new file mode 100644
index 0000000000000000000000000000000000000000..c4480d637db666134acf81b24b90e5d28854e959
--- /dev/null
+++ b/reform2-lpc-fw/src/boards/rf1ghznode/board_rf1ghznode_rtxconf.h
@@ -0,0 +1,213 @@
+/*----------------------------------------------------------------------------
+ *      RL-ARM - RTX
+ *----------------------------------------------------------------------------
+ *      Name:    board_lpcxpresso1347_rtxconf.h
+ *      Purpose: Configuration of CMSIS RTX Kernel for Cortex-M
+ *      Rev.:    V4.70
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of ARM  nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *---------------------------------------------------------------------------*/
+
+#include "projectconfig.h"
+
+#if defined CFG_BRD_RF1GHZNODE
+#include "cmsis_os.h"
+
+/*----------------------------------------------------------------------------
+ *      RTX User configuration part BEGIN
+ *---------------------------------------------------------------------------*/
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
+//
+// <h>Thread Configuration
+// =======================
+//
+//   <o>Number of concurrent running threads <0-250>
+//   <i> Defines max. number of threads that will run at the same time.
+//   <i> Default: 6
+#ifndef OS_TASKCNT
+ #define OS_TASKCNT     3
+#endif
+
+//   <o>Default Thread stack size [bytes] <64-4096:8><#/4>
+//   <i> Defines default stack size for threads with osThreadDef stacksz = 0
+//   <i> Default: 200
+#ifndef OS_STKSIZE
+ #define OS_STKSIZE     150
+#endif
+
+//   <o>Main Thread stack size [bytes] <64-4096:8><#/4>
+//   <i> Defines stack size for main thread.
+//   <i> Default: 200
+#ifndef OS_MAINSTKSIZE
+ #define OS_MAINSTKSIZE 200
+#endif
+
+//   <o>Number of threads with user-provided stack size <0-250>
+//   <i> Defines the number of threads with user-provided stack size.
+//   <i> Default: 0
+#ifndef OS_PRIVCNT
+ #define OS_PRIVCNT     0
+#endif
+
+//   <o>Total stack size [bytes] for threads with user-provided stack size <0-4096:8><#/4>
+//   <i> Defines the combined stack size for threads with user-provided stack size.
+//   <i> Default: 0
+#ifndef OS_PRIVSTKSIZE
+ #define OS_PRIVSTKSIZE 0
+#endif
+
+// <q>Check for stack overflow
+// <i> Includes the stack checking code for stack overflow.
+// <i> Note that additional code reduces the Kernel performance.
+#ifndef OS_STKCHECK
+ #define OS_STKCHECK    1
+#endif
+
+// <o>Processor mode for thread execution
+//   <0=> Unprivileged mode
+//   <1=> Privileged mode
+// <i> Default: Privileged mode
+#ifndef OS_RUNPRIV
+ #define OS_RUNPRIV     1
+#endif
+
+// </h>
+
+// <h>RTX Kernel Timer Tick Configuration
+// ======================================
+// <q> Use Cortex-M SysTick timer as RTX Kernel Timer
+// <i> Use the Cortex-M SysTick timer as a time-base for RTX.
+#ifndef OS_SYSTICK
+ #define OS_SYSTICK     1
+#endif
+//
+//   <o>Timer clock value [Hz] <1-1000000000>
+//   <i> Defines the timer clock value.
+//   <i> Default: 12000000  (12MHz)
+#ifndef OS_CLOCK
+ #define OS_CLOCK       48000000
+#endif
+
+//   <o>Timer tick value [us] <1-1000000>
+//   <i> Defines the timer tick value.
+//   <i> Default: 1000  (1ms)
+#ifndef OS_TICK
+ #define OS_TICK        1000
+#endif
+
+// </h>
+
+// <h>System Configuration
+// =======================
+//
+// <e>Round-Robin Thread switching
+// ===============================
+//
+// <i> Enables Round-Robin Thread switching.
+#ifndef OS_ROBIN
+ #define OS_ROBIN       1
+#endif
+
+//   <o>Round-Robin Timeout [ticks] <1-1000>
+//   <i> Defines how long a thread will execute before a thread switch.
+//   <i> Default: 5
+#ifndef OS_ROBINTOUT
+ #define OS_ROBINTOUT   5
+#endif
+
+// </e>
+
+// <e>User Timers
+// ==============
+//   <i> Enables user Timers
+#ifndef OS_TIMERS
+ #define OS_TIMERS      0
+#endif
+
+//   <o>Timer Thread Priority
+//                        <1=> Low
+//     <2=> Below Normal  <3=> Normal  <4=> Above Normal
+//                        <5=> High
+//                        <6=> Realtime (highest)
+//   <i> Defines priority for Timer Thread
+//   <i> Default: High
+#ifndef OS_TIMERPRIO
+ #define OS_TIMERPRIO   5
+#endif
+
+//   <o>Timer Thread stack size [bytes] <64-4096:8><#/4>
+//   <i> Defines stack size for Timer thread.
+//   <i> Default: 200
+#ifndef OS_TIMERSTKSZ
+ #define OS_TIMERSTKSZ  50
+#endif
+
+//   <o>Timer Callback Queue size <1-32>
+//   <i> Number of concurrent active timer callback functions.
+//   <i> Default: 4
+#ifndef OS_TIMERCBQS
+ #define OS_TIMERCBQS   4
+#endif
+
+// </e>
+
+//   <o>ISR FIFO Queue size<4=>   4 entries  <8=>   8 entries
+//                         <12=> 12 entries  <16=> 16 entries
+//                         <24=> 24 entries  <32=> 32 entries
+//                         <48=> 48 entries  <64=> 64 entries
+//                         <96=> 96 entries
+//   <i> ISR functions store requests to this buffer,
+//   <i> when they are called from the interrupt handler.
+//   <i> Default: 16 entries
+#ifndef OS_FIFOSZ
+ #define OS_FIFOSZ      16
+#endif
+
+// </h>
+
+//------------- <<< end of configuration section >>> -----------------------
+
+// Standard library system mutexes
+// ===============================
+//  Define max. number system mutexes that are used to protect
+//  the arm standard runtime library. For microlib they are not used.
+#ifndef OS_MUTEXCNT
+ #define OS_MUTEXCNT    8
+#endif
+
+/*----------------------------------------------------------------------------
+ *      RTX User configuration part END
+ *---------------------------------------------------------------------------*/
+
+#define OS_TRV          ((uint32_t)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1)
+
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+#endif
diff --git a/reform2-lpc-fw/src/boards/rf1ghzusb/board_rf1ghzusb.c b/reform2-lpc-fw/src/boards/rf1ghzusb/board_rf1ghzusb.c
new file mode 100644
index 0000000000000000000000000000000000000000..4ce5d6e7a0e5513ac5a3049c9b8cc7c626bbd41a
--- /dev/null
+++ b/reform2-lpc-fw/src/boards/rf1ghzusb/board_rf1ghzusb.c
@@ -0,0 +1,302 @@
+/**************************************************************************/
+/*!
+    @file     board_rf1ghzusb.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section DESCRIPTION
+
+    @brief    Board-specific files for the microBuilder LPC1347
+              AT86RF212 USB stick
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#if defined CFG_BRD_RF1GHZUSB
+
+#include "boards/board.h"
+#include "core/gpio/gpio.h"
+#include "core/delay/delay.h"
+#include "core/eeprom/eeprom.h"
+#include "core/pmu/pmu.h"
+
+#ifdef CFG_CHIBI
+  #include "drivers/rf/802.15.4/chibi/chb.h"
+  #include "drivers/rf/802.15.4/chibi/chb_drvr.h"
+  #include "drivers/rf/802.15.4/chibi/messages.h"
+  static chb_rx_data_t rx_data;
+#endif
+
+#ifdef CFG_USB
+  #include "core/usb/usbd.h"
+  #ifdef CFG_USB_CDC
+    #include "core/usb/usb_cdc.h"
+  #endif
+#endif
+
+#ifdef CFG_INTERFACE
+  #include "cli/cli.h"
+#endif
+
+#ifdef CFG_ENABLE_UART
+  #include "core/uart/uart.h"
+#endif
+
+#ifdef CFG_SDCARD
+/**************************************************************************/
+/*!
+    Handles timestamp requests for SD cards (adjust depending on if you
+    want to use the RTC, or just return 0, etc.)
+*/
+/**************************************************************************/
+DWORD get_fattime ()
+{
+  DWORD tmr = 0;
+
+  // tmr =  (((DWORD)rtcYear - 80) << 25)
+  //      | ((DWORD)rtcMon << 21)
+  //      | ((DWORD)rtcMday << 16)
+  //      | (WORD)(rtcHour << 11)
+  //      | (WORD)(rtcMin << 5)
+  //      | (WORD)(rtcSec >> 1);
+
+  return tmr;
+}
+#endif
+
+#ifdef CFG_CHIBI
+/**************************************************************************/
+/*!
+    Converts the ED (Energy Detection) value to dBm using the following
+    formula: dBm = RSSI_BASE_VAL + 1.03 * ED
+
+    For more information see section 6.5 of the AT86RF212 datasheet
+*/
+/**************************************************************************/
+int edToDBM(uint32_t ed)
+{
+  #if CFG_CHIBI_MODE == 0 || CFG_CHIBI_MODE == 1 || CFG_CHIBI_MODE == 2
+    // Calculate for OQPSK (RSSI Base Value = -100)
+    int dbm = (103 * ed - 10000);
+  #else
+    // Calculate for BPSK (RSSI Base Value = -98)
+    int dbm = (103 * ed - 9800);
+  #endif
+
+  return dbm / 100;
+}
+
+void sendMessage(void)
+{
+  uint8_t msgbuf[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+  if(msgSend(0xFFFF, MSG_MESSAGETYPE_NONE, msgbuf, 10))
+  {
+    printf("Message TX failure%s", CFG_PRINTF_NEWLINE);
+  }
+}
+
+void checkForMessages(void)
+{
+  chb_pcb_t *pcb = chb_get_pcb();
+
+  while (pcb->data_rcv)
+  {
+    // Enable LED to indicate message reception
+    boardLED(CFG_LED_ON);
+    // get the length of the data
+    rx_data.len = chb_read(&rx_data);
+    // make sure the length is nonzero
+    if (rx_data.len)
+    {
+      uint8_t msgType = rx_data.data[2];
+      sensors_event_t *event;
+      int dbm = edToDBM(pcb->ed);
+      /* Handle the message based on the msgType */
+      switch(msgType)
+      {
+        case (MSG_MESSAGETYPE_SENSOREVENT):
+          event = (sensors_event_t*)&rx_data.data[9];
+          printf("%04X,%d,", rx_data.src_addr, event->timestamp);
+          printf("%f,%f,%f%s", event->acceleration.x, event->acceleration.y, event->acceleration.z, CFG_PRINTF_NEWLINE);
+          break;
+        default:
+          printf("Message received from node 0x%04X (len=%d, dBm=%d):%s", rx_data.src_addr, rx_data.len, dbm, CFG_PRINTF_NEWLINE);
+          printf("  Message ID:   0x%04X%s", *(uint16_t*)&rx_data.data[0], CFG_PRINTF_NEWLINE);
+          printf("  Message Type: 0x%02X%s", *(uint8_t*)&rx_data.data[2], CFG_PRINTF_NEWLINE);
+          printf("  Timestamp:    %d%s", *(uint32_t*)&rx_data.data[3], CFG_PRINTF_NEWLINE);
+          printf("  Payload:      %d bytes%s", *(uint8_t*)&rx_data.data[8], CFG_PRINTF_NEWLINE);
+          if (rx_data.data[8])
+          {
+            uint8_t i;
+            printf("%s", CFG_PRINTF_NEWLINE);
+            for (i = 0; i < rx_data.data[8]; i++)
+            {
+              printf("0x%02X ", *(uint8_t*)&rx_data.data[9+i]);
+            }
+          }
+          printf("%s", CFG_PRINTF_NEWLINE);
+          break;
+      }
+    }
+    // Disable LED
+    boardLED(CFG_LED_OFF);
+  }
+}
+#endif
+
+/**************************************************************************/
+/*!
+    @brief Board-specific initialisation function
+*/
+/**************************************************************************/
+void boardInit(void)
+{
+  SystemCoreClockUpdate();
+  delayInit();
+  GPIOInit();
+
+  #ifdef CFG_PRINTF_UART
+    uartInit(CFG_UART_BAUDRATE);
+  #endif
+
+  /* Set user LED pin to output and disable it */
+  LPC_GPIO->DIR[CFG_LED_PORT] |= (1 << CFG_LED_PIN);
+  boardLED(CFG_LED_OFF);
+
+  /* Start Chibi */
+  #ifdef CFG_CHIBI
+    /* Set IRQ to GPIO and set ADMODE to digital*/
+    LPC_IOCON->TMS_PIO0_12    = (1<<0) | (2<<3) | (1<<7);
+    /* Set RST to GPIO and set ADMODE to digital*/
+    LPC_IOCON->TDO_PIO0_13    = (1<<0) | (0<<3) | (1<<7);
+    /* Enable pull-up on SLPTR, and set ADMODE to digital*/
+    LPC_IOCON->TRST_PIO0_14   = (1<<0) | (2<<3) | (1<<7);
+    /* You may need to write a new address to EEPROM if it doesn't exist */
+    // uint16_t nodeaddr = 0xCAFE;
+    // uint64_t ieeeaddr = 0x123456780000CAFE;
+    // writeEEPROM((uint8_t*)CFG_EEPROM_CHIBI_NODEADDR, (uint8_t*)&nodeaddr, sizeof(nodeaddr));
+    // writeEEPROM((uint8_t*)CFG_EEPROM_CHIBI_IEEEADDR, (uint8_t*)&ieeeaddr, sizeof(ieeeaddr));
+    if (chb_init())
+    {
+      // printf("Chibi init failed%s", CFG_PRINTF_NEWLINE);
+    }
+  #endif
+
+  /* Initialise USB */
+  #ifdef CFG_USB
+    delay(500);
+    usb_init();
+  #endif
+
+  /* Start the command line interface */
+  #ifdef CFG_INTERFACE
+    cliInit();
+  #endif
+}
+
+/**************************************************************************/
+/*!
+    @brief Primary entry point for this project.
+*/
+/**************************************************************************/
+#if !defined(_TEST_)
+int main(void)
+{
+  uint32_t currentSecond, lastSecond;
+  currentSecond = lastSecond = 0;
+
+  boardInit();
+
+  while (1)
+  {
+    currentSecond = delayGetSecondsActive();
+    if (currentSecond != lastSecond)
+    {
+      lastSecond = currentSecond;
+
+      /* Send a message over the air */
+      #ifdef CFG_CHIBI
+        // sendMessage();
+      #endif
+    }
+
+    /* Poll for CLI input if CFG_INTERFACE is enabled */
+    #ifdef CFG_INTERFACE
+      cliPoll();
+    #endif
+
+    /* Check for incoming wireless messages */
+    #ifdef CFG_CHIBI
+      checkForMessages();
+    #endif
+  }
+}
+#endif
+
+/**************************************************************************/
+/*!
+    @brief Turns the LED(s) on or off
+*/
+/**************************************************************************/
+void boardLED(uint8_t state)
+{
+  if (state)
+  {
+    LPC_GPIO->SET[CFG_LED_PORT] = (1 << CFG_LED_PIN);
+  }
+  else
+  {
+    LPC_GPIO->CLR[CFG_LED_PORT] = (1 << CFG_LED_PIN);
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Configure the board for low power and enter sleep mode
+*/
+/**************************************************************************/
+void boardSleep(void)
+{
+  /* ToDo */
+}
+
+/**************************************************************************/
+/*!
+    @brief  Restores parts and system peripherals to an appropriate
+            state after waking up from sleep mode
+*/
+/**************************************************************************/
+void boardWakeup(void)
+{
+  /* ToDo */
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/boards/rf1ghzusb/board_rf1ghzusb.h b/reform2-lpc-fw/src/boards/rf1ghzusb/board_rf1ghzusb.h
new file mode 100644
index 0000000000000000000000000000000000000000..deab406b9b8ed02ff11272cd609ce843582d57c7
--- /dev/null
+++ b/reform2-lpc-fw/src/boards/rf1ghzusb/board_rf1ghzusb.h
@@ -0,0 +1,711 @@
+/**************************************************************************/
+/*!
+    @file     board_rf1ghzusb.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Board-specific files for the microBuilder LPC1347
+              AT86RF212 USB stick
+    @ingroup  Boards
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013 K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __BOARD_RF1GHZUSB_H__
+#define __BOARD_RF1GHZUSB_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sysdefs.h"
+
+/*=========================================================================
+    MCU SELECTION
+
+    Include one of the following definitions depending on if you are
+    using the LPC11U37 or LPC1347.  They're generally interchangeable, but
+    the LPC11Uxx and LPC13xx CMSIS implementations have some differences
+    in naming convention, and occasionally a feature is only available on
+    the M3 (DWT for example).  Selecting the appropriate MCU allows
+    the right code to be included when differences between the CMSIS
+    implementations are present.
+
+    -----------------------------------------------------------------------*/
+    // #define CFG_MCU_LPC11U24FBD48_401
+    // #define CFG_MCU_LPC11U37FBD48_401
+    // #define CFG_MCU_LPC1347FBD48
+    #define CFG_MCU_LPC1347FHN33
+
+    /* Basic error checking */
+    #if !defined CFG_MCU_LPC1347FBD48 && \
+        !defined CFG_MCU_LPC11U37FBD48_401 && \
+        !defined CFG_MCU_LPC11U24FBD48_401 && \
+        !defined CFG_MCU_LPC1347FHN33
+      #error "An MCU must be selected in projectconfig.h (Ex. CFG_MCU_LPC11U37FBD48_401, CFG_MCU_LPC1347FBD48, etc.)"
+    #endif
+
+    /* Set flag to indicate which CMSIS library to use */
+    #if (defined CFG_MCU_LPC1347FBD48 || defined CFG_MCU_LPC1347FHN33)
+      #define CFG_MCU_FAMILY_LPC13UXX
+    #elif (defined CFG_MCU_LPC11U24FBD48_401 || defined CFG_MCU_LPC11U37FBD48_401)
+      #define CFG_MCU_FAMILY_LPC11UXX
+    #endif
+
+    /* Include the correct MCU header file */
+    #if defined CFG_MCU_FAMILY_LPC13UXX
+      #include "LPC13Uxx.h"
+    #endif
+    #if defined CFG_MCU_FAMILY_LPC11UXX
+      #include "LPC11Uxx.h"
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    FIRMWARE VERSION SETTINGS
+    -----------------------------------------------------------------------*/
+    #define CFG_FIRMWARE_VERSION_MAJOR      (0)
+    #define CFG_FIRMWARE_VERSION_MINOR      (0)
+    #define CFG_FIRMWARE_VERSION_REVISION   (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PIN USAGE
+    -----------------------------------------------------------------------
+    This table tries to give an indication of which GPIO pins and
+    peripherals are used by the available drivers and SW examples.  Only
+    dedicated GPIO pins available on the LPC1347 Reference Board are shown
+    below.  Any unused peripheral blocks like I2C, SSP, ADC, etc., can
+    also be used as GPIO if they are available.
+
+                PORT 0
+                =========================================================
+                0 1 2 3 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
+
+    HX8340B     . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    HX8347G     . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    CHIBI       . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    SSD1306 I2C . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    FAT32/MMC   . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  X  .  .
+    PN532 I2C   . . . . . . . .  .  .  .  .  .  .  X  X  .  .  .  .  .  .
+    PCF2129A    . . . . . . . .  .  .  .  .  .  .  X  X  .  .  .  .  .  .
+
+                PORT 1
+                ===========================================================================
+                0 1 2 3 4 5 7 8 10 11 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 31
+                + + + + + + + +  +  +              +  +                                   -
+
+    HX8340B     . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  X  X  X  X  X  .
+    HX8347G     . . . . . . . .  .  .  X  X  X  X  .  .  X  X  X  X  X  X  X  X  X  X  .  .
+    CHIBI       . . . . . . . .  .  .  X  X  X  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    SSD1306 I2C . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    FAT32/MMC   . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  X  X  .  .  .  .  .  .
+    PN532 I2C   . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+    PCF2129A    . . . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+
+                TIMERS                   SSP   ADC               UART
+                ======================   ===   ===============   ====
+                16B0  16B1  32B0  32B1   0 1   0 1 2 3 4 5 6 7   0
+
+    HX8340B     .      .    .     .      . .   . . . . . . . .   .
+    HX8347G     .      .    .     .      . .   . . . . . . . .   .
+    CHIBI       .      .    .     .      X .   . . . . . . . .   .
+    SSD1306 I2C .      .    .     .      . .   . . . . . . . .   .
+    FAT32/MMC   .      .    .     .      . X   . . . . . . . .   .
+
+    [+]   Only available on QFP64 package
+    [-]   Only available on QFP48 package
+
+  =========================================================================*/
+
+
+/*=========================================================================
+    GPIO INTERRUPTS
+    -----------------------------------------------------------------------
+    This table shows where GPIO interrupts are mapped in this project
+    (Note that the LPC11U and LPC13U use different names for the
+    IRQ Handlers in the standard headers)
+
+    Interrupt                                     Location
+    ------------------------------------------    -------------------------
+    PIN_INT0_IRQHandler - FLEX_INT0_IRQHandler    chb_drvr.c
+    PIN_INT1_IRQHandler - FLEX_INT1_IRQHandler    pcf2129.c
+    PIN_INT2_IRQHandler - FLEX_INT2_IRQHandler
+    PIN_INT3_IRQHandler - FLEX_INT3_IRQHandler
+    PIN_INT4_IRQHandler - FLEX_INT4_IRQHandler
+    PIN_INT5_IRQHandler - FLEX_INT5_IRQHandler
+    PIN_INT6_IRQHandler - FLEX_INT6_IRQHandler
+    PIN_INT7_IRQHandler - FLEX_INT7_IRQHandler
+    GINT0_IRQHandler
+    GINT0_IRQHandler
+    -----------------------------------------------------------------------*/
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SUPPORTED PERIPHERALS
+    -----------------------------------------------------------------------
+    Because all ISRs are referenced in the startup code, GCC typically
+    won't optimise out the ISR functions during compilation even if the
+    ISRs will never be entered, resulting in larger binaries than required
+    (for example if no I2C sensors are used, be sure to disable I2C support
+    since the I2C ISR is quite large).
+
+    Use the defines below to include or exclude support for specific
+    peripherals.
+
+    NOTE: GPIO ISRs are handled seperately in GPIO INTERRUPTS below
+    -----------------------------------------------------------------------*/
+    #define CFG_ENABLE_I2C
+    #define CFG_ENABLE_UART
+    #define CFG_ENABLE_USB
+    #define CFG_ENABLE_TIMER32
+/*=========================================================================*/
+
+
+/*=========================================================================
+    EEPROM
+    -----------------------------------------------------------------------
+    EEPROM is used to persist certain user modifiable values to make
+    sure that these changes remain in effect after a reset or hard
+    power-down.  The addresses in EEPROM for these various system
+    settings/values are defined below.  The first 256 bytes of EEPROM
+    are reserved for this (0x0000..0x00FF).
+
+    CFG_EEPROM_SIZE           The number of bytes available on the EEPROM
+    CFG_EEPROM_RESERVED       The last byte of reserved EEPROM memory
+
+          EEPROM Address (0x0000..0x00FF)
+          ===============================
+          0 1 2 3 4 5 6 7 8 9 A B C D E F
+    000x  x x . . x x x x x x x x . . . .   Chibi
+    001x  . . . . . . . . . . . . . . . .
+    002x  . . . . . . . . . . . . . . . .
+    003x  . . . . . . . . . . . . . . . .
+    004x  . . . . . . . . . . . . . . . .
+    005x  . . . . . . . . . . . . . . . .
+    006x  . . . . . . . . . . . . . . . .
+    007x  . . . . . . . . . . . . . . . .
+    008x  . . . . . . . . . . . . . . . .
+    009x  . . . . . . . . . . . . . . . .
+    00Ax  . . . . . . . . . . . . . . . .
+    00Bx  . . . . . . . . . . . . . . . .
+    00Cx  . . . . . . . . . . . . . . . .
+    00Dx  . . . . . . . . . . . . . . . .
+    00Ex  . . . . . . . . . . . . . . . .
+    00Fx  . . . . . . . . . . . . . . . .
+
+    -----------------------------------------------------------------------*/
+    #define CFG_EEPROM_SIZE                   (4032)
+    #define CFG_EEPROM_RESERVED               (0x00FF)              // Protect first 256 bytes of memory
+    #define CFG_EEPROM_CHIBI_NODEADDR         (uint16_t)(0x0000)    // 2
+    #define CFG_EEPROM_CHIBI_IEEEADDR         (uint16_t)(0x0004)    // 8
+/*=========================================================================*/
+
+
+/*=========================================================================
+    ON-BOARD LED
+    -----------------------------------------------------------------------
+
+    CFG_LED_PORT              The port for the on board LED
+    CFG_LED_PIN               The pin for the on board LED
+    CFG_LED_ON                The pin state to turn the LED on (0 = low, 1 = high)
+    CFG_LED_OFF               The pin state to turn the LED off (0 = low, 1 = high)
+
+    -----------------------------------------------------------------------*/
+    #define CFG_LED_PORT                  (0)
+    #define CFG_LED_PIN                   (23)
+    #define CFG_LED_ON                    (0)
+    #define CFG_LED_OFF                   (1)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    ADC
+    -----------------------------------------------------------------------
+
+    CFG_ADC_MODE_LOWPOWER     If set to 1, this will configure the ADC
+                              for low-power operation (LPC1347 only)
+    CFG_ADC_MODE_10BIT        If set to 1, this will configure the ADC
+                              for 10-bit mode (LPC1347 only)
+
+    -----------------------------------------------------------------------*/
+    #define CFG_ADC_MODE_LOWPOWER       (0)
+    #define CFG_ADC_MODE_10BIT          (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    UART
+    -----------------------------------------------------------------------
+
+    CFG_UART_BAUDRATE         The default UART speed.  This value is used
+                              when initialising UART, and should be a
+                              standard value like 57600, 9600, etc.
+                              NOTE: This value may be overridden if
+                              another value is stored in EEPROM!
+    CFG_UART_BUFSIZE          The length in bytes of the UART RX FIFO. This
+                              will determine the maximum number of received
+                              characters to store in memory.
+
+    -----------------------------------------------------------------------*/
+    #define CFG_UART_BAUDRATE           (115200)
+    #define CFG_UART_BUFSIZE            (256)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SPI
+    -----------------------------------------------------------------------
+
+    CFG_SSP_SCK0_LOCATION     The location of the SCK pin for SSP0
+    CFG_SSP_MISO1_LOCATION    The location of the MISO1 pin for SSP1
+    CFG_SSP_MOSI1_LOCATION    The location of the MOSI1 pin for SSP1
+    CFG_SSP_SCK1_LOCATION     The location of the SCK pin for SSP1
+
+    -----------------------------------------------------------------------*/
+    #define CFG_SSP_SCK0_0_6            (6)     // Used by USBConnect
+    #define CFG_SSP_SCK0_0_10           (10)    // Used by SWD
+    #define CFG_SSP_SCK0_1_29           (29)
+
+    #define CFG_SSP_MISO1_0_22          (22)
+    #define CFG_SSP_MISO1_1_21          (21)
+    #define CFG_SSP_MOSI1_0_21          (21)
+    #define CFG_SSP_MOSI1_1_22          (22)
+    #define CFG_SSP_SCK1_1_15           (15)
+    #define CFG_SSP_SCK1_1_20           (20)
+
+    // Select the appropriate pin locations here
+    #define CFG_SSP_SCK0_LOCATION       (CFG_SSP_SCK0_1_29)
+    #define CFG_SSP_MISO1_LOCATION      (CFG_SSP_MISO1_0_22)
+    #define CFG_SSP_MOSI1_LOCATION      (CFG_SSP_MOSI1_0_21)
+    #define CFG_SSP_SCK1_LOCATION       (CFG_SSP_SCK1_1_15)
+
+    // Set the phase and polarity for SSP0 and SSP1
+    #define CFG_SSP_CPOL0               (0)
+    #define CFG_SSP_CPHA0               (0)
+    #define CFG_SSP_CPOL1               (0)
+    #define CFG_SSP_CPHA1               (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PRINTF REDIRECTION
+    -----------------------------------------------------------------------
+
+    CFG_PRINTF_MAXSTRINGSIZE  Maximum size of string buffer for printf
+    CFG_PRINTF_UART           Will cause all printf statements to be
+                              redirected to UART
+    CFG_PRINTF_USBCDC         Will cause all printf statements to be
+                              redirect to USB Serial
+    CFG_PRINTF_DEBUG          Use the debug interface for printf
+    CFG_PRINTF_NEWLINE        This is typically "\r\n" for Windows or
+                              "\n" for *nix
+
+    Note: If no printf redirection definitions are present, all printf
+    output will be ignored.
+    -----------------------------------------------------------------------*/
+    #define CFG_PRINTF_MAXSTRINGSIZE    (255)
+    // #define CFG_PRINTF_UART
+    #define CFG_PRINTF_USBCDC
+    // #define CFG_PRINTF_DEBUG
+
+    #ifdef CFG_PRINTF_DEBUG
+      #define CFG_PRINTF_NEWLINE          "\n"
+    #else
+      #define CFG_PRINTF_NEWLINE          "\r\n"
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    COMMAND LINE INTERFACE
+    -----------------------------------------------------------------------
+
+    CFG_INTERFACE             If this field is defined the UART or USBCDC
+                              based command-line interface will be included
+    CFG_INTERFACE_MAXMSGSIZE  The maximum number of bytes to accept for an
+                              incoming command
+    CFG_INTERFACE_PROMPT      The command prompt to display at the start
+                              of every new data entry line
+    CFG_INTERFACE_SILENTMODE  If this is set to 1 only text generated in
+                              response to commands will be send to the
+                              output buffer.  The command prompt will not
+                              be displayed and incoming text will not be
+                              echoed back to the output buffer (allowing
+                              you to see the text you have input).  This
+                              is normally only desirable in a situation
+                              where another MCU is communicating with
+                              the LPC1343.
+    CFG_INTERFACE_DROPCR      If this is set to 1 all incoming \r
+                              characters will be dropped
+    CFG_INTERFACE_ENABLEIRQ   If this is set to 1 the IRQ pin will be
+                              set high when a command starts executing
+                              and will go low when the command has
+                              finished executing or the LCD is not busy.
+                              This allows another device to know when a
+                              new command can safely be sent.
+    CFG_INTERFACE_IRQPORT     The gpio port for the IRQ/busy pin
+    CFG_INTERFACE_IRQPIN      The gpio pin number for the IRQ/busy pin
+    CFG_INTERFACE_SHORTERRORS If this is enabled only short 1 character
+                              error messages will be returned (followed
+                              by CFG_PRINTF_NEWLINE), rather than more
+                              verbose error messages.  The specific
+                              characters used are defined below.
+    CFG_INTERFACE_CONFIRMREADY  If this is set to 1 a text confirmation
+                              will be sent when the command prompt is
+                              ready for a new command.  This is in
+                              addition to CFG_INTERFACE_ENABLEIRQ if
+                              this is also enabled.  The character used
+                              is defined below.
+    CFG_INTERFACE_LONGSYSINFO If this is set to 1 extra information will
+                              be included in the Sys Info ('V') command
+                              on the CLI. This can be useful when trying
+                              to debug problems on remote HW, or with
+                              unknown firmware.  It will also use about
+                              0.5KB flash, though, so only enable it is
+                              necessary.
+
+    NOTE:                     The command-line interface will use either
+                              USB-CDC or UART depending on whether
+                              CFG_PRINTF_UART or CFG_PRINTF_USBCDC are
+                              selected.
+    -----------------------------------------------------------------------*/
+    #define CFG_INTERFACE
+    #define CFG_INTERFACE_MAXMSGSIZE    (256)
+    #define CFG_INTERFACE_PROMPT        "LPC1347 >> "
+    #define CFG_INTERFACE_SILENTMODE    (0)
+    #define CFG_INTERFACE_DROPCR        (0)
+    #define CFG_INTERFACE_ENABLEIRQ     (0)
+    #define CFG_INTERFACE_IRQPORT       (0)
+    #define CFG_INTERFACE_IRQPIN        (7)
+    #define CFG_INTERFACE_SHORTERRORS   (0)
+    #define CFG_INTERFACE_CONFIRMREADY  (0)
+    #define CFG_INTERFACE_LONGSYSINFO   (1)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SIMPLE BINARY PROTOCOL
+    -----------------------------------------------------------------------
+
+    CFG_PROTOCOL             If this field is defined the binary command
+                              parser will be included
+    -----------------------------------------------------------------------*/
+    // #define CFG_PROTOCOL
+
+    // #define CFG_PROTOCOL_VIA_HID
+    #define CFG_PROTOCOL_VIA_BULK
+
+    #if defined(CFG_PROTOCOL) && !defined(CFG_PROTOCOL_VIA_HID) && !defined(CFG_PROTOCOL_VIA_BULK)
+        #error CFG_PROTOCOL must be enabled with either CFG_PROTOCOL_VIA_HID or CFG_PROTOCOL_VIA_BULK
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    TFT LCD
+    -----------------------------------------------------------------------
+
+    CFG_TFTLCD                  If defined, this will cause drivers for
+                                a pre-determined LCD screen to be included
+                                during build.  Only one LCD driver can be
+                                included during the build process (for ex.
+                                'drivers/displays/hw/ILI9325.c')
+    CFG_TFTLCD_INCLUDESMALLFONTS If set to 1, smallfont support will be
+                                included for 3x6, 5x8, 7x8 and 8x8 fonts.
+                                This should only be enabled if these small
+                                fonts are required since there is already
+                                support for larger fonts generated with
+                                Dot Factory
+                                http://www.pavius.net/downloads/tools/53-the-dot-factory
+    CFG_TFTLCD_USEAAFONTS       If set to a non-zero value, anti-aliased
+                                fonts will be used instead of regular 1-bit
+                                font.  These result in much higher-
+                                quality text, but the fonts are 2 or 4
+                                times larger than plain bitmap fonts and
+                                take a bit more rendering time to display.
+    CFG_TFTLCD_TS_DEFAULTTHRESHOLD  Default minimum threshold to trigger a
+                                touch event with the touch screen (and exit
+                                from 'tsWaitForEvent' in touchscreen.c).
+                                Should be an 8-bit value somewhere between
+                                8 and 75 in normal circumstances.  This is
+                                the default value and may be overriden by
+                                a value stored in EEPROM.
+    CFG_TFTLCD_TS_KEYPADDELAY   The delay in milliseconds between key
+                                presses in dialogue boxes
+   -----------------------------------------------------------------------*/
+    // #define CFG_TFTLCD
+    #define CFG_TFTLCD_INCLUDESMALLFONTS   (1)
+    #define CFG_TFTLCD_USEAAFONTS          (0)
+    #define CFG_TFTLCD_TS_DEFAULTTHRESHOLD (50)
+    #define CFG_TFTLCD_TS_KEYPADDELAY      (100)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    MICRO-SD CARD
+    -----------------------------------------------------------------------
+
+    CFG_SDCARD                If this field is defined SD Card and FAT32
+                              file system support will be included
+    CFG_SDCARD_SPIPORT        SSP Port used for the SD card (0 or 1)
+    CFG_SDCARD_READONLY       If this is set to 1, all commands to
+                              write to the SD card will be removed
+                              saving some flash space.
+    CFG_SDCARD_CDPORT         The card detect port number
+    CFG_SDCARD_CDPIN          The card detect pin number
+
+    NOTE:                     All config settings for FAT32 are defined
+                              in ffconf.h
+    -----------------------------------------------------------------------*/
+    // #define CFG_SDCARD
+    #define CFG_SDCARD_READONLY         (0)   // Must be 0 or 1
+    #define CFG_SDCARD_SPIPORT          (0)
+    #define CFG_SDCARD_SSELPORT         (0)
+    #define CFG_SDCARD_SSELPIN          (0)
+    #define CFG_SDCARD_CDPORT           (0)
+    #define CFG_SDCARD_CDPIN            (0)
+    #define CFG_SDCARD_ENBLPORT         (0)
+    #define CFG_SDCARD_ENBLPIN          (0)
+
+    #ifdef CFG_SDCARD
+      #if !((CFG_SDCARD_READONLY == 0) || (CFG_SDCARD_READONLY == 1))
+        #error "Invalid value for CFG_SDCARD_READONLY"
+      #endif
+      #if !((CFG_SDCARD_SPIPORT == 0) || (CFG_SDCARD_SPIPORT == 1))
+        #error "Invalid SPI port for CFG_SDCARD_SPIPORT"
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    CHIBI WIRELESS STACK
+    -----------------------------------------------------------------------
+
+    CFG_CHIBI                   If defined, the CHIBI wireless stack will be
+                                included during build.  Requires external HW.
+    CFG_CHIBI_MODE              The mode to use when receiving and transmitting
+                                wireless data.  See chb_drvr.h for possible values
+    CFG_CHIBI_POWER             The power level to use when transmitting.  See
+                                chb_drvr.h for possible values
+    CFG_CHIBI_CHANNEL           802.15.4 Channel (0 = 868MHz, 1-10 = 915MHz)
+    CFG_CHIBI_PANID             16-bit PAN Identifier (ex.0x1234)
+    CFG_CHIBI_PROMISCUOUS       Set to 1 to enabled promiscuous mode or
+                                0 to disable it.  If promiscuous mode is
+                                enabled be sure to set CFG_CHIBI_BUFFERSIZE
+                                to an appropriately large value (ex. 1024)
+    CFG_CHIBI_BUFFERSIZE        The size of the message buffer in bytes
+    -----------------------------------------------------------------------*/
+    #define CFG_CHIBI
+    #define CFG_CHIBI_MODE              (0)                 // OQPSK_868MHZ
+    #define CFG_CHIBI_POWER             (0xE9)              // CHB_PWR_EU2_3DBM
+    #define CFG_CHIBI_CHANNEL           (0)                 // 0 = 868-868.6 MHz, 1 = 906MHz
+    #define CFG_CHIBI_PANID             (0x1234)
+    #define CFG_CHIBI_PROMISCUOUS       (0)
+    #define CFG_CHIBI_BUFFERSIZE        (256)
+
+    // Pin config settings
+    #define CFG_CHIBI_SPIPORT           (1)  // Must be 0 or 1
+    #define CFG_CHIBI_SSPORT            (1)
+    #define CFG_CHIBI_SSPIN             (19)
+    #define CFG_CHIBI_EINTPORT          (0)
+    #define CFG_CHIBI_EINTPIN           (12)
+    #define CFG_CHIBI_RSTPORT           (0)
+    #define CFG_CHIBI_RSTPIN            (13)
+    #define CFG_CHIBI_SLPTRPORT         (0)
+    #define CFG_CHIBI_SLPTRPIN          (14)
+    #define CFG_CHIBI_CC1190_HGM_PORT   (0)   // Not used
+    #define CFG_CHIBI_CC1190_HGM_PIN    (0)   // Not used
+
+    #ifdef CFG_CHIBI
+      #if !((CFG_CHIBI_SPIPORT == 0) || (CFG_CHIBI_SPIPORT == 1))
+        #error "Invalid SPI port for CFG_CHIBI_SPIPORT"
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PN532/NFC STACK
+    -----------------------------------------------------------------------
+
+    CFG_PN532                      If defined, the PN532/NFC stack will be
+                                   included during build.  Requires
+                                   external HW
+    CFG_PN532_MEM_POOL_SIZE_BYTES  Size of the dynamic memory pool in bytes
+                                   (used by pn532/mem_allocator/ when
+                                   working with NDEF messages)
+    -----------------------------------------------------------------------*/
+    // #define CFG_PN532
+    #define CFG_PN532_RSTPD_PORT                      (0)
+    #define CFG_PN532_RSTPD_PIN                       (16)
+    #define CFG_PN532_I2C_IRQPORT                     (0)
+    #define CFG_PN532_I2C_IRQPIN                      (17)
+    #define CFG_PN532_MEM_POOL_SIZE_BYTES             (512)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    RTC SUPPORT
+    -----------------------------------------------------------------------
+
+    CFG_RTC                     If defined, RTC support will be included.
+                                Requires external HW.
+    -----------------------------------------------------------------------*/
+    // #define CFG_RTC
+
+    #if defined(CFG_RTC) && !defined(CFG_ENABLE_I2C)
+      #error "CFG_ENABLE_I2C must be defined with CFG_RTC"
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    STEPPER MOTOR SUPPORT
+    -----------------------------------------------------------------------
+
+    CFG_STEPPER                 If defined, basic stepper motor support
+                                will be included.  Requires external HW.
+    -----------------------------------------------------------------------*/
+    // #define CFG_STEPPER
+    #define CFG_STEPPER_TIMER32                       (0)
+    #define CFG_STEPPER_IN1_PORT                      (0)
+    #define CFG_STEPPER_IN1_PIN                       (8)
+    #define CFG_STEPPER_IN2_PORT                      (0)
+    #define CFG_STEPPER_IN2_PIN                       (9)
+    #define CFG_STEPPER_IN3_PORT                      (0)
+    #define CFG_STEPPER_IN3_PIN                       (14)
+    #define CFG_STEPPER_IN4_PORT                      (0)
+    #define CFG_STEPPER_IN4_PIN                       (13)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    USB
+
+    CFG_USB_STRING_MANUFACTURER Manufacturer name that will appear in the
+                                device descriptor during USB enumeration
+    CFG_USB_STRING_PRODUCT      Product name that will appear in the
+                                device descriptor during USB enumeration
+    CFG_USB_VENDORID            16-bit USB vendor ID
+    USB_PRODUCT_ID              Define this to set a custom product ID
+                                if you do not wish to use the 'auto'
+                                product ID feature
+    CFG_CDC                     Enable USB CDC support
+    CFG_USB_HID_KEYBOARD        Enable USB HID keyboard emulation
+    CFG_USB_HID_MOUSE           Enable USB HID mouse emulation for a five
+                                button 'Windows' mouse with scroll wheels
+    CFG_USB_HID_GENERIC         Enable USB HID Generic support for custom
+                                in and out reports, with report size set
+                                via CFG_USB_HID_GENERIC_REPORT_SIZE
+    CFG_USB_MSC                 Enable USB Mass Storage support, pointing
+                                to the SD card reader (requires mmc.c from
+                                the FATFS drivers, but doesn't use FATFS)
+
+    You can combine more than one USB class below and they will be
+    automatically combined in a USB composite device within the limit of
+    available USB endpoints.  The USB Product ID is calculated automatically
+    based on the combination of classes defined below.
+
+    NOTE: Windows requires the .inf file in '/core/usb' for CDC support
+    -----------------------------------------------------------------------*/
+    #ifdef CFG_ENABLE_USB
+      #define CFG_USB_STRING_MANUFACTURER       "microBuilder.eu"
+      #define CFG_USB_STRING_PRODUCT            "RF1GHZUSB"
+      #define CFG_USB_VENDORID                  (0x1FC9)
+
+      #define CFG_USB_CDC
+
+      // #define CFG_USB_HID_KEYBOARD
+      // #define CFG_USB_HID_MOUSE
+      // #define CFG_USB_HID_GENERIC
+      // #define CFG_USB_HID_GENERIC_REPORT_SIZE (64)
+
+      // #define CFG_USB_MSC
+
+      // #define CFG_USB_CUSTOM_CLASS
+
+      #if (defined(CFG_USB_CDC)       || defined(CFG_USB_HID_KEYBOARD) || \
+           defined(CFG_USB_HID_MOUSE) || defined(CFG_USB_HID_GENERIC)  || \
+           defined(CFG_USB_MSC)       || defined(CFG_USB_CUSTOM_CLASS))
+        #define CFG_USB
+        #if defined(CFG_USB_HID_KEYBOARD) || defined(CFG_USB_HID_MOUSE) || defined(CFG_USB_HID_GENERIC)
+          #define CFG_USB_HID
+          #if defined(CFG_USB_HID_GENERIC) && (CFG_USB_HID_GENERIC_REPORT_SIZE > 64)
+            #error "CFG_USB_HID_GENERIC_REPORT_SIZE exceeds the maximum value of 64 bytes (based on USB specs 2.0 for 'Full Speed Interrupt Endpoint Size')"
+          #endif
+        #endif
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    CONFIG FILE VALIDATION
+
+    Basic error checking to make sure that incompatible defines are not
+    enabled at the same time, etc.
+
+    -----------------------------------------------------------------------*/
+    #if defined(CFG_INTERFACE) && !( defined CFG_PRINTF_UART || defined CFG_PRINTF_USBCDC || defined CFG_PRINTF_DEBUG)
+      #error "At least one CFG_PRINTF target must be defined with CFG_INTERFACE"
+    #endif
+
+    #if defined(CFG_PRINTF_UART) && !defined(CFG_ENABLE_UART)
+      #error "CFG_ENABLE_UART must be enabled with CFG_PRINTF_UART"
+    #endif
+
+    #if defined(CFG_PRINTF_USBCDC) && !defined(CFG_USB_CDC)
+      #error "CFG_USB_CDC must be defined with CFG_PRINTF_USBCDC"
+    #endif
+
+    #if defined(CFG_USB_MSC) && !defined(CFG_SDCARD)
+      #error "CFG_USB_MSC must be defined with CFG_SDCARD"
+    #endif
+
+    #if defined(CFG_PROTOCOL)
+      #if defined(CFG_PROTOCOL_VIA_HID) && !defined(CFG_USB_HID_GENERIC)
+        #error "CFG_PROTOCOL_VIA_HID requires CFG_USB_HID_GENERIC"
+      #endif
+
+      #if defined(CFG_PROTOCOL_VIA_BULK) && !defined(CFG_USB_CUSTOM_CLASS)
+        #error "CFG_PROTOCOL_VIA_BULK requires CFG_USB_CUSTOM_CLASS to be defined"
+      #endif
+    #endif
+/*=========================================================================*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/boards/simulator/board_simulator.c b/reform2-lpc-fw/src/boards/simulator/board_simulator.c
new file mode 100644
index 0000000000000000000000000000000000000000..c2fb7daf3399f5464fc6cbf4a8c6774fa93b64e8
--- /dev/null
+++ b/reform2-lpc-fw/src/boards/simulator/board_simulator.c
@@ -0,0 +1,105 @@
+/**************************************************************************/
+/*!
+    @file     board_simulator.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section DESCRIPTION
+
+    Common, board-specific files for simulators in Crossworks, etc.
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#if defined CFG_BRD_SIMULATOR
+
+#include "boards/board.h"
+
+/**************************************************************************/
+/*!
+    @brief Board-specific initialisation function
+*/
+/**************************************************************************/
+void boardInit(void)
+{
+  SystemCoreClockUpdate();
+}
+
+/**************************************************************************/
+/*!
+    @brief Primary entry point for this project.
+*/
+/**************************************************************************/
+#if !defined(_TEST_)
+int main(void)
+{
+  /* Configure the HW */
+  boardInit();
+
+  while (1)
+  {
+    /* ToDo: Do something! */
+  }
+}
+#endif
+
+/**************************************************************************/
+/*!
+    @brief Turns the LED(s) on or off
+*/
+/**************************************************************************/
+void boardLED(uint8_t state)
+{
+  // ToDo!
+}
+
+/**************************************************************************/
+/*!
+    @brief  Configure the board for low power and enter sleep mode
+*/
+/**************************************************************************/
+void boardSleep(void)
+{
+  // ToDo!
+}
+
+/**************************************************************************/
+/*!
+    @brief  Restores parts and system peripherals to an appropriate
+            state after waking up from sleep mode
+*/
+/**************************************************************************/
+void boardWakeup(void)
+{
+  // ToDo!
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/boards/simulator/board_simulator.h b/reform2-lpc-fw/src/boards/simulator/board_simulator.h
new file mode 100644
index 0000000000000000000000000000000000000000..be8efbad63b117989a60de20ff6321592334e2ce
--- /dev/null
+++ b/reform2-lpc-fw/src/boards/simulator/board_simulator.h
@@ -0,0 +1,660 @@
+/**************************************************************************/
+/*!
+    @file     board_simulator.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Board file for use with the simulator in Crossworks, etc.
+    @ingroup  Boards
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013 K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __BOARD_SIMULATOR_H__
+#define __BOARD_SIMULATOR_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sysdefs.h"
+
+/*=========================================================================
+    MCU SELECTION
+
+    Include one of the following definitions depending on if you are
+    using the LPC11U37 or LPC1347.  They're generally interchangeable, but
+    the LPC11Uxx and LPC13xx CMSIS implementations have some differences
+    in naming convention, and occasionally a feature is only available on
+    the M3 (DWT for example).  Selecting the appropriate MCU allows
+    the right code to be included when differences between the CMSIS
+    implementations are present.
+
+    -----------------------------------------------------------------------*/
+    // #define CFG_MCU_LPC11U24FBD48_401
+    // #define CFG_MCU_LPC11U37FBD48_401
+    // #define CFG_MCU_LPC1347FBD48
+    // #define CFG_MCU_LPC1347FHN33
+    #define CFG_MCU_SIMULATOR
+
+    /* Basic error checking */
+    #if !defined CFG_MCU_LPC1347FBD48      && \
+        !defined CFG_MCU_LPC11U37FBD48_401 && \
+        !defined CFG_MCU_LPC11U24FBD48_401 && \
+        !defined CFG_MCU_LPC1347FHN33      && \
+        !defined CFG_MCU_SIMULATOR
+      #error "An MCU must be selected in projectconfig.h (Ex. CFG_MCU_LPC11U37FBD48_401, CFG_MCU_LPC1347FBD48, etc.)"
+    #endif
+
+    /* Set flag to indicate which CMSIS library to use */
+    #if (defined CFG_MCU_LPC1347FBD48 || defined CFG_MCU_LPC1347FHN33)
+      #define CFG_MCU_FAMILY_LPC13UXX
+    #elif (defined CFG_MCU_LPC11U24FBD48_401 || defined CFG_MCU_LPC11U37FBD48_401)
+      #define CFG_MCU_FAMILY_LPC11UXX
+    #elif (defined CFG_MCU_SIMULATOR)
+      // User LPC13U for the simulator for now
+      #define CFG_MCU_FAMILY_LPC13UXX
+    #endif
+
+    /* Include the correct MCU header file */
+    #if defined CFG_MCU_FAMILY_LPC13UXX
+      #include "LPC13Uxx.h"
+    #endif
+    #if defined CFG_MCU_FAMILY_LPC11UXX
+      #include "LPC11Uxx.h"
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    FIRMWARE VERSION SETTINGS
+    -----------------------------------------------------------------------*/
+    #define CFG_FIRMWARE_VERSION_MAJOR      (0)
+    #define CFG_FIRMWARE_VERSION_MINOR      (0)
+    #define CFG_FIRMWARE_VERSION_REVISION   (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    GPIO INTERRUPTS
+    -----------------------------------------------------------------------
+    This table shows where GPIO interrupts are mapped in this project
+    (Note that the LPC11U and LPC13U use different names for the
+    IRQ Handlers in the standard headers)
+
+    Interrupt                                     Location
+    ------------------------------------------    -------------------------
+    PIN_INT0_IRQHandler - FLEX_INT0_IRQHandler    chb_drvr.c
+    PIN_INT1_IRQHandler - FLEX_INT1_IRQHandler    pcf2129.c
+    PIN_INT2_IRQHandler - FLEX_INT2_IRQHandler
+    PIN_INT3_IRQHandler - FLEX_INT3_IRQHandler
+    PIN_INT4_IRQHandler - FLEX_INT4_IRQHandler
+    PIN_INT5_IRQHandler - FLEX_INT5_IRQHandler
+    PIN_INT6_IRQHandler - FLEX_INT6_IRQHandler
+    PIN_INT7_IRQHandler - FLEX_INT7_IRQHandler
+    GINT0_IRQHandler
+    GINT0_IRQHandler
+    -----------------------------------------------------------------------*/
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SUPPORTED PERIPHERALS
+    -----------------------------------------------------------------------
+    Because all ISRs are referenced in the startup code, GCC typically
+    won't optimise out the ISR functions during compilation even if the
+    ISRs will never be entered, resulting in larger binaries than required
+    (for example if no I2C sensors are used, be sure to disable I2C support
+    since the I2C ISR is quite large).
+
+    Use the defines below to include or exclude support for specific
+    peripherals.
+
+    NOTE: GPIO ISRs are handled separately in GPIO INTERRUPTS below
+    -----------------------------------------------------------------------*/
+    // #define CFG_ENABLE_I2C
+    // #define CFG_ENABLE_UART
+    // #define CFG_ENABLE_USB
+    // #define CFG_ENABLE_TIMER32
+/*=========================================================================*/
+
+
+/*=========================================================================
+    EEPROM
+    -----------------------------------------------------------------------
+    EEPROM is used to persist certain user modifiable values to make
+    sure that these changes remain in effect after a reset or hard
+    power-down.  The addresses in EEPROM for these various system
+    settings/values are defined below.  The first 256 bytes of EEPROM
+    are reserved for this (0x0000..0x00FF).
+
+    CFG_EEPROM_SIZE           The number of bytes available on the EEPROM
+    CFG_EEPROM_RESERVED       The last byte of reserved EEPROM memory
+
+          EEPROM Address (0x0000..0x00FF)
+          ===============================
+          0 1 2 3 4 5 6 7 8 9 A B C D E F
+    000x  x x . . x x x x x x x x . . . .   Chibi
+    001x  . . . . . . . . . . . . . . . .
+    002x  . . . . . . . . . . . . . . . .
+    003x  . . . . . . . . . . . . . . . .
+    004x  . . . . . . . . . . . . . . . .
+    005x  . . . . . . . . . . . . . . . .
+    006x  . . . . . . . . . . . . . . . .
+    007x  . . . . . . . . . . . . . . . .
+    008x  . . . . . . . . . . . . . . . .
+    009x  . . . . . . . . . . . . . . . .
+    00Ax  . . . . . . . . . . . . . . . .
+    00Bx  . . . . . . . . . . . . . . . .
+    00Cx  . . . . . . . . . . . . . . . .
+    00Dx  . . . . . . . . . . . . . . . .
+    00Ex  . . . . . . . . . . . . . . . .
+    00Fx  . . . . . . . . . . . . . . . .
+
+    -----------------------------------------------------------------------*/
+    #define CFG_EEPROM_SIZE                   (4032)
+    #define CFG_EEPROM_RESERVED               (0x00FF)              // Protect first 256 bytes of memory
+    #define CFG_EEPROM_CHIBI_NODEADDR         (uint16_t)(0x0000)    // 2
+    #define CFG_EEPROM_CHIBI_IEEEADDR         (uint16_t)(0x0004)    // 8
+/*=========================================================================*/
+
+
+/*=========================================================================
+    ON-BOARD LED
+    -----------------------------------------------------------------------
+
+    CFG_LED_PORT              The port for the on board LED
+    CFG_LED_PIN               The pin for the on board LED
+    CFG_LED_ON                The pin state to turn the LED on (0 = low, 1 = high)
+    CFG_LED_OFF               The pin state to turn the LED off (0 = low, 1 = high)
+
+    -----------------------------------------------------------------------*/
+    #define CFG_LED_PORT                  (0)
+    #define CFG_LED_PIN                   (7)
+    #define CFG_LED_ON                    (1)
+    #define CFG_LED_OFF                   (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    ADC
+    -----------------------------------------------------------------------
+
+    CFG_ADC_MODE_LOWPOWER     If set to 1, this will configure the ADC
+                              for low-power operation (LPC1347 only)
+    CFG_ADC_MODE_10BIT        If set to 1, this will configure the ADC
+                              for 10-bit mode (LPC1347 only)
+
+    -----------------------------------------------------------------------*/
+    #define CFG_ADC_MODE_LOWPOWER       (0)
+    #define CFG_ADC_MODE_10BIT          (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    UART
+    -----------------------------------------------------------------------
+
+    CFG_UART_BAUDRATE         The default UART speed.  This value is used
+                              when initialising UART, and should be a
+                              standard value like 57600, 9600, etc.
+                              NOTE: This value may be overridden if
+                              another value is stored in EEPROM!
+    CFG_UART_BUFSIZE          The length in bytes of the UART RX FIFO. This
+                              will determine the maximum number of received
+                              characters to store in memory.
+
+    -----------------------------------------------------------------------*/
+    #define CFG_UART_BAUDRATE           (115200)
+    #define CFG_UART_BUFSIZE            (256)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SPI
+    -----------------------------------------------------------------------
+
+    CFG_SSP_SCK0_LOCATION     The location of the SCK pin for SSP0
+    CFG_SSP_MISO1_LOCATION    The location of the MISO1 pin for SSP1
+    CFG_SSP_MOSI1_LOCATION    The location of the MOSI1 pin for SSP1
+    CFG_SSP_SCK1_LOCATION     The location of the SCK pin for SSP1
+
+    -----------------------------------------------------------------------*/
+    #define CFG_SSP_SCK0_0_6            (6)     // Used by USBConnect
+    #define CFG_SSP_SCK0_0_10           (10)    // Used by SWD
+    #define CFG_SSP_SCK0_1_29           (29)
+
+    #define CFG_SSP_MISO1_0_22          (22)
+    #define CFG_SSP_MISO1_1_21          (21)
+    #define CFG_SSP_MOSI1_0_21          (21)
+    #define CFG_SSP_MOSI1_1_22          (22)
+    #define CFG_SSP_SCK1_1_15           (15)
+    #define CFG_SSP_SCK1_1_20           (20)
+
+    // Select the appropriate pin locations here
+    #define CFG_SSP_SCK0_LOCATION       (CFG_SSP_SCK0_1_29)
+    #define CFG_SSP_MISO1_LOCATION      (CFG_SSP_MISO1_1_21)
+    #define CFG_SSP_MOSI1_LOCATION      (CFG_SSP_MOSI1_1_22)
+    #define CFG_SSP_SCK1_LOCATION       (CFG_SSP_SCK1_1_20)
+
+    // Set the phase and polarity for SSP0 and SSP1
+    #define CFG_SSP_CPOL0               (0)
+    #define CFG_SSP_CPHA0               (0)
+    #define CFG_SSP_CPOL1               (0)
+    #define CFG_SSP_CPHA1               (0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PRINTF REDIRECTION
+    -----------------------------------------------------------------------
+
+    CFG_PRINTF_MAXSTRINGSIZE  Maximum size of string buffer for printf
+    CFG_PRINTF_UART           Will cause all printf statements to be
+                              redirected to UART
+    CFG_PRINTF_USBCDC         Will cause all printf statements to be
+                              redirect to USB Serial
+    CFG_PRINTF_NEWLINE        This is typically "\r\n" for Windows or
+                              "\n" for *nix
+
+    Note: If no printf redirection definitions are present, all printf
+    output will be ignored.
+    -----------------------------------------------------------------------*/
+    #define CFG_PRINTF_MAXSTRINGSIZE    (255)
+    // #define CFG_PRINTF_UART
+    // #define CFG_PRINTF_USBCDC
+    #define CFG_PRINTF_DEBUG
+
+    #define CFG_PRINTF_NEWLINE          "\n"
+/*=========================================================================*/
+
+
+/*=========================================================================
+    COMMAND LINE INTERFACE
+    -----------------------------------------------------------------------
+
+    CFG_INTERFACE             If this field is defined the UART or USBCDC
+                              based command-line interface will be included
+    CFG_INTERFACE_MAXMSGSIZE  The maximum number of bytes to accept for an
+                              incoming command
+    CFG_INTERFACE_PROMPT      The command prompt to display at the start
+                              of every new data entry line
+    CFG_INTERFACE_SILENTMODE  If this is set to 1 only text generated in
+                              response to commands will be send to the
+                              output buffer.  The command prompt will not
+                              be displayed and incoming text will not be
+                              echoed back to the output buffer (allowing
+                              you to see the text you have input).  This
+                              is normally only desirable in a situation
+                              where another MCU is communicating with
+                              the LPC1343.
+    CFG_INTERFACE_DROPCR      If this is set to 1 all incoming \r
+                              characters will be dropped
+    CFG_INTERFACE_ENABLEIRQ   If this is set to 1 the IRQ pin will be
+                              set high when a command starts executing
+                              and will go low when the command has
+                              finished executing or the LCD is not busy.
+                              This allows another device to know when a
+                              new command can safely be sent.
+    CFG_INTERFACE_IRQPORT     The gpio port for the IRQ/busy pin
+    CFG_INTERFACE_IRQPIN      The gpio pin number for the IRQ/busy pin
+    CFG_INTERFACE_SHORTERRORS If this is enabled only short 1 character
+                              error messages will be returned (followed
+                              by CFG_PRINTF_NEWLINE), rather than more
+                              verbose error messages.  The specific
+                              characters used are defined below.
+    CFG_INTERFACE_CONFIRMREADY  If this is set to 1 a text confirmation
+                              will be sent when the command prompt is
+                              ready for a new command.  This is in
+                              addition to CFG_INTERFACE_ENABLEIRQ if
+                              this is also enabled.  The character used
+                              is defined below.
+    CFG_INTERFACE_LONGSYSINFO If this is set to 1 extra information will
+                              be included in the Sys Info ('V') command
+                              on the CLI. This can be useful when trying
+                              to debug problems on remote HW, or with
+                              unknown firmware.  It will also use about
+                              0.5KB flash, though, so only enable it is
+                              necessary.
+
+    NOTE:                     The command-line interface will use either
+                              USB-CDC or UART depending on whether
+                              CFG_PRINTF_UART or CFG_PRINTF_USBCDC are
+                              selected.
+    -----------------------------------------------------------------------*/
+    // #define CFG_INTERFACE
+    #define CFG_INTERFACE_MAXMSGSIZE    (256)
+    #define CFG_INTERFACE_PROMPT        "LPC1347 >> "
+    #define CFG_INTERFACE_SILENTMODE    (0)
+    #define CFG_INTERFACE_DROPCR        (0)
+    #define CFG_INTERFACE_ENABLEIRQ     (0)
+    #define CFG_INTERFACE_IRQPORT       (0)
+    #define CFG_INTERFACE_IRQPIN        (7)
+    #define CFG_INTERFACE_SHORTERRORS   (0)
+    #define CFG_INTERFACE_CONFIRMREADY  (0)
+    #define CFG_INTERFACE_LONGSYSINFO   (1)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SIMPLE BINARY PROTOCOL
+    -----------------------------------------------------------------------
+
+    CFG_PROTOCOL             If this field is defined the binary command
+                              parser will be included
+    -----------------------------------------------------------------------*/
+    // #define CFG_PROTOCOL
+
+    // #define CFG_PROTOCOL_VIA_HID
+    #define CFG_PROTOCOL_VIA_BULK
+
+    #if defined(CFG_PROTOCOL) && !defined(CFG_PROTOCOL_VIA_HID) && !defined(CFG_PROTOCOL_VIA_BULK)
+        #error CFG_PROTOCOL must be enabled with either CFG_PROTOCOL_VIA_HID or CFG_PROTOCOL_VIA_BULK
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    TFT LCD
+    -----------------------------------------------------------------------
+
+    CFG_TFTLCD                  If defined, this will cause drivers for
+                                a pre-determined LCD screen to be included
+                                during build.  Only one LCD driver can be
+                                included during the build process (for ex.
+                                'drivers/displays/hw/ILI9325.c')
+    CFG_TFTLCD_INCLUDESMALLFONTS If set to 1, smallfont support will be
+                                included for 3x6, 5x8, 7x8 and 8x8 fonts.
+                                This should only be enabled if these small
+                                fonts are required since there is already
+                                support for larger fonts generated with
+                                Dot Factory
+                                http://www.pavius.net/downloads/tools/53-the-dot-factory
+    CFG_TFTLCD_USEAAFONTS       If set to a non-zero value, anti-aliased
+                                fonts will be used instead of regular 1-bit
+                                font.  These result in much higher-
+                                quality text, but the fonts are 2 or 4
+                                times larger than plain bitmap fonts and
+                                take a bit more rendering time to display.
+    CFG_TFTLCD_TS_DEFAULTTHRESHOLD  Default minimum threshold to trigger a
+                                touch event with the touch screen (and exit
+                                from 'tsWaitForEvent' in touchscreen.c).
+                                Should be an 8-bit value somewhere between
+                                8 and 75 in normal circumstances.  This is
+                                the default value and may be overriden by
+                                a value stored in EEPROM.
+    CFG_TFTLCD_TS_KEYPADDELAY   The delay in milliseconds between key
+                                presses in dialogue boxes
+    ----------------------------------------------------------------------*/
+    // #define CFG_TFTLCD
+    #define CFG_TFTLCD_INCLUDESMALLFONTS   (1)
+    #define CFG_TFTLCD_USEAAFONTS          (0)
+    #define CFG_TFTLCD_TS_DEFAULTTHRESHOLD (50)
+    #define CFG_TFTLCD_TS_KEYPADDELAY      (100)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    MICRO-SD CARD
+    -----------------------------------------------------------------------
+
+    CFG_SDCARD                If this field is defined SD Card and FAT32
+                              file system support will be included
+    CFG_SDCARD_SPIPORT        SSP Port used for the SD card (0 or 1)
+    CFG_SDCARD_READONLY       If this is set to 1, all commands to
+                              write to the SD card will be removed
+                              saving some flash space.
+    CFG_SDCARD_CDPORT         The card detect port number
+    CFG_SDCARD_CDPIN          The card detect pin number
+
+    NOTE:                     All config settings for FAT32 are defined
+                              in ffconf.h
+    -----------------------------------------------------------------------*/
+    // #define CFG_SDCARD
+    #define CFG_SDCARD_READONLY         (1)   // Must be 0 or 1
+    #define CFG_SDCARD_SPIPORT          (0)
+    #define CFG_SDCARD_SSELPORT         (0)
+    #define CFG_SDCARD_SSELPIN          (0)
+    #define CFG_SDCARD_CDPORT           (0)
+    #define CFG_SDCARD_CDPIN            (0)
+    #define CFG_SDCARD_ENBLPORT         (0)
+    #define CFG_SDCARD_ENBLPIN          (0)
+
+    #ifdef CFG_SDCARD
+      #if !((CFG_SDCARD_READONLY == 0) || (CFG_SDCARD_READONLY == 1))
+        #error "Invalid value for CFG_SDCARD_READONLY"
+      #endif
+      #if !((CFG_SDCARD_SPIPORT == 0) || (CFG_SDCARD_SPIPORT == 1))
+        #error "Invalid SPI port for CFG_SDCARD_SPIPORT"
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    CHIBI WIRELESS STACK
+    -----------------------------------------------------------------------
+
+    CFG_CHIBI                   If defined, the CHIBI wireless stack will be
+                                included during build.  Requires external HW.
+    CFG_CHIBI_MODE              The mode to use when receiving and transmitting
+                                wireless data.  See chb_drvr.h for possible values
+    CFG_CHIBI_POWER             The power level to use when transmitting.  See
+                                chb_drvr.h for possible values
+    CFG_CHIBI_CHANNEL           802.15.4 Channel (0 = 868MHz, 1-10 = 915MHz)
+    CFG_CHIBI_PANID             16-bit PAN Identifier (ex.0x1234)
+    CFG_CHIBI_PROMISCUOUS       Set to 1 to enabled promiscuous mode or
+                                0 to disable it.  If promiscuous mode is
+                                enabled be sure to set CFG_CHIBI_BUFFERSIZE
+                                to an appropriately large value (ex. 1024)
+    CFG_CHIBI_BUFFERSIZE        The size of the message buffer in bytes
+    -----------------------------------------------------------------------*/
+    // #define CFG_CHIBI
+    #define CFG_CHIBI_MODE              (0)                 // OQPSK_868MHZ
+    #define CFG_CHIBI_POWER             (0xE9)              // CHB_PWR_EU2_3DBM
+    #define CFG_CHIBI_CHANNEL           (0)                 // 868-868.6 MHz
+    #define CFG_CHIBI_PANID             (0x1234)
+    #define CFG_CHIBI_PROMISCUOUS       (0)
+    #define CFG_CHIBI_BUFFERSIZE        (256)
+
+    // Pin config settings
+    #define CFG_CHIBI_SPIPORT           (0)  // Must be 0 or 1
+    #define CFG_CHIBI_SSPORT            (0)
+    #define CFG_CHIBI_SSPIN             (0)
+    #define CFG_CHIBI_EINTPORT          (0)
+    #define CFG_CHIBI_EINTPIN           (0)
+    #define CFG_CHIBI_RSTPORT           (0)
+    #define CFG_CHIBI_RSTPIN            (0)
+    #define CFG_CHIBI_SLPTRPORT         (0)
+    #define CFG_CHIBI_SLPTRPIN          (0)
+    #define CFG_CHIBI_CC1190_HGM_PORT   (0)   // Not used
+    #define CFG_CHIBI_CC1190_HGM_PIN    (0)   // Not used
+
+    #ifdef CFG_CHIBI
+      #if !((CFG_CHIBI_SPIPORT == 0) || (CFG_CHIBI_SPIPORT == 1))
+        #error "Invalid SPI port for CFG_CHIBI_SPIPORT"
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PN532/NFC STACK
+    -----------------------------------------------------------------------
+
+    CFG_PN532                      If defined, the PN532/NFC stack will be
+                                   included during build.  Requires
+                                   external HW
+    CFG_PN532_MEM_POOL_SIZE_BYTES  Size of the dynamic memory pool in bytes
+                                   (used by pn532/mem_allocator/ when
+                                   working with NDEF messages)
+    -----------------------------------------------------------------------*/
+    // #define CFG_PN532
+    #define CFG_PN532_RSTPD_PORT                      (0)
+    #define CFG_PN532_RSTPD_PIN                       (16)
+    #define CFG_PN532_I2C_IRQPORT                     (0)
+    #define CFG_PN532_I2C_IRQPIN                      (17)
+    #define CFG_PN532_MEM_POOL_SIZE_BYTES             (512)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    RTC SUPPORT
+    -----------------------------------------------------------------------
+
+    CFG_RTC                     If defined, RTC support will be included.
+                                Requires external HW.
+    -----------------------------------------------------------------------*/
+    // #define CFG_RTC
+
+    #if defined(CFG_RTC) && !defined(CFG_ENABLE_I2C)
+      #error "CFG_ENABLE_I2C must be defined with CFG_RTC"
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    STEPPER MOTOR SUPPORT
+    -----------------------------------------------------------------------
+
+    CFG_STEPPER                 If defined, basic stepper motor support
+                                will be included.  Requires external HW.
+    -----------------------------------------------------------------------*/
+    // #define CFG_STEPPER
+    #define CFG_STEPPER_TIMER32                       (0)
+    #define CFG_STEPPER_IN1_PORT                      (0)
+    #define CFG_STEPPER_IN1_PIN                       (8)
+    #define CFG_STEPPER_IN2_PORT                      (0)
+    #define CFG_STEPPER_IN2_PIN                       (9)
+    #define CFG_STEPPER_IN3_PORT                      (0)
+    #define CFG_STEPPER_IN3_PIN                       (14)
+    #define CFG_STEPPER_IN4_PORT                      (0)
+    #define CFG_STEPPER_IN4_PIN                       (13)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    USB
+
+    CFG_USB_STRING_MANUFACTURER Manufacturer name that will appear in the
+                                device descriptor during USB enumeration
+    CFG_USB_STRING_PRODUCT      Product name that will appear in the
+                                device descriptor during USB enumeration
+    CFG_USB_VENDORID            16-bit USB vendor ID
+    USB_PRODUCT_ID              Define this to set a custom product ID
+                                if you do not wish to use the 'auto'
+                                product ID feature
+    CFG_CDC                     Enable USB CDC support
+    CFG_USB_HID_KEYBOARD        Enable USB HID keyboard emulation
+    CFG_USB_HID_MOUSE           Enable USB HID mouse emulation for a five
+                                button 'Windows' mouse with scroll wheels
+    CFG_USB_HID_GENERIC         Enable USB HID Generic support for custom
+                                in and out reports, with report size set
+                                via CFG_USB_HID_GENERIC_REPORT_SIZE
+    CFG_USB_MSC                 Enable USB Mass Storage support, pointing
+                                to the SD card reader (requires mmc.c from
+                                the FATFS drivers, but doesn't use FATFS)
+
+
+    You can combine more than one USB class below and they will be
+    automatically combined in a USB composite device within the limit of
+    available USB endpoints.  The USB Product ID is calculated automatically
+    based on the combination of classes defined below.
+
+    NOTE: Windows requires the .inf file in '/core/usb' for CDC support
+    -----------------------------------------------------------------------*/
+    #ifdef CFG_ENABLE_USB
+      #define CFG_USB_STRING_MANUFACTURER       "microBuilder.eu"
+      #define CFG_USB_STRING_PRODUCT            "LPC1347 LPCXpresso"
+      #define CFG_USB_VENDORID                  (0x1FC9)
+
+      // #define CFG_USB_CDC
+
+      // #define CFG_USB_HID_KEYBOARD
+      // #define CFG_USB_HID_MOUSE
+      // #define CFG_USB_HID_GENERIC
+
+      // #define CFG_USB_MSC
+
+      // #define CFG_USB_CUSTOM_CLASS
+
+      #if (defined(CFG_USB_CDC)       || defined(CFG_USB_HID_KEYBOARD) || \
+           defined(CFG_USB_HID_MOUSE) || defined(CFG_USB_HID_GENERIC)  || \
+           defined(CFG_USB_MSC)       || defined(CFG_USB_CUSTOM_CLASS))
+        #define CFG_USB
+        #if defined(CFG_USB_HID_KEYBOARD) || defined(CFG_USB_HID_MOUSE) || defined(CFG_USB_HID_GENERIC)
+          #define CFG_USB_HID
+          #if defined(CFG_USB_HID_GENERIC) && (CFG_USB_HID_GENERIC_REPORT_SIZE > 64)
+            #error "CFG_USB_HID_GENERIC_REPORT_SIZE exceeds the maximum value of 64 bytes (based on USB specs 2.0 for 'Full Speed Interrupt Endpoint Size')"
+          #endif
+        #endif
+      #endif
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    CONFIG FILE VALIDATION
+
+    Basic error checking to make sure that incompatible defines are not
+    enabled at the same time, etc.
+
+    -----------------------------------------------------------------------*/
+    #if defined(CFG_INTERFACE) && !( defined CFG_PRINTF_UART || defined CFG_PRINTF_USBCDC || defined CFG_PRINTF_DEBUG)
+      #error "At least one CFG_PRINTF target must be defined with CFG_INTERFACE"
+    #endif
+
+    #if defined(CFG_PRINTF_UART) && !defined(CFG_ENABLE_UART)
+      #error "CFG_ENABLE_UART must be enabled with CFG_PRINTF_UART"
+    #endif
+
+    #if defined(CFG_PRINTF_USBCDC) && !defined(CFG_USB_CDC)
+      #error "CFG_USB_CDC must be defined with CFG_PRINTF_USBCDC"
+    #endif
+
+    #if defined(CFG_USB_MSC) && !defined(CFG_SDCARD)
+      #error "CFG_USB_MSC must be defined with CFG_SDCARD"
+    #endif
+
+    #if defined(CFG_PROTOCOL)
+      #if defined(CFG_PROTOCOL_VIA_HID) && !defined(CFG_USB_HID_GENERIC)
+        #error "CFG_PROTOCOL_VIA_HID requires CFG_USB_HID_GENERIC"
+      #endif
+
+      #if defined(CFG_PROTOCOL_VIA_BULK) && !defined(CFG_USB_CUSTOM_CLASS)
+        #error "CFG_PROTOCOL_VIA_BULK requires CFG_USB_CUSTOM_CLASS to be defined"
+      #endif
+    #endif
+/*=========================================================================*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/cli/README.md b/reform2-lpc-fw/src/cli/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..41026959a25d026dc281aa93c33d996fbf634667
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/README.md
@@ -0,0 +1,62 @@
+# Command Line Interface (CLI) #
+
+The code base includes a basic, easy to extend command-line interface (CLI) that provides a convenient way for end-users to interact with or debug your project or hardware.
+
+The CLI uses printf for the output, so it can be configured to work with either **UART** or **USB CDC** depending on the CFG_PRINTF settings in your board config file.
+
+Incoming characters are handled via the appropriate interrupt (UART or USB CDC), and text is held in a buffer until **cliPoll()** is called, which will attempt to process any valid commands.
+
+## Using the CLI ##
+
+Depending on if you are using UART or USB CDC for the CLI, you need to open some sort of terminal software (for example Tera Term on Windows), set it to the correct COM port, and set the baud rate to **115200** (or whatever baud rate you have set in your board config file if you are using UART).
+
+You can enter **'?'** followed by the carriage-return character to display a list of all commands available on the system, or enter any command followed by '?' to see a basic description of the command and it's parameters.
+
+## Extending the CLI ##
+
+Adding new commands to the CLI is relatively easy.  There are two simple steps to follow:
+
+**Step One: Create a new command in 'cli/commands'**
+
+The first thing you need to do is implement the command in a seperate file that should be placed in the '/cli/commands' folder, following the same model at the existing commands:
+
+```
+/**************************************************************************/
+/*!
+    Your command handler
+*/
+/**************************************************************************/
+void cmd_yourCommand(uint8_t argc, char **argv)
+{
+  /* argc = the number of supplied arguments  */
+  /* argv[x] = the specific argument contents */
+
+  printf("Your command!%s", CFG_PRINTF_NEWLINE);
+}
+```
+
+**Step Two: Add the command to the command table (cli/cli_tbl.h)**
+
+Once your command has been created, you simply need to insert it in the command lookup table with a few parameters that let the system know how to handle the command and perform some basic error-checking.
+
+At the top of cli_tbl.h add the function prototype for your command, similar to the following:
+
+```
+void cmd_yourCommand(uint8_t argc, char **argv);
+```
+
+And then add a new command entry in the cli_tbl array:
+
+```
+{ "cmd", 1,  2,  0, cmd_yourCommand , "Desc of your command" , "'cmd param1 [<param2>]'" },
+```
+
+The parameters in the lookup table are the following (in order of appearance):
+
+- **Command name**: The text that will be associated with your command.  This should be a single world (no spaces or special characters) since the command parameters are parsed based on the 'space' character.
+- **Minimum arguments**: The minimum number of arguments that are required for this command (not including the command name itself).  You must have at least this many arguments present or the CLI will reject the command input.
+- **Maximum arguments**: The maximum number of arguments if you wish to support some optional arguments as well.  Anything with more arguments than the max value will also be rejected by the CLI.
+- **Hidden**: If this is set to '1' then the command will not appear in the command list (entering the '?' character at the command prompt).
+- **Function name**: the name of the function where you command is implemented (ex.: 'cmd_yourCommand').  This is where the CLI will redirect command processing to if it passed basic validation checks.
+- **Description**: This is a short description of your command that will appear in the command list, and in the help menu (when you enter the command name followed by the '?' character).
+- **Syntax**: The command syntax, including the cmd name, mandatory parameters, and optional parameters (the latter should be placed in square brackets to indicate they are optional).
\ No newline at end of file
diff --git a/reform2-lpc-fw/src/cli/ansi.h b/reform2-lpc-fw/src/cli/ansi.h
new file mode 100644
index 0000000000000000000000000000000000000000..09dc2859b39535918371dd788677b0a362eb5958
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/ansi.h
@@ -0,0 +1,94 @@
+/**************************************************************************/
+/*!
+    @file     ansi.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    ANSI codes for text-formating in the CLI
+    @ingroup  CLI
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012 K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+
+#ifndef __ANSI_H__
+#define __ANSI_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+#define ANSI_GOTOXY(x, y) do { printf("%c[%d;%df",0x1B,y,x); } while(0)
+
+// See: http://www.inwap.com/pdp10/ansicode.txt
+
+/* Ex: printf(ANSICODES_GRAPHICS_STYLE_BOLD
+               ANSICODES_GRAPHICS_FORECOLOR_BLACK
+               ANSICODES_GRAPHICS_STYLE_NEGATIVE
+               "Bold Black Inverted Text"
+               ANSICODES_GRAPHICS_CLEARALL "\r\n"); */
+
+
+#define ANSICODES_GRAPHICS_CLEARALL               "\33[0m"
+#define ANSICODES_GRAPHICS_STYLE_BOLD             "\33[1m"
+#define ANSICODES_GRAPHICS_STYLE_DIM              "\33[2m"
+#define ANSICODES_GRAPHICS_STYLE_ITALIC           "\33[3m"
+#define ANSICODES_GRAPHICS_STYLE_UNDERSCORE       "\33[4m"
+#define ANSICODES_GRAPHICS_STYLE_SLOWBLINK        "\33[5m"
+#define ANSICODES_GRAPHICS_STYLE_FASTBLINK        "\33[6m"
+#define ANSICODES_GRAPHICS_STYLE_NEGATIVE         "\33[7m"
+#define ANSICODES_GRAPHICS_STYLE_CONCEALED        "\33[8m"   // Do not display character
+#define ANSICODES_GRAPHICS_STYLE_CANCELBOLDDIM    "\33[22m"
+#define ANSICODES_GRAPHICS_STYLE_CANCELUNDERLINE  "\33[24m"
+#define ANSICODES_GRAPHICS_STYLE_CANCELBLINK      "\33[25m"
+#define ANSICODES_GRAPHICS_STYLE_CANCELNEGATIVE   "\33[27m"
+#define ANSICODES_GRAPHICS_FORECOLOR_BLACK        "\33[30m"
+#define ANSICODES_GRAPHICS_FORECOLOR_RED          "\33[31m"
+#define ANSICODES_GRAPHICS_FORECOLOR_GREEN        "\33[32m"
+#define ANSICODES_GRAPHICS_FORECOLOR_YELLOW       "\33[33m"
+#define ANSICODES_GRAPHICS_FORECOLOR_BLUE         "\33[34m"
+#define ANSICODES_GRAPHICS_FORECOLOR_MAGENTA      "\33[35m"
+#define ANSICODES_GRAPHICS_FORECOLOR_CYAN         "\33[36m"
+#define ANSICODES_GRAPHICS_FORECOLOR_WHITE        "\33[37m"
+#define ANSICODES_GRAPHICS_BACKCOLOR_BLACK        "\33[40m"
+#define ANSICODES_GRAPHICS_BACKCOLOR_RED          "\33[41m"
+#define ANSICODES_GRAPHICS_BACKCOLOR_GREEN        "\33[42m"
+#define ANSICODES_GRAPHICS_BACKCOLOR_YELLOW       "\33[43m"
+#define ANSICODES_GRAPHICS_BACKCOLOR_BLUE         "\33[44m"
+#define ANSICODES_GRAPHICS_BACKCOLOR_MAGENTA      "\33[45m"
+#define ANSICODES_GRAPHICS_BACKCOLOR_CYAN         "\33[46m"
+#define ANSICODES_GRAPHICS_BACKCOLOR_WHITE        "\33[47m"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/cli/cli.c b/reform2-lpc-fw/src/cli/cli.c
new file mode 100644
index 0000000000000000000000000000000000000000..ed91fc1c8006bd710b9fd435ba44af96fae65457
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/cli.c
@@ -0,0 +1,363 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+*******************************************************************/
+
+/**************************************************************************/
+/*!
+    @file     cli.c
+    @author   Christopher Wang (Freaklabs)
+              Modified by: K. Townsend (microBuilder.eu)
+
+    @ingroup  CLI
+
+    Original code taken from the FreakUSB Open Source USB Device Stack
+    http://freaklabs.org/index.php/FreakUSB-Open-Source-USB-Device-Stack.html
+
+    If it works well, you can thank Akiba at Freaklabs.  If it fails
+    miserably, you can blame me (since parts of it it were rather
+    ungraciously modified). :-)
+
+*/
+/**************************************************************************/
+
+#include "projectconfig.h"
+
+#ifdef CFG_INTERFACE
+
+#include <stdio.h>
+#include <string.h>
+
+#include "cli.h"
+#include "cli_tbl.h"
+
+#ifdef CFG_PRINTF_UART
+#include "core/uart/uart.h"
+#endif
+
+#ifdef CFG_PRINTF_USBCDC
+  #include "core/usb/usbd.h"
+  #include "core/usb/usb_cdc.h"
+#endif
+
+#if CFG_INTERFACE_ENABLEIRQ == 1
+  #include "core/gpio/gpio.h"
+#endif
+
+#define KEY_CODE_ESC        (27)    /* Escape key code */
+#define KEY_CODE_ENTER      (13)    /* Enter key code  */
+
+static uint8_t cli_buffer[CFG_INTERFACE_MAXMSGSIZE];
+static uint8_t *cli_buffer_ptr;
+
+/**************************************************************************/
+/*!
+    @brief  Polls the relevant incoming message queue to see if anything
+            is waiting to be processed.
+*/
+/**************************************************************************/
+void cliPoll()
+{
+  #if defined CFG_PRINTF_UART
+  while (uartRxBufferDataPending())
+  {
+    uint8_t c = uartRxBufferRead();
+    cliRx(c);
+  }
+  #endif
+
+  #if defined(CFG_USB) && defined(CFG_PRINTF_USBCDC)
+  if (usb_isConfigured())
+  {
+    uint8_t c;
+    while(usb_cdc_getc(&c))
+    {
+      cliRx(c);
+    }
+  }
+  #endif
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the CLI input until the 'Enter' key is detected, or
+            until we reach the end of the input buffer (use with care!)
+*/
+/**************************************************************************/
+void cliReadLine(uint8_t *str, uint16_t *strLen)
+{
+  uint8_t ch;
+  uint16_t idx = 0;
+
+  /* ToDo: Update this to handle UART, etc., with proper #ifdef blocks! */
+
+  while (1)
+  {
+    if (usb_isConfigured())
+    {
+      while (!usb_cdc_getc(&ch));
+
+      if ((ch >= 32) && (ch <= 126) && (idx < *strLen))
+      {
+        str[idx++] = ch;
+        cliRx(ch);
+      }
+      if (((ch == 8) || (ch == 127)) && idx)
+      {
+        str[idx--] = 0;
+        cliRx(ch);
+      }
+      if (ch == KEY_CODE_ENTER)
+      {
+        *strLen = idx;
+        break;
+      }
+    }
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Handles a single incoming character.  If a new line is
+            detected, the entire command will be passed to the command
+            parser.  If a text character is detected, it will be added to
+            the message buffer until a new line is detected (up to the
+            maximum queue size, CFG_INTERFACE_MAXMSGSIZE).
+
+    @param[in]  c
+                The character to parse.
+*/
+/**************************************************************************/
+void cliRx(uint8_t c)
+{
+  // read out the data in the buffer and echo it back to the host.
+  switch (c)
+  {
+    case '\r':
+      #if CFG_INTERFACE_DROPCR == 1
+      break;
+      #endif
+    case '\n':
+        // terminate the cli_buffer and reset the cli_buffer ptr. then send
+        // it to the handler for processing.
+        *cli_buffer_ptr = '\0';
+        #if CFG_INTERFACE_SILENTMODE == 0
+        printf("%s", CFG_PRINTF_NEWLINE);
+        #endif
+        cliParse((char *)cli_buffer);
+        cli_buffer_ptr = cli_buffer;
+        break;
+
+    case '\b':
+        #if CFG_INTERFACE_SILENTMODE == 0
+        printf("%c",c);
+        #endif
+        if (cli_buffer_ptr == cli_buffer)
+        {
+            // Send bell alert and space (to maintain position)
+            printf("\a ");
+        }
+        else if (cli_buffer_ptr > cli_buffer)
+        {
+            cli_buffer_ptr--;
+        }
+        break;
+
+    default:
+        #if CFG_INTERFACE_SILENTMODE == 0
+        printf("%c",c);
+        #endif
+        *cli_buffer_ptr++ = c;
+        break;
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Displays the command prompt.  The text that appears is defined
+            in projectconfig.h.
+*/
+/**************************************************************************/
+static void cliMenu()
+{
+  #if CFG_INTERFACE_SILENTMODE == 0
+  printf(CFG_PRINTF_NEWLINE);
+  printf(CFG_INTERFACE_PROMPT);
+  #endif
+  #if CFG_INTERFACE_CONFIRMREADY == 1
+  printf("%s%s", CFG_INTERFACE_CONFIRMREADY_TEXT, CFG_PRINTF_NEWLINE);
+  #endif
+}
+
+/**************************************************************************/
+/*!
+    @brief  Parse the command line. This function tokenizes the command
+            input, then searches for the command table entry associated
+            with the commmand. Once found, it will jump to the
+            corresponding function.
+
+    @param[in]  cmd
+                The entire command string to be parsed
+*/
+/**************************************************************************/
+void cliParse(char *cmd)
+{
+  size_t argc, i = 0;
+  char *argv[30];
+
+  argv[i] = strtok(cmd, " ");
+  do
+  {
+      argv[++i] = strtok(NULL, " ");
+  } while ((i < 30) && (argv[i] != NULL));
+
+  argc = i;
+  for (i=0; i < CMD_COUNT; i++)
+  {
+      if (!strcmp(argv[0], cli_tbl[i].command))
+      {
+        if ((argc == 2) && !strcmp (argv [1], "?"))
+        {
+          // Display parameter help menu on 'command ?'
+          printf ("%s%s%s", cli_tbl[i].description, CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+          printf ("%s%s", cli_tbl[i].parameters, CFG_PRINTF_NEWLINE);
+        }
+        else if ((argc - 1) < cli_tbl[i].minArgs)
+        {
+          // Too few arguments supplied
+          #if CFG_INTERFACE_SHORTERRORS == 1
+          printf ("%s%s", CFG_INTERFACE_SHORTERRORS_TOOFEWARGS, CFG_PRINTF_NEWLINE);
+          #else
+          printf ("%s (%s %d)%s", STRING(LOCALISATION_TEXT_Too_few_arguments), STRING(LOCALISATION_TEXT_Expected), cli_tbl[i].minArgs, CFG_PRINTF_NEWLINE);
+          printf ("%s'%s ?' %s%s%s", CFG_PRINTF_NEWLINE, cli_tbl[i].command, STRING(LOCALISATION_TEXT_for_more_information), CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+          #endif
+        }
+        else if ((argc - 1) > cli_tbl[i].maxArgs)
+        {
+          // Too many arguments supplied
+          #if CFG_INTERFACE_SHORTERRORS == 1
+          printf ("%s%s", CFG_INTERFACE_SHORTERRORS_TOOMANYARGS, CFG_PRINTF_NEWLINE);
+          #else
+          printf ("%s (%s %d)%s", STRING(LOCALISATION_TEXT_Too_many_arguments), STRING(LOCALISATION_TEXT_Maximum), cli_tbl[i].maxArgs, CFG_PRINTF_NEWLINE);
+          printf ("%s'%s ?' %s%s%s", CFG_PRINTF_NEWLINE, cli_tbl[i].command, STRING(LOCALISATION_TEXT_for_more_information), CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+          #endif
+        }
+        else
+        {
+          #if CFG_INTERFACE_ENABLEIRQ != 0
+          // Set the IRQ pin high at start of a command
+          gpioSetValue(CFG_INTERFACE_IRQPORT, CFG_INTERFACE_IRQPIN, 1);
+          #endif
+          // Dispatch command to the appropriate function
+          cli_tbl[i].func(argc - 1, &argv [1]);
+          #if CFG_INTERFACE_ENABLEIRQ  != 0
+          // Set the IRQ pin low to signal the end of a command
+          gpioSetValue(CFG_INTERFACE_IRQPORT, CFG_INTERFACE_IRQPIN, 0);
+          #endif
+        }
+
+        // Refresh the command prompt
+        cliMenu();
+        return;
+      }
+  }
+  // Command not recognized
+  #if CFG_INTERFACE_SHORTERRORS == 1
+  printf ("%s%s", CFG_INTERFACE_SHORTERRORS_UNKNOWNCOMMAND, CFG_PRINTF_NEWLINE);
+  #else
+  printf("%s: '%s'%s%s", STRING(LOCALISATION_TEXT_Command_Not_Recognized), cmd, CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+  #if CFG_INTERFACE_SILENTMODE == 0
+  printf("%s%s", STRING(LOCALISATION_TEXT_Type_QUESTION_for_a_list_of), CFG_PRINTF_NEWLINE);
+  #endif
+  #endif
+
+  cliMenu();
+}
+
+/**************************************************************************/
+/*!
+    @brief Initialises the command line using the appropriate interface
+*/
+/**************************************************************************/
+void cliInit()
+{
+  #if defined CFG_INTERFACE && defined CFG_PRINTF_UART
+    // Check if UART is already initialised
+    uart_pcb_t *pcb = uartGetPCB();
+    if (!pcb->initialised)
+    {
+      uartInit(CFG_UART_BAUDRATE);
+    }
+  #endif
+
+  #if CFG_INTERFACE_ENABLEIRQ != 0
+    // Set IRQ pin as output
+    LPC_GPIO->DIR[CFG_INTERFACE_IRQPORT] |= (1 << CFG_INTERFACE_IRQPIN);
+    LPC_GPIO->SET[CFG_INTERFACE_IRQPORT] = (1 << CFG_INTERFACE_IRQPIN);
+  #endif
+
+  // init the cli_buffer ptr
+  cli_buffer_ptr = cli_buffer;
+
+  // Show the menu
+  cliMenu();
+
+  // Set the IRQ pin low by default
+  #if CFG_INTERFACE_ENABLEIRQ  != 0
+    LPC_GPIO->CLR[CFG_INTERFACE_IRQPORT] = (1 << CFG_INTERFACE_IRQPIN);
+  #endif
+}
+
+/**************************************************************************/
+/*!
+    'help' command handler
+*/
+/**************************************************************************/
+void cmd_help(uint8_t argc, char **argv)
+{
+  size_t i;
+
+  printf("%s      %s%s", STRING(LOCALISATION_TEXT_Command), STRING(LOCALISATION_TEXT_Description), CFG_PRINTF_NEWLINE);
+  printf("-------      -----------%s", CFG_PRINTF_NEWLINE);
+
+  // Display full command list
+  for (i=0; i < CMD_COUNT; i++)
+  {
+    if (!cli_tbl[i].hidden)
+    {
+      printf ("%-10s   %s%s", cli_tbl[i].command, cli_tbl[i].description, CFG_PRINTF_NEWLINE);
+    }
+  }
+
+  printf("%s%s", STRING(LOCALISATION_TEXT_Command_parameters_can_be_seen), CFG_PRINTF_NEWLINE);
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/cli/cli.h b/reform2-lpc-fw/src/cli/cli.h
new file mode 100644
index 0000000000000000000000000000000000000000..f924baff5153f302a7ec12f3a4dcb82dd91ef3ef
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/cli.h
@@ -0,0 +1,80 @@
+/**************************************************************************/
+/*!
+    @defgroup CLI Command Line Interface
+
+    @brief    Easily extensible command-line interface that can handle
+	          data from UART, USB CDC, or a variety of other IO sources.
+*/
+/**************************************************************************/
+
+/**************************************************************************/
+/*! 
+    @file     cli.h
+    @author   K. Townsend (microBuilder.eu)
+
+	@brief    Core functions called to process CLI data and route request
+	          to the appropriate command handler.
+    @ingroup  CLI
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+
+#ifndef __CLI_H__ 
+#define __CLI_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+typedef struct
+{
+  char *command;
+  uint8_t minArgs;
+  uint8_t maxArgs;
+  uint8_t hidden;
+  void (*func)(uint8_t argc, char **argv);
+  const char *description;
+  const char *parameters;
+} cli_t;
+
+void cliPoll(void);
+void cliRx(uint8_t c);
+void cliParse(char *cmd);
+void cliInit(void);
+void cliReadLine(uint8_t *str, uint16_t *strLen);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/cli/cli_tbl.h b/reform2-lpc-fw/src/cli/cli_tbl.h
new file mode 100644
index 0000000000000000000000000000000000000000..af01268cb040d3f4bf1c834a232e4e0d012ac81b
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/cli_tbl.h
@@ -0,0 +1,170 @@
+/**************************************************************************/
+/*!
+    @file     cli_tbl.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Command lookup table for the CLI
+    @ingroup  CLI
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+
+#ifndef __CLI_TBL_H__
+#define __CLI_TBL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CMD_COUNT (sizeof(cli_tbl)/sizeof(cli_t))
+
+#include <stdio.h>
+
+#ifdef CFG_INTERFACE_UART
+#include "core/uart/uart.h"
+#endif
+
+/* Function prototypes for the command table */
+void cmd_help(uint8_t argc, char **argv);         /* handled by cli/cli.c */
+void cmd_sysinfo(uint8_t argc, char **argv);
+void cmd_dbg_memrd(uint8_t argc, char **argv);
+void cmd_eeprom_read(uint8_t argc, char **argv);
+void cmd_eeprom_write(uint8_t argc, char **argv);
+
+#ifdef CFG_ENABLE_I2C
+void cmd_i2c_scan(uint8_t argc, char **argv);
+void cmd_i2c_write(uint8_t argc, char **argv);
+void cmd_i2c_read(uint8_t argc, char **argv);
+#endif
+
+#ifdef CFG_PN532
+void cmd_nfc_mifareclassic_memdump(uint8_t argc, char **argv);
+void cmd_nfc_mifareultralight_memdump(uint8_t argc, char **argv);
+void cmd_nfc_mifareclassic_valueblock_create(uint8_t argc, char **argv);
+void cmd_nfc_mifareclassic_valueblock_increment(uint8_t argc, char **argv);
+void cmd_nfc_mifareclassic_valueblock_decrement(uint8_t argc, char **argv);
+void cmd_nfc_mifareclassic_valueblock_read(uint8_t argc, char **argv);
+void cmd_nfc_mfc_ndef_memdump(uint8_t argc, char **argv);
+void cmd_nfc_mfc_ndef_blankFormat(uint8_t argc, char **argv);
+void cmd_nfc_mfc_ndef_nfcFormat(uint8_t argc, char **argv);
+void cmd_nfc_mfc_ndef_write_ndef(uint8_t argc, char **argv);
+void cmd_nfc_mfc_ndef_prepare_ndefMessage(uint8_t argc, char **argv);
+#endif
+
+#ifdef CFG_SDCARD
+void cmd_sd_dir(uint8_t argc, char **argv);
+#endif
+
+#ifdef CFG_CHIBI
+void cmd_chibi_addr(uint8_t argc, char **argv);
+void cmd_chibi_ieeeaddr(uint8_t argc, char **argv);
+void cmd_chibi_tx(uint8_t argc, char **argv);
+#endif
+
+#ifdef CFG_RTC
+void cmd_rtc_read(uint8_t argc, char **argv);
+void cmd_rtc_write(uint8_t argc, char **argv);
+#endif
+
+#ifdef CFG_CC3000
+void cmd_wifi_moduleinfo(uint8_t argc, char **argv);
+void cmd_wifi_smartConfig(uint8_t argc, char **argv);
+void cmd_wifi_ssidscan(uint8_t argc, char **argv);
+void cmd_wifi_connect(uint8_t argc, char **argv);
+void cmd_wifi_disconnect(uint8_t argc, char **argv);
+void cmd_wifi_ping(uint8_t argc, char **argv);
+void cmd_wifi_gethostnameip(uint8_t argc, char **argv);
+#endif
+
+#define CMD_NOPARAMS ( "This command has no parameters" )
+
+/**************************************************************************/
+/*!
+    Command list for the command-line interpreter and the name of the
+    corresponding method that handles the command.
+
+    Note that a trailing ',' is required on the last entry, which will
+    cause a NULL entry to be appended to the end of the table.
+*/
+/**************************************************************************/
+cli_t cli_tbl[] =
+{
+  // command name, min args, max args, hidden, function name, command description, syntax
+  { "?",            0,  0,  0, cmd_help                                   , "Help"                              , CMD_NOPARAMS },
+  { "V",            0,  0,  0, cmd_sysinfo                                , "System Info"                       , CMD_NOPARAMS },
+  { "mr",           1,  3,  0, cmd_dbg_memrd                              , "Memory read"                       , "'mr <addr> [<len> <size(1..8)>]'" },
+  { "er",           1,  1,  0, cmd_eeprom_read                            , "EEPROM read"                       , "'er <addr>'" },
+  { "ew",           2,  2,  0, cmd_eeprom_write                           , "EEPROM write"                      , "'ew <addr> <val>'" },
+  #ifdef CFG_ENABLE_I2C
+  { "is",           0,  0,  0, cmd_i2c_scan                               , "I2C bus scan"                      , CMD_NOPARAMS },
+  { "ir",           2,  2,  0, cmd_i2c_read                               , "I2C read"                          , "'ir <addr> <len>'" },
+  { "iw",           2,  99, 0, cmd_i2c_write                              , "I2C write"                         , "'iw <addr> <value(s)>'" },
+  #endif
+  #ifdef CFG_PN532
+  { "du",           0,  1,  0, cmd_nfc_mifareultralight_memdump           , "Dump Mifare Ultralight card"       , "'du [<timeout>]'" },
+  { "dc",           0,  1,  0, cmd_nfc_mifareclassic_memdump              , "Dump Mifare Classic card"          , "'dc [<timeout>]'" },
+  { "dn",           0,  0,  0, cmd_nfc_mfc_ndef_memdump                   , "Dump Mifare Classic NFC messages"  , CMD_NOPARAMS },
+  { "fn",           0,  0,  0, cmd_nfc_mfc_ndef_nfcFormat                 , "Format Mifare Classic as NFC Tag"  , CMD_NOPARAMS },
+  { "fb",           0,  0,  0, cmd_nfc_mfc_ndef_blankFormat               , "Format NFC Tag as Mifare Classic"  , CMD_NOPARAMS },
+  { "npn",          0,  0,  0, cmd_nfc_mfc_ndef_prepare_ndefMessage       , "Create NDEF msg in mem for 'nw'"   , CMD_NOPARAMS },
+  { "nw",           0,  0,  0, cmd_nfc_mfc_ndef_write_ndef                , "Write msg from 'npn' to MFC card"  , "'nw [<sector>]'"},
+  { "vc",           2,  2,  0, cmd_nfc_mifareclassic_valueblock_create    , "Create Mifare value block"         , "'vc <block> <value>'" },
+  { "vi",           2,  2,  0, cmd_nfc_mifareclassic_valueblock_increment , "Increment Mifare value block"      , "'vi <block> <value>'" },
+  { "vd",           2,  2,  0, cmd_nfc_mifareclassic_valueblock_decrement , "Decrement Mifare value block"      , "'vd <block> <value>'" },
+  { "vr",           1,  1,  0, cmd_nfc_mifareclassic_valueblock_read      , "Read Mifare value block"           , "'vr <block> <value>'" },
+  #endif
+  #ifdef CFG_SDCARD
+  { "d",            0,  1,  0, cmd_sd_dir                                 , "Dir (SD Card)"                     , "'d [<path>]'" },
+  #endif
+  #ifdef CFG_CHIBI
+  { "ca",           0,  1,  0, cmd_chibi_addr                             , "Get/set node address"              , "'ca [<1-65534>|<OxFFFE>]'" },
+  { "cs",           2, 99,  0, cmd_chibi_tx                               , "Send msg to node"                  , "'cs <destaddr> <msg>'" },
+  #endif
+  #ifdef CFG_RTC
+  { "tr",           0, 0,  0, cmd_rtc_read                                , "RTC read"                           , CMD_NOPARAMS },
+  { "tw",           6, 7,  0, cmd_rtc_write                               , "RTC write"                          , "'tw <yr> <mon> <day> <hr> <min> <sec>'" },
+  #endif
+  #ifdef CFG_CC3000
+  { "winfo",        0, 0,  0, cmd_wifi_moduleinfo                         , "Wifi module info"                   , CMD_NOPARAMS },
+  { "wsc",          0, 1,  0, cmd_wifi_smartConfig                        , "Wifi SmartConnect"                  , "'wsc [<usekey(0|1)>]'" },
+  { "ws",           0, 0,  0, cmd_wifi_ssidscan                           , "Wifi SSID scan"                     , CMD_NOPARAMS },
+  { "wc",           2, 3,  0, cmd_wifi_connect                            , "Wifi connect"                       , "'wc <sec[0|1|2|3]> <ssid> <key>'" },
+  { "wd",           0, 0,  0, cmd_wifi_disconnect                         , "Wifi disconnect"                    , CMD_NOPARAMS },
+  { "wp",           1, 1,  0, cmd_wifi_ping                               , "Wifi ping"                          , "'wp <ipaddress>'" },
+  { "wl",           1, 1,  0, cmd_wifi_gethostnameip                      , "Wifi host name lookup"              , "'wl <hostname>'" },
+  #endif
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/cli/commands.c b/reform2-lpc-fw/src/cli/commands.c
new file mode 100644
index 0000000000000000000000000000000000000000..b0a6b20e44be7d246825f61297b1d4fa5ec377e9
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/commands.c
@@ -0,0 +1,136 @@
+/**************************************************************************/
+/*!
+    @file     commands.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+
+#include "projectconfig.h"
+
+#ifdef CFG_INTERFACE
+
+#include <stdio.h>
+#include <string.h>   // memset
+#include <ctype.h>    // isdigit, isspace, etc.
+
+#include "cli.h"
+#include "commands.h"
+
+/**************************************************************************/
+/*!
+    @brief  Attempts to convert the supplied decimal or hexadecimal
+            string to the matching 32-bit value.  All hexadecimal values
+            must be preceded by either '0x' or '0X' to be properly parsed.
+
+    @param[in]  s
+                Input string
+    @param[out] result
+                Signed 32-bit integer to hold the conversion results
+
+    @section Example
+
+    @code
+    char *hex = "0xABCD";
+    char *dec = "1234";
+
+    // Convert supplied values to integers
+    int32_t hexValue, decValue;
+    getNumber (hex, &hexValue);
+    getNumber (dec, &decValue);
+
+    @endcode
+*/
+/**************************************************************************/
+int getNumber (char *s, int32_t *result)
+{
+  int32_t value;
+  uint32_t mustBeHex = FALSE;
+  uint32_t sgn = 1;
+  const unsigned char hexToDec [] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15};
+
+  if (!s)
+    return 0;
+
+  // Check if this is a hexadecimal value
+  if ((strlen (s) > 2) && (!strncmp (s, "0x", 2) || !strncmp (s, "0X", 2)))
+  {
+    mustBeHex = TRUE;
+    s += 2;
+  }
+
+  // Check for negative sign
+  if (!mustBeHex && *s && (*s == '-'))
+  {
+    sgn = -1;
+    s++;
+  }
+
+  // Try to convert value
+  for (value = 0; *s; s++)
+  {
+    if (mustBeHex && isxdigit ((uint8_t)*s))
+      value = (value << 4) | hexToDec [toupper((uint8_t)*s) - '0'];
+    else if (isdigit ((uint8_t)*s))
+      value = (value * 10) + ((uint8_t)*s - '0');
+    else
+    {
+      // "Malformed number. Must be decimal number or hex value preceeded by '0x'"
+      printf ("%s%s", STRING(LOCALISATION_TEXT_Malformed_Number), CFG_PRINTF_NEWLINE);
+      return 0;
+    }
+  }
+
+  // Set number to negative value if required
+  if (!mustBeHex)
+    value *= sgn;
+
+  *result = value;
+
+  return 1;
+}
+
+int getNumberU32 (char *s, uint32_t *result)
+{
+  int32_t r;
+  if (getNumber(s, &r))
+  {
+    *result = (uint32_t)r;
+    return 1;
+  }
+  else
+  {
+    /* An error occured in getNumber */
+    return 0;
+  }
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/cli/commands.h b/reform2-lpc-fw/src/cli/commands.h
new file mode 100644
index 0000000000000000000000000000000000000000..239b90d462821d7ca1ba76e731920df32cb35df7
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/commands.h
@@ -0,0 +1,57 @@
+/**************************************************************************/
+/*!
+    @file     commands.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Common helper-functions for all commands in the 'core/cmd'
+              command-line interpretter.
+    @ingroup  CLI
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __COMMANDS_H__
+#define __COMMANDS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+/* Method Prototypes */
+int getNumber  (char *s, int32_t *result);
+int getNumberU32 (char *s, uint32_t *result);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/cli/commands/cmd_chibi_addr.c b/reform2-lpc-fw/src/cli/commands/cmd_chibi_addr.c
new file mode 100644
index 0000000000000000000000000000000000000000..1a0ca4f0963621705864636fbc608ed2fafddfce
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/commands/cmd_chibi_addr.c
@@ -0,0 +1,90 @@
+/**************************************************************************/
+/*!
+    @file     cmd_chibi_addr.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Code to execute for cmd_chibi_addr in the 'core/cmd'
+              command-line interpretter.
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2010, microBuilder SARL
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <stdio.h>
+
+#include "projectconfig.h"
+#include "cli/cli.h"
+#include "cli/commands.h"       // Generic helper functions
+
+#ifdef CFG_CHIBI
+  #include "drivers/rf/802.15.4/chibi/chb.h"
+  #include "drivers/rf/802.15.4/chibi/chb_drvr.h"
+
+/**************************************************************************/
+/*!
+    Gets or sets the 16-bit sensor node address.  This value can be
+    anything between 1-65534 (0x0001-0xFFFE), and in decimal or
+    hexadecimal notation.  All hexadecimal values must be preceded by
+    '0x' or '0X' to be properly interpreted (ex. 0x009F).
+*/
+/**************************************************************************/
+void cmd_chibi_addr(uint8_t argc, char **argv)
+{
+  if (argc > 0)
+  {
+    // Try to convert supplied value to an integer
+    int32_t addr;
+    getNumber (argv[0], &addr);
+
+    // Check for invalid values (getNumber may complain about this as well)
+    if (addr <= 0 || addr > 0xFFFF)
+    {
+      printf("Invalid Address: 1-65534 or 0x0001-0xFFFE required.%s", CFG_PRINTF_NEWLINE);
+      return;
+    }
+    if (addr == 0xFFFF)
+    {
+      printf("Invalid Address: 0xFFFF  reserved for broadcast.%s", CFG_PRINTF_NEWLINE);
+      return;
+    }
+
+    // Write address to EEPROM and update peripheral control block
+    chb_set_short_addr((uint16_t)addr);
+    chb_pcb_t *pcb = chb_get_pcb();
+    printf("Address set to: 0x%04X%s", pcb->src_addr, CFG_PRINTF_NEWLINE);
+  }
+  else
+  {
+    // Display the current address
+    chb_pcb_t *pcb = chb_get_pcb();
+    printf("0x%04X%s", pcb->src_addr, CFG_PRINTF_NEWLINE);
+  }
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/cli/commands/cmd_chibi_tx.c b/reform2-lpc-fw/src/cli/commands/cmd_chibi_tx.c
new file mode 100644
index 0000000000000000000000000000000000000000..21449447510f024f5864554e9828edcb1b348e50
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/commands/cmd_chibi_tx.c
@@ -0,0 +1,107 @@
+/**************************************************************************/
+/*!
+    @file     cmd_chibi_tx.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Code to execute for cmd_chibi_tx in the 'core/cmd'
+              command-line interpretter.
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2010, microBuilder SARL
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <stdio.h>
+#include <string.h>
+
+#include "projectconfig.h"
+#include "cli/cli.h"
+#include "cli/commands.h"       // Generic helper functions
+#include "boards/board.h"       // boardLED
+
+#ifdef CFG_CHIBI
+  #include "drivers/rf/802.15.4/chibi/chb.h"
+  #include "drivers/rf/802.15.4/chibi/chb_drvr.h"
+
+/**************************************************************************/
+/*!
+    Sends text or data via Chibi
+
+*/
+/**************************************************************************/
+void cmd_chibi_tx(uint8_t argc, char **argv)
+{
+  uint8_t i, len, *data_ptr, data[50], result;
+  uint16_t addr;
+
+  // Try to convert supplied address to an integer
+  int32_t addr32;
+  getNumber (argv[0], &addr32);
+
+  // Check for invalid values (getNumber may complain about this as well)
+  if (addr32 <= 0 || addr32 > 0xFFFF)
+  {
+    printf("Invalid Address: 1-65534 or 0x0001-0xFFFE required.%s", CFG_PRINTF_NEWLINE);
+    return;
+  }
+
+  // Address seems to be OK
+  addr = (uint16_t)addr32;
+
+  // Get message contents
+  data_ptr = data;
+  for (i=0; i<argc-1; i++)
+  {
+    len = strlen(argv[i+1]);
+    strcpy((char *)data_ptr, (char *)argv[i+1]);
+    data_ptr += len;
+    *data_ptr++ = ' ';
+  }
+  *data_ptr++ = '\0';
+
+  // Send message
+  boardLED(CFG_LED_ON);
+  result = chb_write(addr, data, data_ptr - data);
+  if (result != CHB_SUCCESS)
+  {
+    switch (result)
+    {
+      case CHB_NO_ACK:
+        printf("ERROR: No ACK received%s", CFG_PRINTF_NEWLINE);
+        break;
+      case CHB_CHANNEL_ACCESS_FAILURE:
+        printf("ERROR: Channel access failure%s", CFG_PRINTF_NEWLINE);
+        break;
+      default:
+        break;
+    }
+  }
+  boardLED(CFG_LED_OFF);
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/cli/commands/cmd_dbg_memrd.c b/reform2-lpc-fw/src/cli/commands/cmd_dbg_memrd.c
new file mode 100644
index 0000000000000000000000000000000000000000..e6fb4c30549f9b5ec7d6d540a4a0318e7b3a248d
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/commands/cmd_dbg_memrd.c
@@ -0,0 +1,85 @@
+/**************************************************************************/
+/*!
+    @file     cmd_dbg_memrd.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Reads the contents of memory at a specific address.0
+    @ingroup  CLI
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <stdio.h>
+
+#include "projectconfig.h"
+#include "cli/cli.h"
+#include "cli/commands.h"       // Generic helper functions
+
+/**************************************************************************/
+/*!
+    Command handler
+*/
+/**************************************************************************/
+void cmd_dbg_memrd(uint8_t argc, char **argv)
+{
+  uint32_t startAddr;
+  int32_t  i, s;
+  int32_t  len = 4;
+  int32_t  size = 4;
+
+  /* Warning: This command is extremely dangerous and can easily
+     lead to a hardfault ... use with care! */
+
+  getNumberU32(argv[0], &startAddr);
+  if (argc > 1) getNumber(argv[1], &len);
+  if (argc == 3) getNumber(argv[2], &size);
+
+  /* Make sure size is something sane */
+  if ((size < 1) || (size > 8))
+  {
+    printf("%s %d%s", STRING(LOCALISATION_TEXT_Invalid_argument), (int)size, CFG_PRINTF_NEWLINE);
+    return;
+  }
+
+  s = 0;
+  for (i = 0; i<len; i++)
+  {
+    /* Get the aligned word address (M0 can't do unaligned access!) */
+    uint32_t mem = *(uint32_t*)(startAddr+i - ((startAddr+i) % 4));
+
+    s++;
+    printf("%02X", (unsigned int)((mem >> (8*(3-((startAddr+i) % 4)))) & 0xFF));
+    if (s == size)
+    {
+      printf(" ");
+      s = 0;
+    }
+  }
+}
diff --git a/reform2-lpc-fw/src/cli/commands/cmd_eeprom_read.c b/reform2-lpc-fw/src/cli/commands/cmd_eeprom_read.c
new file mode 100644
index 0000000000000000000000000000000000000000..f4703913e698095bc7b56a2944697eab3b6c27ae
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/commands/cmd_eeprom_read.c
@@ -0,0 +1,74 @@
+/**************************************************************************/
+/*!
+    @file     cmd_eeprom_read.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Code to execute for cmd_eeprom_read in the cli
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <stdio.h>
+
+#include "projectconfig.h"
+#include "cli/cli.h"
+#include "cli/commands.h"       // Generic helper functions
+#include "core/eeprom/eeprom.h"
+
+/**************************************************************************/
+/*!
+    Reads a single byte at the supplied EEPROM address
+*/
+/**************************************************************************/
+void cmd_eeprom_read(uint8_t argc, char **argv)
+{
+  // Try to convert supplied address to an integer
+  int32_t addr32;
+  getNumber (argv[0], &addr32);
+
+  // Check for invalid values (getNumber may complain about this as well)
+  if (addr32 < 0 || addr32 > CFG_EEPROM_SIZE)
+  {
+    printf("Address out of range%s", CFG_PRINTF_NEWLINE);
+    return;
+  }
+
+  // Address seems to be OK
+  uint8_t value[1] = { 0x00 };
+  err_t error = readEEPROM((uint8_t*) addr32, value, 1);
+  if (!error)
+  {
+    printf("0x%02X%s", value[0], CFG_PRINTF_NEWLINE);
+  }
+  else
+  {
+    printf("Error reading EEPROM: %d%s", error, CFG_PRINTF_NEWLINE);
+  }
+}
diff --git a/reform2-lpc-fw/src/cli/commands/cmd_eeprom_write.c b/reform2-lpc-fw/src/cli/commands/cmd_eeprom_write.c
new file mode 100644
index 0000000000000000000000000000000000000000..e2fc61eba7fc17b89ad135965c349d476d2fe6be
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/commands/cmd_eeprom_write.c
@@ -0,0 +1,97 @@
+/**************************************************************************/
+/*!
+    @file     cmd_eeprom_write.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Code to execute for cmd_eeprom_write in the cli
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <stdio.h>
+
+#include "projectconfig.h"
+#include "cli/cli.h"
+#include "cli/commands.h"       // Generic helper functions
+#include "core/eeprom/eeprom.h"
+
+/**************************************************************************/
+/*!
+    Writes a single byte at the supplied EEPROM address
+*/
+/**************************************************************************/
+void cmd_eeprom_write(uint8_t argc, char **argv)
+{
+  uint8_t val;
+
+  // Try to convert supplied address to an integer
+  int32_t addr32;
+  getNumber (argv[0], &addr32);
+
+  // Check for invalid values (getNumber may complain about this as well)
+  if (addr32 < 0 || addr32 > CFG_EEPROM_SIZE)
+  {
+    printf("Address out of range %s", CFG_PRINTF_NEWLINE);
+    return;
+  }
+
+  // Make sure this isn't in the reserved system config space
+  if (addr32 <= CFG_EEPROM_RESERVED)
+  {
+    printf("ERROR: Reserved address (0x%04X-0x%04X)%s", 0, CFG_EEPROM_RESERVED, CFG_PRINTF_NEWLINE);
+    return;
+  }
+
+  // Try to convert supplied data to an integer
+  int32_t val32;
+  getNumber (argv[1], &val32);
+
+  // Check for invalid values (getNumber may complain about this as well)
+  if (val32 < 0 || val32 > 0xFF)
+  {
+    printf("Invalid Data: 0-255 or 0x00-0xFF required.%s", CFG_PRINTF_NEWLINE);
+    return;
+  }
+
+  // Data seems to be OK
+  val = (uint8_t)val32;
+
+  // Write data at supplied address
+  err_t error = writeEEPROM((uint8_t*)addr32, (uint8_t *)&val, 1);
+  if (error)
+  {
+    printf("Error reading EEPROM: %d%s", error, CFG_PRINTF_NEWLINE);
+  }
+  else
+  {
+    printf("0x%02X written at 0x%04X%s", val, (uint16_t)addr32 & 0xFFFF, CFG_PRINTF_NEWLINE);
+  }
+}
+
diff --git a/reform2-lpc-fw/src/cli/commands/cmd_i2c_read.c b/reform2-lpc-fw/src/cli/commands/cmd_i2c_read.c
new file mode 100644
index 0000000000000000000000000000000000000000..34babd127e48f675d1fd7c6e6c84159e7f91fee1
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/commands/cmd_i2c_read.c
@@ -0,0 +1,139 @@
+/**************************************************************************/
+/*!
+    @file     cmd_i2c_read.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Reads the specified number of bytes on the I2C bus.
+    @ingroup  CLI
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microbuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <stdio.h>
+
+#include "projectconfig.h"
+#include "core/i2c/i2c.h"
+#include "cli/commands.h"           // Generic helper functions
+
+#if defined(CFG_ENABLE_I2C)
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+/**************************************************************************/
+/*!
+    @brief  Calls the underlying I2C driver (private function)
+*/
+/**************************************************************************/
+err_t cmd_i2cReadWrapper(uint8_t addr, uint8_t len, uint8_t* values)
+{
+  uint8_t i;
+
+  I2CWriteLength = 0;
+  I2CReadLength = len;
+  I2CMasterBuffer[0] = (addr << 1) | 0x01;
+
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  /* Copy payload into the buffer */
+  for (i=0;i<len;i++)
+  {
+    values[i] = I2CSlaveBuffer[i];
+  }
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    'sysinfo' command handler
+*/
+/**************************************************************************/
+void cmd_i2c_read(uint8_t argc, char **argv)
+{
+  err_t error;
+  int32_t addr32;
+  uint8_t addr;
+  int32_t len32;
+  uint8_t len;
+  uint8_t values[I2C_BUFSIZE];
+
+  getNumber(argv[0], &addr32);
+  getNumber(argv[1], &len32);
+
+  /* Make sure addr is valid */
+  if ((addr32 < 0x03) || (addr32 > 0x78))
+  {
+    printf("%s%s", STRING(LOCALISATION_TEXT_Invalid_I2C_Address), CFG_PRINTF_NEWLINE);
+    return;
+  }
+  addr = (uint8_t)addr32 & 0xFF;
+
+  /* Make sure len is valid */
+  if ((len32 > I2C_BUFSIZE) || (len32 < 1))
+  {
+    printf("%s %d%s", STRING(LOCALISATION_TEXT_len_must_be_less_than_equal), I2C_BUFSIZE, CFG_PRINTF_NEWLINE);
+    return;
+  }
+  len = (uint8_t)len32 & 0xFF;
+
+  /* Send read command */
+  error = cmd_i2cReadWrapper(addr, len, values);
+
+  /* Handle error cases */
+  if (error)
+  {
+    switch(error)
+    {
+      case ERROR_I2C_NOACK:
+        printf("%s%s", STRING(LOCALISATION_TEXT_No_ACK_received), CFG_PRINTF_NEWLINE);
+        break;
+      case ERROR_I2C_TIMEOUT:
+        printf("%s%s", STRING(LOCALISATION_TEXT_Timeout), CFG_PRINTF_NEWLINE);
+        break;
+      default:
+        printf("%s: %04X%s", STRING(LOCALISATION_TEXT_Unknown_Error), error, CFG_PRINTF_NEWLINE);
+        break;
+    }
+    return;
+  }
+
+  /* Print values */
+  uint8_t i;
+  for (i=0;i<len;i++)
+  {
+    printf("%02X ", values[i]);
+  }
+  printf("%s", CFG_PRINTF_NEWLINE);
+}
+
+#endif /* CFG_ENABLE_I2C */
diff --git a/reform2-lpc-fw/src/cli/commands/cmd_i2c_scan.c b/reform2-lpc-fw/src/cli/commands/cmd_i2c_scan.c
new file mode 100644
index 0000000000000000000000000000000000000000..1af6cf2e03c23914087dbd93ad7d232c3b1d0321
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/commands/cmd_i2c_scan.c
@@ -0,0 +1,95 @@
+/**************************************************************************/
+/*!
+    @file     cmd_i2c_scan.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Scans the I2C bus and displays a list of any addresses where
+	          a valid I2C response occured.
+    @ingroup  CLI
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microbuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <stdio.h>
+
+#include "projectconfig.h"
+#include "core/i2c/i2c.h"
+
+#if defined(CFG_ENABLE_I2C)
+
+/**************************************************************************/
+/*!
+    'sysinfo' command handler
+*/
+/**************************************************************************/
+void cmd_i2c_scan(uint8_t argc, char **argv)
+{
+  uint8_t addr;
+  bool match;
+
+  i2cInit(I2CMASTER);
+
+  // "Scanning I2C bus for devices"
+  printf("%s%s%s", STRING(LOCALISATION_TEXT_Scanning_I2C_bus_for_devices), CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+  printf("     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F%s", CFG_PRINTF_NEWLINE);
+  printf("00:          ");
+
+  // Scan through I2C address range (0x03-0x77)
+  for (addr = 0x03; addr < 0x78; addr++)
+  {
+    if (!(addr % 0x10))
+    {
+      printf("%s", CFG_PRINTF_NEWLINE);
+      printf("%X: ", addr);
+    }
+
+    // Check if we get an ACK at this address
+    match = i2cCheckAddress(addr << 1);
+    if (match)
+    {
+      // I2C device found
+      printf("%02x ", addr);
+    }
+    else
+    {
+      // I2C slave didn't acknowledge the master transfer
+      // The device probably isn't connected
+      printf("-- ");
+    }
+  }
+
+  printf("%s%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+  // "All addresses are in 7-bit format and are not"
+  printf("%s%s", STRING(LOCALISATION_TEXT_All_addresses_are_in_7bit_L1), CFG_PRINTF_NEWLINE);
+  // "shifted to include the read bit."
+  printf("%s%s", STRING(LOCALISATION_TEXT_All_addresses_are_in_7bit_L2), CFG_PRINTF_NEWLINE);
+}
+
+#endif /* CFG_ENABLE_I2C */
diff --git a/reform2-lpc-fw/src/cli/commands/cmd_i2c_write.c b/reform2-lpc-fw/src/cli/commands/cmd_i2c_write.c
new file mode 100644
index 0000000000000000000000000000000000000000..d48bfea95177e76eba1358303478bd6838ac8311
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/commands/cmd_i2c_write.c
@@ -0,0 +1,140 @@
+/**************************************************************************/
+/*!
+    @file     cmd_i2c_write.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Writes the specified number of bytes on the I2C bus.
+    @ingroup  CLI
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microbuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <stdio.h>
+
+#include "projectconfig.h"
+#include "core/i2c/i2c.h"
+#include "cli/commands.h"           // Generic helper functions
+
+#if defined(CFG_ENABLE_I2C)
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+/**************************************************************************/
+/*!
+    @brief  Calls the underlying I2C driver (private function)
+*/
+/**************************************************************************/
+err_t cmd_i2cWriteWrapper(uint8_t addr, uint8_t len, uint8_t* values)
+{
+  uint8_t i;
+
+  I2CWriteLength = len;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = (addr << 1);
+  /* Copy payload into the buffer */
+  for (i=0;i<len-1;i++)
+  {
+    I2CMasterBuffer[i+1] = values[i];
+  }
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    'sysinfo' command handler
+*/
+/**************************************************************************/
+void cmd_i2c_write(uint8_t argc, char **argv)
+{
+  err_t error;
+  int32_t addr32;
+  uint8_t addr;
+  uint8_t values[I2C_BUFSIZE];
+
+  getNumber(argv[0], &addr32);
+
+  /* Make sure addr is valid */
+  if ((addr32 < 0x03) || (addr32 > 0x78))
+  {
+	    printf("%s%s", STRING(LOCALISATION_TEXT_Invalid_I2C_Address), CFG_PRINTF_NEWLINE);
+    return;
+  }
+  addr = (uint8_t)addr32 & 0xFF;
+
+  /* Make sure len is valid */
+  if (argc-1 > I2C_BUFSIZE)
+  {
+    printf("%s (%d %s)%s", STRING(LOCALISATION_TEXT_Too_large_for_I2C_buffer), I2C_BUFSIZE, STRING(LOCALISATION_TEXT_bytes), CFG_PRINTF_NEWLINE);
+    return;
+  }
+
+  /* Copy payload into the target buffer */
+  uint8_t i;
+  int32_t val;
+  for (i=1;i<argc;i++)
+  {
+    getNumber(argv[i], &val);
+    if ((val > 0xFF) || (val < 0))
+    {
+      printf("%s (%d)%s", STRING(LOCALISATION_TEXT_Invalid_argument), i, CFG_PRINTF_NEWLINE);
+      return;
+    }
+    values[i-1] = (uint8_t)val & 0xFF;
+  }
+
+  /* Send write command */
+  error = cmd_i2cWriteWrapper(addr, argc, values);
+
+  /* Handle error cases */
+  if (error)
+  {
+    switch(error)
+    {
+      case ERROR_I2C_NOACK:
+        printf("%s%s", STRING(LOCALISATION_TEXT_No_ACK_received), CFG_PRINTF_NEWLINE);
+        break;
+      case ERROR_I2C_TIMEOUT:
+        printf("%s%s", STRING(LOCALISATION_TEXT_Timeout), CFG_PRINTF_NEWLINE);
+        break;
+      default:
+        printf("%s: %04X%s", STRING(LOCALISATION_TEXT_Unknown_Error), error, CFG_PRINTF_NEWLINE);
+        break;
+    }
+    return;
+  }
+
+  printf("%s%s", STRING(LOCALISATION_TEXT_OK), CFG_PRINTF_NEWLINE);
+}
+
+#endif /* CFG_ENABLE_I2C */
diff --git a/reform2-lpc-fw/src/cli/commands/cmd_nfc_mfc_ndef.c b/reform2-lpc-fw/src/cli/commands/cmd_nfc_mfc_ndef.c
new file mode 100644
index 0000000000000000000000000000000000000000..3c6d60b53e4f013776473cd555d3280a77dbf968
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/commands/cmd_nfc_mfc_ndef.c
@@ -0,0 +1,654 @@
+/**************************************************************************/
+/*!
+    @file     cmd_nfc_mifareultralight_memdump.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @ingroup  CLI
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013 K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <stdio.h>
+
+#include "projectconfig.h"
+
+#ifdef CFG_PN532
+
+#include "core/gpio/gpio.h"
+#include "cli/cli.h"
+#include "cli/commands.h"
+
+#include "drivers/rf/nfc/pn532/pn532.h"
+#include "drivers/rf/nfc/pn532/pn532_bus.h"
+#include "drivers/rf/nfc/pn532/helpers/pn532_config.h"
+#include "drivers/rf/nfc/pn532/helpers/pn532_mifare_classic.h"
+#include "drivers/rf/nfc/pn532/helpers/pn532_ndef.h"
+#include "drivers/rf/nfc/pn532/helpers/pn532_ndef_cards.h"
+
+void message_dump(pn532_ndef_message_t mess);
+void print_tag_tech(Tag_t  *pTag);
+void print_tag_type(Tag_t *pTag);
+
+pn532_ndef_message_t gNdefMess = NULL;
+/**************************************************************************/
+/*
+ @brief 'cmd_nfc_mfc_ndef_memdump' dump a NFC formated Tags. Input value
+ if present is a timeout period of the waiting Tag present time.
+ @param argc [in]: argument counter
+ @param argv [in]: list of argument value
+ @return: void
+ */
+/**************************************************************************/
+void cmd_nfc_mfc_ndef_memdump(uint8_t argc, char **argv)
+{
+        pn532_error_t error;
+        int32_t timeout;
+        bool retriesChanged = false;
+        uint8_t sak;
+        uint16_t atqa;
+        Tag_t tag;
+        // Set a timeout waiting for passive targets (default = 0xFF, wait forever)
+        if (argc > 0)
+        {
+                getNumber(argv[0], &timeout);
+                if (timeout > 0xFF || timeout < 0)
+                {
+                        printf("\n\rInvalid timeout [0..255]%s", CFG_PRINTF_NEWLINE);
+                        return;
+                }
+                else if (timeout > 0 || timeout < 0xFF)
+                {
+                        // We can safely ignore errors here since there is a default value anyway
+                        pn532_config_SetPassiveActivationRetries(timeout);
+                        retriesChanged = true;
+                }
+        }
+        //clean up old ndef message
+        // Use the MIFARE Classic Helper to read/write to the tag's EEPROM storage
+        printf("Please place a Mifare Classic 1K or 4K card with NDEF data inside %s%s",
+                CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+
+        error = pn532_mifareclassic_WaitForTypeATags(&sak, &atqa, &tag.uid[0],
+                (size_t*) &tag.lenUid);
+
+        if (!error)
+        {
+                error = pn532_ndef_mfc_tagType_identify(sak, atqa, &tag);
+                if (error != PN532_ERROR_NONE)
+                {
+                        printf("\n\rIdentify tag error, code = 0x%02X", error);
+                }
+                print_tag_tech(&tag);
+
+                error = pn532_ndef_mfc_get_tagType(&tag);
+                if (error != PN532_ERROR_NONE)
+                {
+                        printf("\n\rGet tag type error, code = 0x%02X", error);
+                        return;
+                }
+
+                //print out Ndef tag type
+                print_tag_type(&tag);
+
+                if ((tag.type != TAG_TYPE_MFC_1K) && (tag.type != TAG_TYPE_MFC_4K))
+                {
+                        printf("\n\rOnly support Mifare Classic 1K or 4K");
+                        return;
+                }
+
+                //destroy previous message then destroy it to avoid memory leak
+                if ((gNdefMess)&&(pn532_ndef_getNumberOfRecords(gNdefMess)))
+                {
+                        pn532_ndef_destroy(gNdefMess);
+                        gNdefMess = NULL;
+                }
+
+                error = pn532_ndef_mfc_parseNtag(&tag, &gNdefMess);
+
+                if (error != PN532_ERROR_NONE)
+                {
+                if (error == PN532_ERROR_NOT_NDEF_CARD)
+                {
+                  printf("\n\rCard has no Ndef Message");
+                  printf("\n\rPlease create a Ndef Message by 'npn' command and then write to card!!!");
+                }
+                else
+                {
+                        printf("\n\rparsing tag error, code = 0x%02X", error);
+                }
+                        return;
+                }
+
+                message_dump(gNdefMess);
+
+        }
+        else
+        {
+                switch (error)
+                {
+                        case PN532_ERROR_TIMEOUTWAITINGFORCARD:
+                                printf("\n\rTimed out waiting for a card%s", CFG_PRINTF_NEWLINE);
+                                break;
+                        default:
+                                printf("\n\rError establishing passive connection (0x%02x)%s",
+                                        error, CFG_PRINTF_NEWLINE);
+                                break;
+                }
+        }
+
+        // Set retry count back to infinite if it was changed
+        if (retriesChanged)
+        {
+                pn532_config_SetPassiveActivationRetries(0xFF);
+        }
+}
+
+void message_dump(pn532_ndef_message_t mess)
+{
+        uint8_t idx, numberOfRecord;
+        pn532_ndef_record_t pRecord;
+
+        numberOfRecord = pn532_ndef_getNumberOfRecords(mess);
+
+        for (idx=0; idx<numberOfRecord; idx++)
+        {
+                pRecord = pn532_ndef_getRecord(mess, idx);
+
+                printf("MB: %d\r\n", pn532_ndef_getMB(pRecord));
+                printf("ME: %d\r\n", pn532_ndef_getME(pRecord));
+                printf("TNF: %d\r\n", pn532_ndef_getTNF(pRecord));
+                printf("Type: ");
+
+                pn532PrintHex(pn532_ndef_getType(pRecord), pn532_ndef_getTypeLength(pRecord));
+                printf("\n\rId: ");
+                pn532PrintHex(pn532_ndef_getId(pRecord), pn532_ndef_getIdLength(pRecord));
+                printf("\n\rPayload: ");
+                pn532PrintHex(pn532_ndef_getPayload(pRecord), pn532_ndef_getPayloadLength(pRecord));
+                printf("\n\rEntire: ");
+                pn532PrintHexChar(pn532_ndef_getAll(pRecord), pn532_ndef_getLength(pRecord));
+                printf("\r\n");
+        }
+
+        return;
+}
+
+void print_tag_tech(Tag_t  *pTag)
+{
+        switch (pTag->type)
+        {
+                case TAG_TYPE_MFC_1K:
+                        printf("\n\r Mifare 1K detected");
+                        break;
+                case TAG_TYPE_MFC_4K:
+                        printf("\n\r Mifare 4K detected");
+                        break;
+                case TAG_TYPE_MFPLUS_S_2K:
+                        printf("\n\r Mifare Plus S 2K detected");
+                        break;
+                case TAG_TYPE_MFPLUS_S_4K:
+                        printf("\n\r Mifare Plus S 4K detected");
+                        break;
+                case TAG_TYPE_MFPLUS_X_2K:
+                        printf("\n\r Mifare Plus x 2K detected");
+                        break;
+                case TAG_TYPE_MFPLUS_X_4K:
+                        printf("\n\r Mifare Plus x 4K detected");
+                        break;
+                case TAG_TYPE_MF_MINI:
+                        printf("\n\r Mifare Mini detected");
+                        break;
+                case TAG_TYPE_MF_ULTRALIGHT:
+                        printf("\n\r Mifare Ultralight detected");
+                        break;
+                default:
+                        printf("\n\r Unknown card detected");
+                        break;
+        }
+        return;
+}
+
+void print_tag_type(Tag_t *pTag)
+{
+        switch (pTag->ndefType)
+        {
+                case NDEF_TAG_TYPE_BLANK:
+                        printf("\n\rType blank card");
+                        break;
+                case NDEF_TAG_TYPE_NDEF_READ_ONLY:
+                        printf("\n\rType read only card");
+                        break;
+                case NDEF_TAG_TYPE_NDEF_WRITE_ENABLE:
+                        printf("\n\rType read/write card");
+                        break;
+                case NDEF_TAG_UNKNOWN:
+                        printf("\n\rUnknown card");
+                        break;
+                default:
+                        break;
+        }
+        return;
+}
+
+/**************************************************************************/
+/*
+    @brief 'cmd_nfc_mfc_ndef_blankFormat' format a Mifare Classic NFC tag to
+        become Blank by using transportation keys and default data . Input value
+        if present is a timeout period of the waiting Tag present time.
+        @param argc [in]: argument counter
+        @param argv [in]: list of argument value
+        @return: void
+*/
+/**************************************************************************/
+void cmd_nfc_mfc_ndef_blankFormat(uint8_t argc, char **argv)
+{
+        pn532_error_t error;
+        int32_t timeout;
+        bool retriesChanged = false;
+        uint8_t sak;
+        uint16_t atqa;
+        Tag_t tag;
+        // Set a timeout waiting for passive targets (default = 0xFF, wait forever)
+        if (argc > 0)
+        {
+                getNumber(argv[0], &timeout);
+                if (timeout > 0xFF || timeout < 0)
+                {
+                        printf("Invalid timeout [0..255]%s", CFG_PRINTF_NEWLINE);
+                        return;
+                }
+                else if (timeout > 0 || timeout < 0xFF)
+                {
+                        // We can safely ignore errors here since there is a default value anyway
+                        pn532_config_SetPassiveActivationRetries(timeout);
+                        retriesChanged = true;
+                }
+        }
+
+        // Use the MIFARE Classic Helper to read/write to the tag's EEPROM storage
+        printf("Please place a Nfc formated Mifare Classic 1K or 4K card %s%s",
+                CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+
+        // Wait for any ISO14443A card
+        error = pn532_mifareclassic_WaitForTypeATags(&sak, &atqa, &tag.uid[0], (size_t*)&tag.lenUid);
+        if (!error)
+        {
+                error = pn532_ndef_mfc_tagType_identify(sak, atqa, &tag);
+                if (error != PN532_ERROR_NONE)
+                {
+                        printf("identify tag error, code = 0x%02X", error);
+                        return;
+                }
+                print_tag_tech(&tag);
+
+                error = pn532_ndef_mfc_get_tagType(&tag);
+                if (error != PN532_ERROR_NONE)
+                {
+                        printf("get tag type error, code = 0x%02X", error);
+                        return;
+                }
+                //print out Ndef tag type
+                print_tag_type(&tag);
+
+                if ((tag.type != TAG_TYPE_MFC_1K) && (tag.type != TAG_TYPE_MFC_4K))
+                {
+                        printf("\n\rOnly support Mifare Classic 1K or 4K");
+                        return;
+                }
+
+                //after check card, formatting card
+                error = pn532_ndef_mfc_blank_format(&tag);
+                if (error != PN532_ERROR_NONE)
+                {
+                        printf("\n\rFormat to blank card error");
+                        return;
+                }
+                else
+                {
+                        printf("\n\rFormat to blank card success");
+                }
+        }
+        else
+        {
+                switch (error)
+                {
+                        case PN532_ERROR_TIMEOUTWAITINGFORCARD:
+                                printf("Timed out waiting for a card%s", CFG_PRINTF_NEWLINE);
+                                break;
+                        default:
+                                printf("Error establishing passive connection (0x%02x)%s",
+                                        error, CFG_PRINTF_NEWLINE);
+                                break;
+                }
+        }
+
+        // Set retry count back to infinite if it was changed
+        if (retriesChanged)
+        {
+                pn532_config_SetPassiveActivationRetries(0xFF);
+        }
+}
+
+
+/**************************************************************************/
+/*
+    @brief 'cmd_nfc_mfc_ndef_blankFormat' format a Mifare Classic NFC tag to
+        become Blank by using transportation keys and default data . Input value
+        if present is a timeout period of the waiting Tag present time.
+        @param argc [in]: argument counter
+        @param argv [in]: list of argument value
+        @return: void
+*/
+/**************************************************************************/
+void cmd_nfc_mfc_ndef_nfcFormat(uint8_t argc, char **argv)
+{
+        pn532_error_t error;
+        int32_t timeout;
+        bool retriesChanged = false;
+        uint8_t sak;
+        uint16_t atqa;
+        Tag_t tag;
+        // Set a timeout waiting for passive targets (default = 0xFF, wait forever)
+        if (argc > 0)
+        {
+                getNumber(argv[0], &timeout);
+                if (timeout > 0xFF || timeout < 0)
+                {
+                        printf("Invalid timeout [0..255]%s", CFG_PRINTF_NEWLINE);
+                        return;
+                }
+                else if (timeout > 0 || timeout < 0xFF)
+                {
+                        // We can safely ignore errors here since there is a default value anyway
+                        pn532_config_SetPassiveActivationRetries(timeout);
+                        retriesChanged = true;
+                }
+        }
+
+        // Use the MIFARE Classic Helper to read/write to the tag's EEPROM storage
+        printf("Please place a Nfc formated Mifare Classic 1K or 4K card %s%s",
+                CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+
+        // Wait for any ISO14443A card
+        error = pn532_mifareclassic_WaitForTypeATags(&sak, &atqa, &tag.uid[0], (size_t*)&tag.lenUid);
+        if (!error)
+        {
+                error = pn532_ndef_mfc_tagType_identify(sak, atqa, &tag);
+                if (error != PN532_ERROR_NONE)
+                {
+                        printf("identify tag error, code = 0x%02X", error);
+                        return;
+                }
+                print_tag_tech(&tag);
+
+                error = pn532_ndef_mfc_get_tagType(&tag);
+                if (error != PN532_ERROR_NONE)
+                {
+                        printf("get tag type error, code = 0x%02X", error);
+                        return;
+                }
+
+                //print out Ndef tag type
+                print_tag_type(&tag);
+
+                if ((tag.type != TAG_TYPE_MFC_1K) && (tag.type != TAG_TYPE_MFC_4K))
+                {
+                        printf("\n\rOnly support Mifare Classic 1K or 4K");
+                        return;
+                }
+
+                error = pn532_ndef_mfc_nfc_format(&tag, True);
+                if (error != PN532_ERROR_NONE)
+                {
+                        printf("\n\rFormat to NFC format error");
+                        return;
+                }
+                else
+                {
+                        printf("\n\rFormat to NFC format success");
+                }
+        }
+        else
+        {
+                switch (error)
+                {
+                        case PN532_ERROR_TIMEOUTWAITINGFORCARD:
+                                printf("Timed out waiting for a card%s", CFG_PRINTF_NEWLINE);
+                                break;
+                        default:
+                                printf("Error establishing passive connection (0x%02x)%s",
+                                        error, CFG_PRINTF_NEWLINE);
+                                break;
+                }
+        }
+
+        // Set retry count back to infinite if it was changed
+        if (retriesChanged)
+        {
+                pn532_config_SetPassiveActivationRetries(0xFF);
+        }
+}
+
+/**************************************************************************/
+/*
+ @brief 'cmd_nfc_mfc_ndef_write_ndef' write a Ndef form a card. Input value
+ if present is a timeout period of the waiting Tag present time.
+ @param argc [in]: argument counter
+ @param argv [in]: list of argument value
+ @return: void
+ */
+/**************************************************************************/
+void cmd_nfc_mfc_ndef_write_ndef(uint8_t argc, char **argv)
+{
+        pn532_error_t error;
+        bool retriesChanged = false;
+        uint8_t sak;
+        uint16_t atqa;
+        Tag_t tag;
+        uint32_t sector = 1; //default
+
+        // Set a timeout waiting for passive targets (default = 0xFF, wait forever)
+
+        // Use the MIFARE Classic Helper to read/write to the tag's EEPROM storage
+        printf("Please place a Nfc formated Mifare Classic 1K or 4K card %s%s",
+                CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+
+        // Wait for any ISO14443A card
+        error = pn532_mifareclassic_WaitForTypeATags(&sak, &atqa, &tag.uid[0], (size_t*)&tag.lenUid);
+        if (!error)
+        {
+                error = pn532_ndef_mfc_tagType_identify(sak, atqa, &tag);
+                if (error != PN532_ERROR_NONE)
+                {
+                        printf("identify tag error, code = 0x%02X", error);
+                        return;
+                }
+                print_tag_tech(&tag);
+
+                error = pn532_ndef_mfc_get_tagType(&tag);
+                if (error != PN532_ERROR_NONE)
+                {
+                        printf("get tag type error, code = 0x%02X", error);
+                        return;
+                }
+
+                //print out Ndef tag type
+                print_tag_type(&tag);
+
+                if ((tag.type != TAG_TYPE_MFC_1K) && (tag.type != TAG_TYPE_MFC_4K))
+                {
+                        printf("\n\rOnly support Mifare Classic 1K or 4K");
+                        return;
+                }
+
+                if (gNdefMess)
+                {
+                        error = pn532_ndef_mfc_ndef_write(&tag, (pn532_ndef_record_t)gNdefMess,
+                                (uint8_t) sector);
+                        if (error != PN532_ERROR_NONE)
+                        {
+                                printf("\n\rWrite NDEF to card error");
+                                return;
+                        }
+                        else
+                        {
+                                printf("\n\rWrite NDEF to card success");
+                        }
+                }
+                else
+                {
+                        printf("\n\rNdef Message empty!!!! ");
+                }
+        }
+        else
+        {
+                switch (error)
+                {
+                        case PN532_ERROR_TIMEOUTWAITINGFORCARD:
+                                printf("Timed out waiting for a card%s", CFG_PRINTF_NEWLINE);
+                                break;
+                        default:
+                                printf("Error establishing passive connection (0x%02x)%s",
+                                        error, CFG_PRINTF_NEWLINE);
+                                break;
+                }
+        }
+
+        // Set retry count back to infinite if it was changed
+        if (retriesChanged)
+        {
+                pn532_config_SetPassiveActivationRetries(0xFF);
+        }
+}
+
+/**************************************************************************/
+/*
+ @brief 'cmd_nfc_mfc_ndef_prepare_ndefMessage' create a Ndef Message to write to card
+ @return: void
+ */
+/**************************************************************************/
+void cmd_nfc_mfc_ndef_prepare_ndefMessage(uint8_t argc, char **argv)
+{
+        uint16_t length;
+        uint8_t terminalBuff[4];
+        uint8_t ndefPayloadBuff[256];
+        uint8_t ndefType;
+        uint8_t ndefTnf = NDEF_TNF_WELL_KNOWN;
+        uint8_t payloadLength;
+        pn532_error_t errCode;
+
+        while (1)
+        {
+                printf("\r\n1. Bookmark/URI");
+                printf("\r\n2. Text");
+                printf("\r\n3. SMS");
+                printf("\r\nPress a number to select type of Ndef Message:");
+                // get type of ndef message
+                length = sizeof(terminalBuff);
+                cliReadLine(&terminalBuff[0], &length);
+                if ((length == 1) && (terminalBuff[0] >= '1') && (terminalBuff[0] <= '3'))
+                {
+                        ndefType = terminalBuff[0];
+                        break;
+                }
+        }
+
+        switch (ndefType)
+        {
+                case '1':
+                        ndefType = 'U';
+                        while (1)
+                        {
+                                printf("\r\n0. N/A");
+                                printf("\r\n1. http://www.");
+                                printf("\r\n2. https://www.");
+                                printf("\r\n3. http://");
+                                printf("\r\n4. https://");
+                                printf("\r\nPress a number to select type of Bookmark:");
+                                // get the bookmark type
+                                length = sizeof(terminalBuff);
+                                cliReadLine(&terminalBuff[0], &length);
+                                if ((length == 1) && (terminalBuff[0] >= '0')
+                                        && (terminalBuff[0] <= '4'))
+                                {
+                                        break;
+                                }
+                        }
+
+                        ndefPayloadBuff[0] = terminalBuff[0] - '0';
+
+                        printf("\n\rEnter the content of NdefMessage:\n\r");
+                        length = sizeof(ndefPayloadBuff) - 1;
+                        cliReadLine(&ndefPayloadBuff[1], &length);
+                        payloadLength = 1 + length;
+
+                        break;
+                case '2':
+                        ndefType = 'T';
+                        length = sizeof(ndefPayloadBuff) - 3;
+                        ndefPayloadBuff[0] = 0x02; //UTF8
+                        ndefPayloadBuff[1] = 'e';
+                        ndefPayloadBuff[2] = 'n';
+                        printf("\r\nEnter a text:\n\r");
+                        cliReadLine(&ndefPayloadBuff[3], &length);
+                        payloadLength = length + 3;
+                        break;
+                case '3':
+                        ndefPayloadBuff[0] = 0x00; //NA
+                        length = sizeof(ndefPayloadBuff) - 1;
+                        printf("\r\nEnter a SMS:\n\r");
+                        cliReadLine(&ndefPayloadBuff[1], &length);
+                        payloadLength = 1 + length;
+                        break;
+                default:
+                        break;
+        }
+
+        //destroy previous message then destroy it to avoid memory leak
+        if ((gNdefMess)&&(pn532_ndef_getNumberOfRecords(gNdefMess)))
+        {
+                pn532_ndef_destroy(gNdefMess);
+                gNdefMess = NULL;
+        }
+
+        errCode = pn532_ndef_createFromValue(&gNdefMess, ndefTnf, &ndefType, 1,
+                                                                                NULL, 0, ndefPayloadBuff, payloadLength);
+        if (errCode != PN532_ERROR_NONE)
+        {
+                printf("Create Ndef Record error, code = 0x%02X", errCode);
+
+        }
+
+        message_dump(gNdefMess);
+
+        return;
+
+}
+
+#endif  // #ifdef CFG_PN532
diff --git a/reform2-lpc-fw/src/cli/commands/cmd_nfc_mifareclassic_memdump.c b/reform2-lpc-fw/src/cli/commands/cmd_nfc_mifareclassic_memdump.c
new file mode 100644
index 0000000000000000000000000000000000000000..4bbcbce4cfb4bd7baa47c9e315be6b1121cfd224
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/commands/cmd_nfc_mifareclassic_memdump.c
@@ -0,0 +1,194 @@
+/**************************************************************************/
+/*!
+    @file     cmd_nfc_mifareclassic_memdump.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Dumps the contents of a Mifare Classic card to the CLI
+    @ingroup  CLI
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <stdio.h>
+
+#include "projectconfig.h"
+
+#ifdef CFG_PN532
+
+#include "core/gpio/gpio.h"
+#include "cli/cli.h"
+#include "cli/commands.h"       // Generic helper functions
+
+#include "core/i2c/i2c.h"
+#include "drivers/rf/nfc/pn532/pn532.h"
+#include "drivers/rf/nfc/pn532/pn532_bus.h"
+#include "drivers/rf/nfc/pn532/helpers/pn532_config.h"
+#include "drivers/rf/nfc/pn532/helpers/pn532_mifare_classic.h"
+#include "drivers/rf/nfc/pn532/helpers/pn532_mifare_ultralight.h"
+
+/**************************************************************************/
+/*!
+    'nfc_mifareclassic_memdump' command handler
+*/
+/**************************************************************************/
+void cmd_nfc_mifareclassic_memdump(uint8_t argc, char **argv)
+{
+  pn532_error_t error;
+  byte_t abtUID[8];
+  byte_t abtBlock[32];
+  size_t szUIDLen;
+  int32_t timeout;
+  bool retriesChanged = false;
+
+  // To dump an NDEF formatted Mifare Classic Card (formatted using NXP TagWriter on Android
+  // for example), you must use the following authentication keys:
+  //
+  //    Sector 0:       0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5
+  //    Sectors 1..15:  0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7
+  //
+  // For more information on NDEF see the following document:
+  //
+  //    AN1305 - MIFARE Classic as NFC Type MIFARE Classic Tag
+  //    http://www.nxp.com/documents/application_note/AN1305.pdf
+
+  // Set this to one for NDEF cards, or 0 for blank factory default cards
+  #define CARDFORMAT_NDEF (0)
+
+  #if CARDFORMAT_NDEF == 1
+    byte_t abtAuthKey1[6] = { 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5 };   // Sector 0 of NXP formatter NDEF cards
+    byte_t abtAuthKey2[6] = { 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7 };   // All other sectors use standard key (AN1305 p.20, Table 6)
+  #else
+    byte_t abtAuthKey1[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+    byte_t abtAuthKey2[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+  #endif
+
+  // Set a timeout waiting for passive targets (default = 0xFF, wait forever)
+  if (argc > 0)
+  {
+    getNumber (argv[0], &timeout);
+    if (timeout > 0xFF || timeout < 0)
+    {
+      printf("Invalid timeout [0..255]%s", CFG_PRINTF_NEWLINE);
+      return;
+    }
+    else if (timeout > 0 || timeout < 0xFF)
+    {
+      // We can safely ignore errors here since there is a default value anyway
+      pn532_config_SetPassiveActivationRetries(timeout);
+      retriesChanged = true;
+    }
+  }
+
+  // Use the MIFARE Classic Helper to read/write to the tag's EEPROM storage
+  printf("Please insert a Mifare Classic 1K or 4K card%s%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+
+  // Wait for any ISO14443A card
+  error = pn532_mifareclassic_WaitForPassiveTarget(abtUID, &szUIDLen);
+  if (!error)
+  {
+    // Mifare classic card found ... cycle through each sector
+    uint8_t block;
+    bool authenticated = false;
+    for (block = 0; block < 64; block++)
+    {
+      // Check if this is a new block so that we can reauthenticate
+      if (pn532_mifareclassic_isFirstBlock(block)) authenticated = false;
+      if (!authenticated)
+      {
+        // Start of a new sector ... try to to authenticate
+        printf("-------------------------Sector %02d--------------------------%s", block / 4, CFG_PRINTF_NEWLINE);
+        error = pn532_mifareclassic_AuthenticateBlock (abtUID, szUIDLen, block, PN532_MIFARE_CMD_AUTH_A, block / 4 ? abtAuthKey2 : abtAuthKey1);
+        if (error)
+        {
+          switch(error)
+          {
+            default:
+              printf("Authentication error (0x%02x)%s", error, CFG_PRINTF_NEWLINE);
+              break;
+          }
+        }
+        else
+        {
+          authenticated = true;
+        }
+      }
+      // If we're still not authenticated just skip the block
+      if (!authenticated)
+      {
+        printf("Block %02d: ", block);
+        printf("Unable to authenticate%s", CFG_PRINTF_NEWLINE);
+      }
+      else
+      {
+        // Authenticated ... we should be able to read the block now
+        error = pn532_mifareclassic_ReadDataBlock (block, abtBlock);
+        if (error)
+        {
+          switch(error)
+          {
+            default:
+              printf("Block %02d: ", block);
+              printf("Unable to read this block%s", CFG_PRINTF_NEWLINE);
+              break;
+          }
+        }
+        else
+        {
+          // Read successful
+          printf("Block %02d: ", block);
+          pn532PrintHexChar(abtBlock, 16);
+        }
+      }
+    }
+  }
+  else
+  {
+    switch (error)
+    {
+      case PN532_ERROR_WRONGCARDTYPE:
+        printf("Wrong card type%s", CFG_PRINTF_NEWLINE);
+        break;
+      case PN532_ERROR_TIMEOUTWAITINGFORCARD:
+        printf("Timed out waiting for a card%s", CFG_PRINTF_NEWLINE);
+        break;
+      default:
+        printf("Error establishing passive connection (0x%02x)%s", error, CFG_PRINTF_NEWLINE);
+        break;
+    }
+  }
+
+  // Set retry count back to infinite if it was changed
+  if (retriesChanged)
+  {
+    pn532_config_SetPassiveActivationRetries(0xFF);
+  }
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/cli/commands/cmd_nfc_mifareclassic_valueblock.c b/reform2-lpc-fw/src/cli/commands/cmd_nfc_mifareclassic_valueblock.c
new file mode 100644
index 0000000000000000000000000000000000000000..634b1f491594dc19a56245b19c42f2c6c61a5c65
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/commands/cmd_nfc_mifareclassic_valueblock.c
@@ -0,0 +1,324 @@
+/**************************************************************************/
+/*!
+    @file     cmd_nfc_mifareclassic_valueblock.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Commands to work with 'Value Blocks' on Mifare Classic cards.
+    @ingroup  CLI
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013 K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <stdio.h>
+
+#include "projectconfig.h"
+
+#ifdef CFG_PN532
+
+#include "core/gpio/gpio.h"
+#include "cli/cli.h"
+#include "cli/commands.h"       // Generic helper functions
+
+#include "core/i2c/i2c.h"
+#include "drivers/rf/nfc/pn532/pn532.h"
+#include "drivers/rf/nfc/pn532/pn532_bus.h"
+#include "drivers/rf/nfc/pn532/helpers/pn532_config.h"
+#include "drivers/rf/nfc/pn532/helpers/pn532_mifare_classic.h"
+#include "drivers/rf/nfc/pn532/helpers/pn532_mifare_ultralight.h"
+
+// Use default Mifare Classic authentication keys
+static byte_t _cmd_mifare_valueblock_AuthKey1[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+static byte_t _cmd_mifare_valueblock_AuthKey2[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+// Handle common error cases here for pn532_mifareclassic_WaitForPassiveTarget()
+#define VALUEBLOCK_PASSIVETARGET_ERRORHANDLER()  \
+  do { switch (error) \
+       { \
+         case PN532_ERROR_WRONGCARDTYPE: \
+           printf("Wrong card type%s", CFG_PRINTF_NEWLINE); \
+           break; \
+         case PN532_ERROR_TIMEOUTWAITINGFORCARD: \
+           printf("Timed out waiting for a card%s", CFG_PRINTF_NEWLINE); \
+           break; \
+         default: \
+           printf("Error establishing passive connection (0x%02x)%s", error, CFG_PRINTF_NEWLINE); \
+           break; \
+       } \
+     } while (0);
+
+// ToDo: The increment and decrement commands only vary by one command byte!
+// Clean this code up with a single function that specifies if we are
+// incrementing or decrementing!
+
+/**************************************************************************/
+/*!
+    'cmd_nfc_mifareclassic_valueblock_create' command handler
+*/
+/**************************************************************************/
+void cmd_nfc_mifareclassic_valueblock_create(uint8_t argc, char **argv)
+{
+  pn532_error_t error;
+  byte_t abtUID[8];
+  size_t szUIDLen;
+  int32_t block;
+  int32_t value;
+
+  getNumber (argv[0], &block);
+  getNumber (argv[1], &value);
+
+  // Make sure the block address is valid, and we're not in the sector trailer
+  if (block > 63 || block < 1 || pn532_mifareclassic_isTrailerBlock(block))
+  {
+    printf("Invalid block number%s", CFG_PRINTF_NEWLINE);
+        return;
+  }
+
+  printf("Creating a value block at address %d%s%s", (int)block, CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+
+  // Set a timeout waiting for passive targets (default = 0xFF, wait forever)
+  pn532_config_SetPassiveActivationRetries(0xFE);
+
+  // Wait for any ISO14443A card
+  error = pn532_mifareclassic_WaitForPassiveTarget(abtUID, &szUIDLen);
+  if (!error)
+  {
+    // Mifare classic card found ... try to authenticate the sector
+    if (pn532_mifareclassic_AuthenticateBlock (abtUID, szUIDLen, block, PN532_MIFARE_CMD_AUTH_A, (block / 4) ? _cmd_mifare_valueblock_AuthKey2 : _cmd_mifare_valueblock_AuthKey1))
+    {
+      printf("Authentication error %s", CFG_PRINTF_NEWLINE);
+      return;
+    }
+    // We should be able to create the value block now
+    if (pn532_mifareclassic_CreateValueBlock (block, value))
+    {
+      printf("Unable to write to block %d%s", (int)block, CFG_PRINTF_NEWLINE);
+    }
+    // Write successful
+    printf("Updated block %02d with value '%d'%s", (int)block, (int)value, CFG_PRINTF_NEWLINE);
+  }
+  else
+  {
+    // Handled by macro since this is common to every function
+    VALUEBLOCK_PASSIVETARGET_ERRORHANDLER()
+  }
+
+  // Set retry count back to infinite if it was changed
+  pn532_config_SetPassiveActivationRetries(0xFF);
+}
+
+/**************************************************************************/
+/*!
+    'cmd_nfc_mifareclassic_valueblock_increment' command handler
+*/
+/**************************************************************************/
+void cmd_nfc_mifareclassic_valueblock_increment(uint8_t argc, char **argv)
+{
+  pn532_error_t error;
+  byte_t abtUID[8];
+  size_t szUIDLen;
+  int32_t block;
+  int32_t value;
+
+  getNumber (argv[0], &block);
+  getNumber (argv[1], &value);
+
+  // Make sure the block address is valid, and we're not in the sector trailer
+  if (block > 63 || block < 1 || pn532_mifareclassic_isTrailerBlock(block))
+  {
+    printf("Invalid block number%s", CFG_PRINTF_NEWLINE);
+        return;
+  }
+
+  printf("Trying to increment value block %d%s%s", (int)block, CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+
+  // Set a timeout waiting for passive targets (default = 0xFF, wait forever)
+  pn532_config_SetPassiveActivationRetries(0xFE);
+
+  // Wait for any ISO14443A card
+  error = pn532_mifareclassic_WaitForPassiveTarget(abtUID, &szUIDLen);
+  if (!error)
+  {
+    // Mifare classic card found ... try to authenticate the sector
+    if (pn532_mifareclassic_AuthenticateBlock (abtUID, szUIDLen, block, PN532_MIFARE_CMD_AUTH_A, (block / 4) ? _cmd_mifare_valueblock_AuthKey2 : _cmd_mifare_valueblock_AuthKey1))
+    {
+      printf("Authentication error%s", CFG_PRINTF_NEWLINE);
+      return;
+    }
+    // We should be able to increment the value block now
+    error = pn532_mifareclassic_IncrementValueBlock (block, value);
+    if (error)
+    {
+      switch (error)
+      {
+        case PN532_ERROR_INCORRECTBLOCKFORMAT:
+          printf("Block %d is not a Mifare value block%s", (int)block, CFG_PRINTF_NEWLINE);
+          break;
+        default:
+          printf("Unable to increment to block %d%s", (int)block, CFG_PRINTF_NEWLINE);
+          break;
+      }
+    }
+    // Increment successful
+    printf("Incremented block %02d by '%d'%s", (int)block, (int)value, CFG_PRINTF_NEWLINE);
+  }
+  else
+  {
+    // Handled by macro since this is common to every function
+    VALUEBLOCK_PASSIVETARGET_ERRORHANDLER()
+  }
+
+  // Set retry count back to infinite if it was changed
+  pn532_config_SetPassiveActivationRetries(0xFF);
+}
+
+/**************************************************************************/
+/*!
+    'cmd_nfc_mifareclassic_valueblock_decrement' command handler
+*/
+/**************************************************************************/
+void cmd_nfc_mifareclassic_valueblock_decrement(uint8_t argc, char **argv)
+{
+  pn532_error_t error;
+  byte_t abtUID[8];
+  size_t szUIDLen;
+  int32_t block;
+  int32_t value;
+
+  getNumber (argv[0], &block);
+  getNumber (argv[1], &value);
+
+  // Make sure the block address is valid, and we're not in the sector trailer
+  if (block > 63 || block < 1 || pn532_mifareclassic_isTrailerBlock(block))
+  {
+    printf("Invalid block number%s", CFG_PRINTF_NEWLINE);
+        return;
+  }
+
+  printf("Trying to decrement value block %d%s%s", (int)block, CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+
+  // Set a timeout waiting for passive targets (default = 0xFF, wait forever)
+  pn532_config_SetPassiveActivationRetries(0xFE);
+
+  // Wait for any ISO14443A card
+  error = pn532_mifareclassic_WaitForPassiveTarget(abtUID, &szUIDLen);
+  if (!error)
+  {
+    // Mifare classic card found ... try to authenticate the sector
+    if (pn532_mifareclassic_AuthenticateBlock (abtUID, szUIDLen, block, PN532_MIFARE_CMD_AUTH_A, (block / 4) ? _cmd_mifare_valueblock_AuthKey2 : _cmd_mifare_valueblock_AuthKey1))
+    {
+      printf("Authentication error%s", CFG_PRINTF_NEWLINE);
+      return;
+    }
+    // We should be able to decrement the value block now
+    error = pn532_mifareclassic_DecrementValueBlock (block, value);
+    if (error)
+    {
+      switch (error)
+      {
+        case PN532_ERROR_INCORRECTBLOCKFORMAT:
+          printf("Block %d is not a Mifare balue block%s", (int)block, CFG_PRINTF_NEWLINE);
+          break;
+        default:
+          printf("Unable to decrement to block %d%s", (int)block, CFG_PRINTF_NEWLINE);
+          break;
+      }
+    }
+    // Decrement successful
+    printf("Decremented block %02d by '%d'%s", (int)block, (int)value, CFG_PRINTF_NEWLINE);
+  }
+  else
+  {
+    // Handled by macro since this is common to every function
+    VALUEBLOCK_PASSIVETARGET_ERRORHANDLER()
+  }
+
+  // Set retry count back to infinite if it was changed
+  pn532_config_SetPassiveActivationRetries(0xFF);
+}
+
+/**************************************************************************/
+/*!
+    'cmd_nfc_mifareclassic_valueblock_read' command handler
+*/
+/**************************************************************************/
+void cmd_nfc_mifareclassic_valueblock_read(uint8_t argc, char **argv)
+{
+  pn532_error_t error;
+  byte_t abtUID[8];
+  size_t szUIDLen;
+  int32_t block;
+
+  getNumber (argv[0], &block);
+
+  // Set a timeout waiting for passive targets (default = 0xFF, wait forever)
+  pn532_config_SetPassiveActivationRetries(0xFE);
+
+  // Wait for any ISO14443A card
+  error = pn532_mifareclassic_WaitForPassiveTarget(abtUID, &szUIDLen);
+  if (!error)
+  {
+    // Try to authenticate the sector
+    if (pn532_mifareclassic_AuthenticateBlock (abtUID, szUIDLen, block, PN532_MIFARE_CMD_AUTH_A, (block / 4) ? _cmd_mifare_valueblock_AuthKey2 : _cmd_mifare_valueblock_AuthKey1))
+    {
+      printf("Authentication error%s", CFG_PRINTF_NEWLINE);
+      return;
+    }
+    // We should be able to read the value now
+    int32_t value = 0;
+    error = pn532_mifareclassic_ReadValueBlock(block, &value);
+    if (error)
+    {
+      switch (error)
+      {
+        case PN532_ERROR_ADDRESSOUTOFRANGE:
+          printf("Invalid block number%s", CFG_PRINTF_NEWLINE);
+          break;
+        case PN532_ERROR_INCORRECTBLOCKFORMAT:
+          printf("Block %d is not a Mifare value block%s", (int)block, CFG_PRINTF_NEWLINE);
+          break;
+        default:
+          printf("Unable to read block %d%s", (int)block, CFG_PRINTF_NEWLINE);
+          break;
+      }
+    }
+    // Read successful
+    printf("Block %02d = %d (0x%08X)%s", (int)block, (int)value, (int)value, CFG_PRINTF_NEWLINE);
+  }
+  else
+  {
+    // Handled by macro since this is common to every function
+    VALUEBLOCK_PASSIVETARGET_ERRORHANDLER()
+  }
+
+  // Set retry count back to infinite if it was changed
+  pn532_config_SetPassiveActivationRetries(0xFF);
+}
+
+#endif  // #ifdef CFG_PN532
diff --git a/reform2-lpc-fw/src/cli/commands/cmd_nfc_mifareultralight_memdump.c b/reform2-lpc-fw/src/cli/commands/cmd_nfc_mifareultralight_memdump.c
new file mode 100644
index 0000000000000000000000000000000000000000..477a697b45e545adc223549265e406524e8d22c2
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/commands/cmd_nfc_mifareultralight_memdump.c
@@ -0,0 +1,141 @@
+/**************************************************************************/
+/*!
+    @file     cmd_nfc_mifareultralight_memdump.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Tries to authenticate a Mifare Ultralight card using the default
+              authentication key, and displays the raw memory contents if
+              possible.
+    @ingroup  CLI
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013 K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <stdio.h>
+
+#include "projectconfig.h"
+
+#ifdef CFG_PN532
+
+#include "core/gpio/gpio.h"
+#include "cli/cli.h"
+#include "cli/commands.h"       // Generic helper functions
+
+#include "core/i2c/i2c.h"
+#include "drivers/rf/nfc/pn532/pn532.h"
+#include "drivers/rf/nfc/pn532/pn532_bus.h"
+#include "drivers/rf/nfc/pn532/helpers/pn532_config.h"
+#include "drivers/rf/nfc/pn532/helpers/pn532_mifare_classic.h"
+#include "drivers/rf/nfc/pn532/helpers/pn532_mifare_ultralight.h"
+
+/**************************************************************************/
+/*!
+    'nfc_mifareultralight_memdump' command handler
+*/
+/**************************************************************************/
+void cmd_nfc_mifareultralight_memdump(uint8_t argc, char **argv)
+{
+  pn532_error_t error;
+  byte_t        abtBuffer[8];
+  size_t        szUIDLen;
+  int32_t       timeout;
+  bool          retriesChanged = false;
+
+  // Set a timeout waiting for passive targets (default = 0xFF, wait forever)
+  if (argc > 0)
+  {
+    getNumber (argv[0], &timeout);
+    if (timeout > 0xFF || timeout < 0)
+    {
+      printf("Invalid timeout [0..255]%s", CFG_PRINTF_NEWLINE);
+      return;
+    }
+    // We can safely ignore errors here since there is a default value anyway
+    pn532_config_SetPassiveActivationRetries(timeout);
+    retriesChanged = true;
+  }
+
+  printf("Please insert a Mifare Ultralight card%s%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+
+  // Set a timeout waiting for passive targets (default = 0xFF, wait forever)
+  // We can safely ignore errors here since there is a default value anyway
+  getNumber (argv[0], &timeout);
+  if ((timeout < 1) || (timeout > 0xFE))
+    timeout = 0xFF;
+  pn532_config_SetPassiveActivationRetries(timeout & 0xFF);
+
+  // Try to do a memory dump of a Mifare Ultralight card
+  // First wait for a card to arrive (will wake the PN532 if required)
+  error = pn532_mifareultralight_WaitForPassiveTarget(abtBuffer, &szUIDLen);
+  if (!error)
+  {
+    // Display the card's UID (normally 7 bytes long)
+    printf("UID: ");
+    pn532PrintHex(abtBuffer, szUIDLen);
+    printf("%s", CFG_PRINTF_NEWLINE);
+    printf("Page  Hex       Text%s", CFG_PRINTF_NEWLINE);
+    printf("----  --------  ----%s", CFG_PRINTF_NEWLINE);
+    // Dump the memory contents page by page
+    uint8_t i;
+    for (i = 0; i < 16; i++)
+    {
+      // Try to read the current page
+      error = pn532_mifareultralight_ReadPage(i, abtBuffer);
+      if (!error)
+      {
+        printf("0x%02x  ", i);
+        pn532PrintHexChar(abtBuffer, 4);
+      }
+    }
+  }
+  else
+  {
+    switch (error)
+    {
+      case PN532_ERROR_WRONGCARDTYPE:
+        printf("Wrong card type%s", CFG_PRINTF_NEWLINE);
+        break;
+      case PN532_ERROR_TIMEOUTWAITINGFORCARD:
+        printf("Timed out waiting for a card%s", CFG_PRINTF_NEWLINE);
+        break;
+      default:
+        printf("Error establishing passive connection (0x%02x)%s", error, CFG_PRINTF_NEWLINE);
+        break;
+    }
+  }
+
+  // Set retry count back to infinite if it was changed
+  if (retriesChanged)
+  {
+    pn532_config_SetPassiveActivationRetries(0xFF);
+  }
+}
+
+#endif  // #ifdef CFG_PN532
diff --git a/reform2-lpc-fw/src/cli/commands/cmd_rtc_read.c b/reform2-lpc-fw/src/cli/commands/cmd_rtc_read.c
new file mode 100644
index 0000000000000000000000000000000000000000..0e41c30c256abdcda40f2fb4bc90470a0f148da6
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/commands/cmd_rtc_read.c
@@ -0,0 +1,71 @@
+/**************************************************************************/
+/*!
+    @file     cmd_rtc_read.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Reads the time on the RTC
+    @ingroup  CLI
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microbuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <stdio.h>
+
+#include "projectconfig.h"
+
+#if defined(CFG_RTC)
+
+#include "cli/commands.h"
+#include "drivers/rtc/rtc.h"
+#include "drivers/rtc/pcf2129/pcf2129.h"
+
+/**************************************************************************/
+/*!
+    'cmd_rtc_read' command handler
+*/
+/**************************************************************************/
+void cmd_rtc_read(uint8_t argc, char **argv)
+{
+  err_t error;
+  rtcTime_t time;
+
+  error = pcf2129ReadTime(&time);
+  if (error)
+  {
+    printf("%s%s", STRING(LOCALISATION_TEXT_No_response_on_the_I2C_bus), CFG_PRINTF_NEWLINE);
+    return;
+  }
+
+  printf("%04d/%02d/%02d%s", time.years+1900, time.months+1, time.days, CFG_PRINTF_NEWLINE);
+  printf("%02d:%02d:%02d%s", time.hours, time.minutes, time.seconds, CFG_PRINTF_NEWLINE);
+  printf("%u%s", rtcToEpochTime(&time), CFG_PRINTF_NEWLINE);
+}
+
+#endif /* CFG_RTC */
diff --git a/reform2-lpc-fw/src/cli/commands/cmd_rtc_write.c b/reform2-lpc-fw/src/cli/commands/cmd_rtc_write.c
new file mode 100644
index 0000000000000000000000000000000000000000..c7a29f18349334830a58199a1ab1eb0284a8c2dd
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/commands/cmd_rtc_write.c
@@ -0,0 +1,116 @@
+/**************************************************************************/
+/*!
+    @file     cmd_rtc_write.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Sets the time on the RTC
+    @ingroup  CLI
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microbuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <stdio.h>
+
+#include "projectconfig.h"
+
+#if defined(CFG_RTC)
+
+#include "cli/commands.h"
+#include "drivers/rtc/rtc.h"
+#include "drivers/rtc/pcf2129/pcf2129.h"
+
+/**************************************************************************/
+/*!
+    'cmd_rtc_write' command handler
+*/
+/**************************************************************************/
+void cmd_rtc_write(uint8_t argc, char **argv)
+{
+  err_t error;
+  rtcTime_t time;
+  int32_t year, month, day, hour, minute, second;
+
+  getNumber(argv[0], &year);
+  getNumber(argv[1], &month);
+  getNumber(argv[2], &day);
+  getNumber(argv[3], &hour);
+  getNumber(argv[4], &minute);
+  getNumber(argv[5], &second);
+
+  /* Make sure values are valid */
+  if ((year < 2000) || (year > 2038))
+  {
+    printf("%s%s", "Year must be between 2000 and 2023", CFG_PRINTF_NEWLINE);
+    return;
+  }
+  if ((month < RTC_MONTHS_JANUARY) || (month > RTC_MONTHS_DECEMBER))
+  {
+    printf("%s%s", "Month must be between 1 and 12", CFG_PRINTF_NEWLINE);
+    return;
+  }
+  if ((day < 1) || (day > 31))
+  {
+    printf("%s%s", "Day must be between 1 and 31", CFG_PRINTF_NEWLINE);
+    return;
+  }
+  if ((hour < 0) || (hour > 23))
+  {
+    printf("%s%s", "Hour must be between 0 and 23", CFG_PRINTF_NEWLINE);
+    return;
+  }
+  if ((minute < 0) || (minute > 59))
+  {
+    printf("%s%s", "Minute must be between 0 and 59", CFG_PRINTF_NEWLINE);
+    return;
+  }
+  if ((second < 0) || (second > 59))
+  {
+    printf("%s%s", "Second must be between 0 and 59", CFG_PRINTF_NEWLINE);
+    return;
+  }
+
+  /* Try to create a date */
+  error = rtcCreateTime(year, month, day, hour, minute, second, 0, &time);
+  if (error)
+  {
+    printf("%s%s", "Invalid timestamp", CFG_PRINTF_NEWLINE);
+    return;
+  }
+
+  /* Write the time to the RTC */
+  error = pcf2129SetTime(time);
+  if (error)
+  {
+    printf("%s%s", STRING(LOCALISATION_TEXT_No_response_on_the_I2C_bus), CFG_PRINTF_NEWLINE);
+    return;
+  }
+}
+
+#endif /* CFG_RTC */
diff --git a/reform2-lpc-fw/src/cli/commands/cmd_sd_dir.c b/reform2-lpc-fw/src/cli/commands/cmd_sd_dir.c
new file mode 100644
index 0000000000000000000000000000000000000000..7f713484b3ac1dd892556c577cdb4bdad89d1375
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/commands/cmd_sd_dir.c
@@ -0,0 +1,181 @@
+/**************************************************************************/
+/*!
+    @file     cmd_sd_dir.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Displays the contents of the specified directory or
+	          sub-directories on the SD card using FatFS.
+    @ingroup  CLI
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <stdio.h>
+#include <string.h>
+
+#include "projectconfig.h"
+#include "cli/cli.h"
+#include "cli/commands.h"           // Generic helper functions
+
+#ifdef CFG_SDCARD
+  #include "drivers/storage/fatfs/diskio.h"
+  #include "drivers/storage/fatfs/ff.h"
+
+  static FILINFO Finfo;
+  static FATFS Fatfs[1];
+
+/**************************************************************************/
+/*!
+    sd 'dir' command handler
+
+    This demonstrates how to initialise the SD card, read the contents
+    of a directory (including checking if an entry is a folder or a file),
+    and checking the amount of freespace on available on the disk.
+*/
+/**************************************************************************/
+void cmd_sd_dir(uint8_t argc, char **argv)
+{
+  char* path;
+  DSTATUS stat;
+
+  // Display root folder by default
+  path = argc > 0 ? argv[0] : "/";
+
+  // Initialise SD Card
+  stat = disk_initialize(0);
+  if (stat & STA_NOINIT)
+  {
+    // Init failed
+    printf("%s%s", STRING(LOCALISATION_TEXT_SD_init_failed), CFG_PRINTF_NEWLINE);
+  }
+  if (stat & STA_NODISK)
+  {
+    // No disk present
+    printf("%s%s", STRING(LOCALISATION_TEXT_No_SD_card), CFG_PRINTF_NEWLINE);
+  }
+  if (stat == 0)
+  {
+    BYTE res;
+    DIR dir;
+
+    // Try to mount drive
+    res = f_mount(0, &Fatfs[0]);
+    if (res != FR_OK)
+    {
+          // Unable to mount driver
+      printf("%s%s", STRING(LOCALISATION_TEXT_Failed_to_mount_partition), CFG_PRINTF_NEWLINE);
+    }
+    if (res == FR_OK)
+    {
+      res = f_opendir(&dir, path);
+      if (res)
+      {
+          // Unable to open specified path
+          printf("%s '%s' %s", STRING(LOCALISATION_TEXT_Failed_to_open), path, CFG_PRINTF_NEWLINE);
+          return;
+      }
+
+      #if _USE_LFN
+        // Buffer for long file names
+        static char lfn[_MAX_LFN + 1];
+        Finfo.lfname = lfn;
+        Finfo.lfsize = sizeof lfn;
+      #endif
+
+      // Display directory name
+      printf("%s %s %s %s%s", CFG_PRINTF_NEWLINE, STRING(LOCALISATION_TEXT_Contents_of), path, CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+      printf("       %-25s %12s %s", STRING(LOCALISATION_TEXT_Filename), STRING(LOCALISATION_TEXT_Size), CFG_PRINTF_NEWLINE);
+      printf("       %-25s %12s %s", "--------", "----", CFG_PRINTF_NEWLINE);
+
+      // Read directory contents
+      int folderBytes = 0;
+      for(;;)
+      {
+          res = f_readdir(&dir, &Finfo);
+          if ((res != FR_OK) || !Finfo.fname[0]) break;
+          if (Finfo.fattrib & AM_DIR)
+          {
+            // Directory
+            #if _USE_LFN
+              if (*Finfo.lfname)
+              {
+                printf(" <DIR> %-25s %s", (char *)&Finfo.lfname[0], CFG_PRINTF_NEWLINE);
+              }
+              else
+              {
+                printf(" <DIR> %-25s %s", (char *)&Finfo.fname[0], CFG_PRINTF_NEWLINE);
+              }
+            #else
+              printf(" <DIR> %-25s %s", (char *)&Finfo.fname[0], CFG_PRINTF_NEWLINE);
+            #endif
+          }
+          else
+          {
+            // File
+            #if _USE_LFN
+              if (*Finfo.lfname)
+              {
+                printf("       %-25s %12d %s %s", (char *)&Finfo.lfname[0], (int)(Finfo.fsize), STRING(LOCALISATION_TEXT_Bytes), CFG_PRINTF_NEWLINE);
+              }
+              else
+              {
+                printf("       %-25s %12d %s %s", (char *)&Finfo.fname[0], (int)(Finfo.fsize), STRING(LOCALISATION_TEXT_Bytes), CFG_PRINTF_NEWLINE);
+              }
+            #else
+              printf("       %-25s %12d %s %s", (char *)&Finfo.fname[0], (int)(Finfo.fsize), STRING(LOCALISATION_TEXT_Bytes), CFG_PRINTF_NEWLINE);
+            #endif
+          }
+          folderBytes += Finfo.fsize;
+      }
+
+      // Display folder size
+      printf("%s", CFG_PRINTF_NEWLINE);
+      printf("       %-25s %12d %s %s", STRING(LOCALISATION_TEXT_Folder_Size_COLON_SPACE), (int)(folderBytes / 1024), STRING(LOCALISATION_SYMBOL_KILOBYTES), CFG_PRINTF_NEWLINE);
+
+      // Get free disk space (only available if FATFS was compiled with _FS_MINIMIZE set to 0)
+      #if _FS_MINIMIZE == 0 && _FS_READONLY == 0
+        do
+        {
+          FATFS *fs = &Fatfs[0];
+          DWORD clust;
+
+          // Get free clusters
+          res = f_getfree("0:", &clust, &fs);
+
+          // Display total and free space
+          printf("       %-25s %12d %s %s", STRING(LOCALISATION_TEXT_Disk_Size_COLON_SPACE), (int)((DWORD)(fs->max_clust - 2) * fs->csize / 2), STRING(LOCALISATION_SYMBOL_KILOBYTES), CFG_PRINTF_NEWLINE);
+          printf("       %-25s %12d %s %s", STRING(LOCALISATION_TEXT_Space_Available_COLON_SPACE), (int)(clust * fs->csize / 2), STRING(LOCALISATION_SYMBOL_KILOBYTES), CFG_PRINTF_NEWLINE);
+        } while(0);
+      #endif
+    }
+  }
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/cli/commands/cmd_sysinfo.c b/reform2-lpc-fw/src/cli/commands/cmd_sysinfo.c
new file mode 100644
index 0000000000000000000000000000000000000000..6a5b883573463a96e791eceed8ebee3e6b54c1d4
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/commands/cmd_sysinfo.c
@@ -0,0 +1,193 @@
+/**************************************************************************/
+/*!
+    @file     cmd_sysinfo.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Displays some basic information about the core HW and system.
+    @ingroup  CLI
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <stdio.h>
+
+#include "projectconfig.h"
+#include "core/gpio/gpio.h"
+#include "core/delay/delay.h"
+#include "core/iap/iap.h"
+#include "cli/cli.h"
+#include "cli/commands.h"       // Generic helper functions
+
+#ifdef CFG_PRINTF_UART
+  #include "core/uart/uart.h"
+#endif
+
+#ifdef CFG_TFTLCD
+  #include "drivers/displays/graphic/lcd.h"
+#endif
+
+#ifdef CFG_CHIBI
+  #include "drivers/rf/802.15.4/chibi/chb.h"
+  #include "drivers/rf/802.15.4/chibi/chb_drvr.h"
+#endif
+
+/**************************************************************************/
+/*!
+    'sysinfo' command handler
+*/
+/**************************************************************************/
+void cmd_sysinfo(uint8_t argc, char **argv)
+{
+  /* Note: Certain values are only reported if CFG_INTERFACE_LONGSYSINFO
+     is set to 1 in projectconfig.h.  These extra values are more useful
+     for debugging than real-world use, so there's no point wasting
+     flash space storing the text and code for them */
+
+  /* Firmware Version */
+  printf("%-25s : %u.%u.%u %s", STRING(LOCALISATION_TEXT_Code_Base_COLON_SPACE), CFG_CODEBASE_VERSION_MAJOR, CFG_CODEBASE_VERSION_MINOR, CFG_CODEBASE_VERSION_REVISION, CFG_PRINTF_NEWLINE);
+  printf("%-25s : %u.%u.%u %s", STRING(LOCALISATION_TEXT_Firmware), CFG_FIRMWARE_VERSION_MAJOR, CFG_FIRMWARE_VERSION_MINOR, CFG_FIRMWARE_VERSION_REVISION, CFG_PRINTF_NEWLINE);
+
+  /* MCU */
+  #ifdef CFG_MCU_LPC11U24FBD48_401
+  printf("%-25s : %s%s", STRING(LOCALISATION_TEXT_MCU), "LPC11U24FBD48/401", CFG_PRINTF_NEWLINE);
+  #endif
+  #ifdef CFG_MCU_LPC11U37FBD48_401
+  printf("%-25s : %s%s", STRING(LOCALISATION_TEXT_MCU), "LPC11U37FBD48/401", CFG_PRINTF_NEWLINE);
+  #endif
+  #ifdef CFG_MCU_LPC1347FBD48
+  printf("%-25s : %s%s", STRING(LOCALISATION_TEXT_MCU), "LPC1347FBD48/401", CFG_PRINTF_NEWLINE);
+  #endif
+
+  /* Unique Chip ID */
+  #if CFG_INTERFACE_LONGSYSINFO
+    uint32_t uid[4];
+    iapReadUID(uid);  /* 1st byte is LSB, 4th byte is MSB */
+    printf("%-25s : %08X%08X%08X%08X %s",
+        STRING(LOCALISATION_TEXT_Serial_Number),
+        (unsigned int)uid[3],
+        (unsigned int)uid[2],
+        (unsigned int)uid[1],
+        (unsigned int)uid[0],
+        CFG_PRINTF_NEWLINE);
+  #endif
+
+  /* Core Frequency */
+  printf("%-25s : %u.%u %s %s", STRING(LOCALISATION_TEXT_System_Clock), (unsigned int)(SystemCoreClock / 1000000), (unsigned int)(SystemCoreClock % 1000000), STRING(LOCALISATION_SYMBOL_MHZ), CFG_PRINTF_NEWLINE);
+
+  /* EEPROM Size */
+  printf("%-25s : %u %s %s", STRING(LOCALISATION_TEXT_EEPROM_Size_COLON_SPACE), (unsigned int)CFG_EEPROM_SIZE, STRING(LOCALISATION_TEXT_bytes), CFG_PRINTF_NEWLINE);
+
+  /* System Uptime (based on delay timer) */
+  printf("%-25s : %u %s %s", STRING(LOCALISATION_TEXT_System_Uptime), (unsigned int)delayGetSecondsActive(), STRING(LOCALISATION_SYMBOL_SECONDS), CFG_PRINTF_NEWLINE);
+
+  /* Wireless Settings (if CFG_CHIBI enabled) */
+  #ifdef CFG_CHIBI
+    do
+    {
+      chb_pcb_t *chibipcb = chb_get_pcb();
+      /* Transceiver Model */
+      printf("%-25s : %s %s", STRING(LOCALISATION_TEXT_RF_Transceiver), "AT86RF212", CFG_PRINTF_NEWLINE);
+      /* Indicate promiscuous mode if enabled */
+      #if CFG_CHIBI_PROMISCUOUS == 1
+        printf("%-25s : %s %s", STRING(LOCALISATION_TEXT_RF_Receive_Mode), STRING(LOCALISATION_TEXT_Promiscuous), CFG_PRINTF_NEWLINE);
+      #else
+        printf("%-25s : %s %s", STRING(LOCALISATION_TEXT_RF_Receive_Mode), STRING(LOCALISATION_TEXT_Normal), CFG_PRINTF_NEWLINE);
+      #endif
+      /* 4-byte PAN ID */
+      printf("%-25s : 0x%04X (%d) %s", STRING(LOCALISATION_TEST_802154_PAN_ID), CFG_CHIBI_PANID, CFG_CHIBI_PANID, CFG_PRINTF_NEWLINE);
+      /* Short (4-byte) Node Address */
+      printf("%-25s : 0x%04X (%d) %s", STRING(LOCALISATION_TEXT_802154_Node_Address), chibipcb->src_addr, chibipcb->src_addr, CFG_PRINTF_NEWLINE);
+      /* Current 802.15.4 Channel */
+      printf("%-25s : %d %s", STRING(LOCALISATION_TEXT_802154_Channel), CFG_CHIBI_CHANNEL, CFG_PRINTF_NEWLINE);
+    } while(0);
+  #endif
+
+  // CLI and buffer Settings
+  #if CFG_INTERFACE_LONGSYSINFO
+    /* Max number of characters for a single CLI command */
+    printf("%-25s : %d %s %s", STRING(LOCALISATION_TEXT_CLI_Max_Command_Size), CFG_INTERFACE_MAXMSGSIZE, STRING(LOCALISATION_TEXT_bytes), CFG_PRINTF_NEWLINE);
+    /* Whether the IRW pin is enabled when a CLI command is complete */
+    printf("%-25s : %s %s", STRING(LOCALISATION_TEXT_CLI_IRQ_Enabled), CFG_INTERFACE_ENABLEIRQ ? STRING(LOCALISATION_TEXT_True) : STRING(LOCALISATION_TEXT_False), CFG_PRINTF_NEWLINE);
+    #if CFG_INTERFACE_ENABLEIRQ
+      /* Location of the IRQ pin */
+      printf("%-25s : %d.%d %s", STRING(LOCALISATION_TEXT_CLI_IRQ_Location), CFG_INTERFACE_IRQPORT, CFG_INTERFACE_IRQPIN, CFG_PRINTF_NEWLINE);
+    #endif
+  #endif
+
+  #ifdef CFG_PRINTF_UART
+    do
+    {
+      uart_pcb_t *uartpcb = uartGetPCB();
+      /* UART Baud Rate */
+      printf("%-25s : %u %s", STRING(LOCALISATION_TEXT_UART_Baud_Rate), (unsigned int)(uartpcb->baudrate), CFG_PRINTF_NEWLINE);
+    } while(0);
+  #endif
+
+  // SD Card and FATFS
+  #ifdef CFG_SDCARD
+    /* Indicate if an SD card has been detected or not */
+    printf("%-25s : %s %s", STRING(LOCALISATION_TEXT_SD_Card_Present), GPIOGetPinValue(CFG_SDCARD_CDPORT, CFG_SDCARD_CDPIN) ? STRING(LOCALISATION_TEXT_True) : STRING(LOCALISATION_TEXT_False), CFG_PRINTF_NEWLINE);
+    #if CFG_INTERFACE_LONGSYSINFO
+      /* Indicate whether the filesystem is read-only or if write is also enabled */
+      printf("%-25s : %s %s", STRING(LOCALISATION_TEXT_FAT_File_System), CFG_SDCARD_READONLY ? STRING(LOCALISATION_TEXT_Read_Only) : STRING(LOCALISATION_TEXT_Read_FORWARDSLASH_Write), CFG_PRINTF_NEWLINE);
+    #endif
+  #endif
+
+  // TFT LCD Settings (if CFG_TFTLCD enabled)
+  #ifdef CFG_TFTLCD
+    /* LCD width in pixels */
+    printf("%-25s : %d %s", STRING(LOCALISATION_TEXT_LCD_Width), (int)lcdGetWidth(), CFG_PRINTF_NEWLINE);
+    /* LCD height in pixels */
+    printf("%-25s : %d %s", STRING(LOCALISATION_TEXT_LCD_Height), (int)lcdGetHeight(), CFG_PRINTF_NEWLINE);
+    #if CFG_INTERFACE_LONGSYSINFO
+      /* LCD Controller ID */
+      printf("%-25s : %04X %s", STRING(LOCALISATION_TEXT_LCD_Controller_ID), (unsigned short)lcdGetControllerID(), CFG_PRINTF_NEWLINE);
+      /* Whether small fonts are enabled or not */
+      printf("%-25s : %s %s", STRING(LOCALISATION_TEXT_LCD_Small_Fonts), CFG_TFTLCD_INCLUDESMALLFONTS == 1 ? STRING(LOCALISATION_TEXT_True) : STRING(LOCALISATION_TEXT_False), CFG_PRINTF_NEWLINE);
+      /* Whether anti-aliased fonts are enabled or not */
+      printf("%-25s : %s %s", STRING(LOCALISATION_TEXT_LCD_AA_Fonts), CFG_TFTLCD_USEAAFONTS == 1 ? STRING(LOCALISATION_TEXT_True) : STRING(LOCALISATION_TEXT_False), CFG_PRINTF_NEWLINE);
+      lcdProperties_t lcdprops = lcdGetProperties();
+      /* Whether a touch screen is enabled or not */
+      printf("%-25s : %s %s", STRING(LOCALISATION_TEXT_Touch_Screen), lcdprops.touchscreen ? STRING(LOCALISATION_TEXT_True) : STRING(LOCALISATION_TEXT_False), CFG_PRINTF_NEWLINE);
+      if (lcdprops.touchscreen)
+      {
+        // printf("%-25s : %s %s", "Touch Screen Calibrated", eepromReadU8(CFG_EEPROM_TOUCHSCREEN_CALIBRATED) == 1 ? "True" : "False", CFG_PRINTF_NEWLINE);
+        /* ADC Threshold for a valid touch screen event to occur */
+        printf("%-25s : %d %s", STRING(LOCALISATION_TEXT_Touch_Screen_Threshold), CFG_TFTLCD_TS_DEFAULTTHRESHOLD, CFG_PRINTF_NEWLINE);
+      }
+    #endif
+  #endif
+
+  // Debug LED
+  #if CFG_INTERFACE_LONGSYSINFO
+    /* Location of the LED pin */
+    printf("%-25s : %d.%d %s", STRING(LOCALISATION_TEXT_LED_Location), CFG_LED_PORT, CFG_LED_PIN, CFG_PRINTF_NEWLINE);
+  #endif
+}
diff --git a/reform2-lpc-fw/src/cli/commands/cmd_wifi.c b/reform2-lpc-fw/src/cli/commands/cmd_wifi.c
new file mode 100644
index 0000000000000000000000000000000000000000..e53f823620d7e0f49b58fd60427f96a25a13b435
--- /dev/null
+++ b/reform2-lpc-fw/src/cli/commands/cmd_wifi.c
@@ -0,0 +1,300 @@
+/**************************************************************************/
+/*!
+    @file     cmd_wifi.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Commands for the CC3000 wifi module.
+    @ingroup  CLI
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microbuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <stdio.h>
+#include <string.h>
+
+#include "projectconfig.h"
+
+#ifdef CFG_CC3000
+
+#include "cli/cli.h"
+#include "cli/commands.h"
+#include "core/eeprom/eeprom.h"
+#include "drivers/rf/wifi/cc3000/wifi.h"
+
+/**************************************************************************/
+/*!
+    Helper function that displays an error message
+*/
+/**************************************************************************/
+void cmd_wifi_helper_error(err_t error)
+{
+  if(error)
+  {
+    printf("ERROR: ");
+    switch (error)
+    {
+      case ERROR_CC3000_CONNECT_TIMEOUT:
+      printf("Timed out waiting for a connection%s", CFG_PRINTF_NEWLINE);
+        break;
+      default:
+        printf("0x%04X%s", error, CFG_PRINTF_NEWLINE);
+        break;
+    }
+  }
+}
+
+/**************************************************************************/
+/*!
+    'wifi_ssidscan' command handler
+*/
+/**************************************************************************/
+void cmd_wifi_ssidscan(uint8_t argc, char **argv)
+{
+  err_t error;
+
+  printf("Performing SSID scan (please wait a bit) ...%s%s",
+    CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+
+  error = wifi_displaySSIDResults();
+  if (error)
+  {
+    cmd_wifi_helper_error(error);
+  }
+}
+
+/**************************************************************************/
+/*!
+    'wifi_connect' command handler
+*/
+/**************************************************************************/
+void cmd_wifi_connect(uint8_t argc, char **argv)
+{
+  err_t error;
+
+  int32_t sec;
+  uint8_t ip[4];
+  uint8_t netmask[4];
+  uint8_t gateway[4];
+  uint8_t dhcp[4];
+  uint8_t dns[4];
+
+  /* Retrieve the security mode */
+  getNumber (argv[0], &sec);
+  if (sec < 0 || sec > 3)
+  {
+    printf("Security mode not in range (0..3)%s", CFG_PRINTF_NEWLINE);
+    return;
+  }
+
+  /* Check SSID length */
+  if (strlen(argv[1]) > 32)
+  {
+    printf("SSID must be <= 32 characters%s", CFG_PRINTF_NEWLINE);
+    return;
+  }
+
+  /* Check key length if we're using a secure network */
+  if (sec)
+  {
+    if (strlen(argv[2]) > 16)
+    {
+      printf("Key must be <= 16 characters%s", CFG_PRINTF_NEWLINE);
+      return;
+    }
+  }
+
+  /* Try to connect to the AP */
+  printf("Connecting to %s (30s timeout) ...%s", argv[1], CFG_PRINTF_NEWLINE);
+  if (sec)
+  {
+    /* Connect to a secure network */
+    error = wifi_connectSecure(sec, argv[1], (int32_t)strlen(argv[1]), argv[2], (int32_t)strlen(argv[2]));
+  }
+  else
+  {
+    /* Connect to an open network */
+    error = wifi_connectSecure(0, argv[1], (int32_t)strlen(argv[1]), "", 1);
+  }
+  if(error)
+  {
+    cmd_wifi_helper_error(error);
+    return;
+  }
+
+  /* Display the connection details */
+  error = wifi_getConnectionDetails(ip, netmask, gateway, dhcp, dns);
+  if (error)
+  {
+    cmd_wifi_helper_error(error);
+    return;
+  }
+
+  printf(CFG_PRINTF_NEWLINE);
+  printf("IP Address  : %d.%d.%d.%d %s",
+    ip[0], ip[1], ip[2], ip[3], CFG_PRINTF_NEWLINE);
+  printf("Netmask     : %d.%d.%d.%d %s",
+    netmask[0], netmask[1], netmask[2], netmask[3], CFG_PRINTF_NEWLINE);
+  printf("Gateway     : %d.%d.%d.%d %s",
+    gateway[0], gateway[1], gateway[2], gateway[3], CFG_PRINTF_NEWLINE);
+  printf("DHCP Server : %d.%d.%d.%d %s",
+    dhcp[0], dhcp[1], dhcp[2], dhcp[3], CFG_PRINTF_NEWLINE);
+  printf("DNS Server  : %d.%d.%d.%d %s",
+    dns[0], dns[1], dns[2], dns[3], CFG_PRINTF_NEWLINE);
+}
+
+/**************************************************************************/
+/*!
+    'wifi_smartConfig' command handler
+*/
+/**************************************************************************/
+void cmd_wifi_smartConfig(uint8_t argc, char **argv)
+{
+  err_t error;
+  uint32_t enableAES = 0;
+
+  if (argc == 1)
+  {
+    getNumber (argv[0], &enableAES);
+
+    /* Make sure enableAES is 1 or 0 */
+    if (enableAES < 0 || enableAES > 1)
+    {
+      printf("enableAES must be 0 or 1%s", CFG_PRINTF_NEWLINE);
+      return;
+    }
+  }
+
+  printf("Waiting for a SmartConfig connection ...%s", CFG_PRINTF_NEWLINE);
+  error = wifi_startSmartConfig(enableAES);
+  if (error)
+  {
+    cmd_wifi_helper_error(error);
+    return;
+  }
+}
+
+/**************************************************************************/
+/*!
+    'wifi_disconnect' command handler
+*/
+/**************************************************************************/
+void cmd_wifi_disconnect(uint8_t argc, char **argv)
+{
+  wifi_disconnect();
+  printf("Disconnected%s", CFG_PRINTF_NEWLINE);
+}
+
+/**************************************************************************/
+/*!
+    'wifi_ping' command handler
+*/
+/**************************************************************************/
+void cmd_wifi_ping(uint8_t argc, char **argv)
+{
+  err_t  error;
+  uint8_t  pingAttempts = 3;
+  uint16_t pingTimeout  = 1000;
+  uint8_t  ip8[4] = { 0, 0, 0, 0 };
+  unsigned int ip[4] = { 0, 0, 0, 0 }; /* keep sscanf happy */
+
+  /* Parse the IP address into four individual bytes */
+  sscanf(argv[0], "%u.%u.%u.%u", &ip[0], &ip[1], &ip[2], &ip[3]);
+
+  /* Validate the IP address */
+  if(!((ip[0] != 0) && (ip[0] <= 255) && (ip[1] <= 255) && (ip[2] <= 255) && (ip[3] <= 255)))
+  {
+    printf("Invalid IP address%s", CFG_PRINTF_NEWLINE);
+  }
+
+  /* Push values in 8-bit buffer */
+  ip8[0] = (uint8_t)(ip[0] & 0xFF);
+  ip8[1] = (uint8_t)(ip[1] & 0xFF);
+  ip8[2] = (uint8_t)(ip[2] & 0xFF);
+  ip8[3] = (uint8_t)(ip[3] & 0xFF);
+
+  /* Send the ping request */
+  printf("Pinging %u.%u.%u.%u %u times (%u ms timeout)%s",
+    (unsigned int)(ip[0]), (unsigned int)(ip[1]),
+    (unsigned int)(ip[2]), (unsigned int)(ip[3]),
+    (unsigned int)pingAttempts, (unsigned int)pingTimeout,
+    CFG_PRINTF_NEWLINE);
+  error = wifi_ping(ip8, pingAttempts, pingTimeout);
+  if (error)
+  {
+    cmd_wifi_helper_error(error);
+    return;
+  }
+}
+
+/**************************************************************************/
+/*!
+    'wifi_gethostnameip' command handler
+*/
+/**************************************************************************/
+void cmd_wifi_gethostnameip(uint8_t argc, char **argv)
+{
+  err_t error;
+  uint8_t lookupIP[4] = { 0, 0, 0, 0 };
+
+  error = wifi_getHostByName(argv[0], lookupIP);
+  if (!error)
+  {
+    printf("%s => %u.%u.%u.%u %s", argv[0],
+      (unsigned int)(lookupIP[0]), (unsigned int)(lookupIP[1]),
+      (unsigned int)(lookupIP[2]), (unsigned int)(lookupIP[3]),
+      CFG_PRINTF_NEWLINE);
+  }
+}
+
+/**************************************************************************/
+/*!
+    'wifi_moduleinfo' command handler
+*/
+/**************************************************************************/
+void cmd_wifi_moduleinfo(uint8_t argc, char **argv)
+{
+  uint8_t major, minor;
+    uint8_t macAddress[6] = { 0, 0, 0, 0, 0, 0 };
+
+  if (!wifi_getFirmwareVersion(&major, &minor))
+  {
+    printf("Firmware    : v%d.%d%s", major, minor, CFG_PRINTF_NEWLINE);
+  }
+
+  if (!wifi_getMacAddress(macAddress))
+  {
+    printf("MAC Address : %02X:%02X:%02X:%02X:%02X:%02X%s",
+      macAddress[0], macAddress[1], macAddress[2],
+      macAddress[3], macAddress[4], macAddress[5],
+      CFG_PRINTF_NEWLINE);
+  }
+}
+
+#endif /* CFG_CC3000 */
diff --git a/reform2-lpc-fw/src/core/adc/adc.c b/reform2-lpc-fw/src/core/adc/adc.c
new file mode 100644
index 0000000000000000000000000000000000000000..5beaca8f8c991cdca9d2dc9107f7576ab92e2961
--- /dev/null
+++ b/reform2-lpc-fw/src/core/adc/adc.c
@@ -0,0 +1,154 @@
+/**************************************************************************/
+/*!
+    @file     adc.c
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "adc.h"
+
+/**************************************************************************/
+/*!
+    @brief Powers up and configures the ADC block
+*/
+/**************************************************************************/
+void adcInit(void)
+{
+  /* Disable Power down bit to the ADC block. */
+  LPC_SYSCON->PDRUNCFG &= ~(0x1<<4);
+
+  /* Enable AHB clock to the ADC. */
+  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<13);
+
+  /* These pins should be setup elsewhere in your code -- ideally in
+   * boardInit() or in the driver init sequence -- but the various pin
+   * config options are presented below for reference sake */
+
+  /* P0.11 = ADC0 */
+  // LPC_IOCON->TDI_PIO0_11   &= ~0x9F;
+  // LPC_IOCON->TDI_PIO0_11   |= 0x02;
+
+  /* P0.12 = ADC1 */
+  // LPC_IOCON->TMS_PIO0_12   &= ~0x9F;
+  // LPC_IOCON->TMS_PIO0_12   |= 0x02;
+
+  /* P0.13 = ADC2 */
+  // LPC_IOCON->TDO_PIO0_13   &= ~0x9F;
+  // LPC_IOCON->TDO_PIO0_13   |= 0x02;
+
+  /* P0.14 = ADC3 */
+  // LPC_IOCON->TRST_PIO0_14  &= ~0x9F;
+  // LPC_IOCON->TRST_PIO0_14  |= 0x02;
+
+  /* P0.15 = ADC4 ... this is also SWDIO so be careful with this pin! */
+  // LPC_IOCON->SWDIO_PIO0_15 &= ~0x9F;
+  // LPC_IOCON->SWDIO_PIO0_15 |= 0x02;
+
+  /* P0.16 = ADC5 */
+  // LPC_IOCON->PIO0_16       &= ~0x9F;
+  // LPC_IOCON->PIO0_16       |= 0x01;
+
+  /* P0.22 = ADC6 */
+  // LPC_IOCON->PIO0_22       &= ~0x9F;
+  // LPC_IOCON->PIO0_22       |= 0x01;
+
+  /* P0.23 = ADC7 */
+  // LPC_IOCON->PIO0_23       &= ~0x9F;
+  // LPC_IOCON->PIO0_23       |= 0x01;
+
+  #if defined CFG_MCU_FAMILY_LPC11UXX
+    /* Setup the ADC clock, conversion mode, etc. */
+    LPC_ADC->CR = (0x01 << 0)                            |
+                  ((SystemCoreClock / ADC_CLK - 1) << 8) |  /* CLKDIV = Fpclk / 1000000 - 1 */
+                  (0 << 16)                              |  /* BURST = 0, no BURST, software controlled */
+                  (0 << 24)                              |  /* START = 0 A/D conversion stops */
+                  (0 << 27);                                /* EDGE = 0 (CAP/MAT rising edge, trigger A/D conversion) */
+  #elif defined CFG_MCU_FAMILY_LPC13UXX
+    /* Setup the ADC clock, conversion mode, etc. */
+    LPC_ADC->CR = (0x01 << 0)                            |
+                  ((SystemCoreClock / ADC_CLK - 1) << 8) |  /* CLKDIV = Fpclk / 1000000 - 1 */
+                  (0 << 16)                              |  /* BURST = 0, no BURST, software controlled */
+                  (0 << 17)                              |  /* CLKS = 0, 11 clocks/10 bits */
+                  #if CFG_ADC_MODE_LOWPOWER
+                  (1 << 22)                              |  /* Low-power mode */
+                  #endif
+                  #if CFG_ADC_MODE_10BIT
+                  (1 << 23)                              |  /* 10-bit mode */
+                  #endif
+                  (0 << 24)                              |  /* START = 0 A/D conversion stops */
+                  (0 << 27);                                /* EDGE = 0 (CAP/MAT rising edge, trigger A/D conversion) */
+  #endif
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the specified ADC channel
+
+    @param  channelNum
+            The ADC channel number to read (0..7)
+*/
+/**************************************************************************/
+uint32_t adcRead(uint8_t channelNum)
+{
+  uint32_t regVal;
+
+  /* Channel number is 0 through 7 */
+  if (channelNum >= ADC_CHANNELS)
+  {
+    channelNum = 0;
+  }
+
+  /* Enable the correct channel and start a new conversion */
+  LPC_ADC->CR &= 0xFFFFFF00;
+  LPC_ADC->CR |= (1 << 24) | (1 << channelNum);
+
+  /* Wait until the conversion is complete */
+  while (1)
+  {
+    regVal = LPC_ADC->DR[channelNum];
+    if ( regVal & ADC_DONE )
+    {
+      break;
+    }
+  }
+
+  /* Stop the ADC */
+  LPC_ADC->CR &= 0xF8FFFFFF;
+
+  #if defined CFG_MCU_FAMILY_LPC11UXX
+      return ( regVal >> 6 ) & 0x3FF;
+  #elif defined CFG_MCU_FAMILY_LPC13UXX
+    #if CFG_ADC_MODE_10BIT
+      return ( regVal >> 6 ) & 0x3FF;
+    #else
+      return ( regVal >> 4 ) & 0xFFF;
+    #endif
+  #endif
+}
diff --git a/reform2-lpc-fw/src/core/adc/adc.h b/reform2-lpc-fw/src/core/adc/adc.h
new file mode 100644
index 0000000000000000000000000000000000000000..cbc73a81e4d898ae5f3e09df16b9409c9de626b7
--- /dev/null
+++ b/reform2-lpc-fw/src/core/adc/adc.h
@@ -0,0 +1,57 @@
+/**************************************************************************/
+/*!
+    @file     adc.h
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __ADC_H__
+#define __ADC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+#define ADC_OFFSET            (0x10)
+#define ADC_INDEX             (4)
+#define ADC_DONE              (0x80000000)
+#define ADC_CHANNELS          (8)
+#define ADC_CLK               (4000000) /* 4MHz */
+
+void     adcInit (void);
+uint32_t adcRead (uint8_t channelNum);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/core/debug/debug.c b/reform2-lpc-fw/src/core/debug/debug.c
new file mode 100644
index 0000000000000000000000000000000000000000..5d7ac0abca31bd8cfce9027be64a172540c54610
--- /dev/null
+++ b/reform2-lpc-fw/src/core/debug/debug.c
@@ -0,0 +1,66 @@
+/**************************************************************************/
+/*!
+    @file     debug.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#include "debug.h"
+
+/**************************************************************************/
+/*!
+    @brief      Dumps the NVIC priority level of every interrupt
+*/
+/**************************************************************************/
+void debugDumpNVICPriorities(void)
+{
+  uint32_t i = 0;
+
+  #if defined CFG_MCU_FAMILY_LPC11UXX
+    printf("IRQ  Priority%s", CFG_PRINTF_NEWLINE);
+    printf("---  --------%s", CFG_PRINTF_NEWLINE);
+    for (i = 0; i < 32; i++)
+    {
+      printf("%3u: %u %s", (unsigned int)i, (unsigned int)NVIC_GetPriority(i), CFG_PRINTF_NEWLINE);
+    }
+  #elif defined CFG_MCU_FAMILY_LPC13UXX
+    printf("IRQ  Priority%s", CFG_PRINTF_NEWLINE);
+    printf("---  --------%s", CFG_PRINTF_NEWLINE);
+    for (i = 0; i < 32; i++)
+    {
+      printf("%3u: %u %s", (unsigned int)i, (unsigned int)NVIC_GetPriority(i), CFG_PRINTF_NEWLINE);
+    }
+  #else
+    #error "debug.c: No MCU defined"
+  #endif
+}
diff --git a/reform2-lpc-fw/src/core/debug/debug.h b/reform2-lpc-fw/src/core/debug/debug.h
new file mode 100644
index 0000000000000000000000000000000000000000..d9d67d052ce3ef2552a46305f509aa50e6ae77c6
--- /dev/null
+++ b/reform2-lpc-fw/src/core/debug/debug.h
@@ -0,0 +1,51 @@
+/**************************************************************************/
+/*!
+    @file     debug.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _DEBUG_H_
+#define _DEBUG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+void     debugDumpNVICPriorities (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/core/delay/delay.c b/reform2-lpc-fw/src/core/delay/delay.c
new file mode 100644
index 0000000000000000000000000000000000000000..bba9f226994d3e779a64151bc8aaf098f259c0d5
--- /dev/null
+++ b/reform2-lpc-fw/src/core/delay/delay.c
@@ -0,0 +1,252 @@
+/**************************************************************************/
+/*!
+    @file     delay.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#include "delay.h"
+
+/* RTX claims systick so we need to use TIMER16[0] instead */
+#define DELAY_USE_TIMER16_0      (1)
+
+#ifdef CFG_SDCARD
+#include "drivers/storage/fatfs/diskio.h"
+volatile uint32_t fatTicks = 0;
+#endif
+
+volatile uint32_t delayTicks = 0;
+volatile uint32_t delayRollovers = 0;
+
+#if DELAY_USE_TIMER16_0
+/**************************************************************************/
+/*!
+    @brief Interrupt handler for 16-bit timer 0
+*/
+/**************************************************************************/
+#if defined CFG_MCU_FAMILY_LPC11UXX
+void TIMER16_0_IRQHandler(void)
+#elif defined CFG_MCU_FAMILY_LPC13UXX
+void CT16B0_IRQHandler(void)
+#else
+  #error "timer16.c: No MCU defined"
+#endif
+{
+  LPC_CT16B0->IR = 0x1 << 0;  /* Clear MAT0 */
+
+  delayTicks++;
+  if (delayTicks == 0) delayRollovers++;
+
+  #ifdef CFG_SDCARD
+  fatTicks++;
+  if (fatTicks == 10)
+  {
+    fatTicks = 0;
+    disk_timerproc();
+  }
+  #endif
+
+  return;
+}
+#else
+/**************************************************************************/
+/*!
+    @brief Systick interrupt handler
+*/
+/**************************************************************************/
+void SysTick_Handler (void)
+{
+  delayTicks++;
+  if (delayTicks == 0) delayRollovers++;
+
+  #ifdef CFG_SDCARD
+  fatTicks++;
+  if (fatTicks == 10)
+  {
+    fatTicks = 0;
+    disk_timerproc();
+  }
+  #endif
+
+  return;
+}
+#endif
+
+/**************************************************************************/
+/*!
+    @brief      Initialises the delay timer
+*/
+/**************************************************************************/
+void delayInit (void)
+{
+  delayTicks = 0;
+  delayRollovers = 0;
+
+  #if DELAY_USE_TIMER16_0
+    /* Power up the timer */
+    LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 7);
+
+    LPC_CT16B0->TCR  = 0x02;            /* Reset the timer                */
+    LPC_CT16B0->PR   = 0x03;            /* Set prescaler to four          */
+    LPC_CT16B0->IR   = 0xff;            /* Reset all interrrupts          */
+    LPC_CT16B0->PWMC = 0x00;            /* Disable PWM mode               */
+    LPC_CT16B0->MR0  = (SystemCoreClock / 1000) >> 2; /* 1 ms w/prescalar */
+    LPC_CT16B0->MCR  = (0x3<<0);        /* Interrupt and Reset on MR0     */
+
+    /* Make sure the delay timer IRQ has one higher priority than the     *
+     * lowest level to allow for some IRQs to still use delay if          *
+     * absolutely necessary, even if it's not ideal. To allow this, the   *
+     * IRQs calling delay must have the lowest possible priority, which   *
+     * will allow the delay timer to still fire even if we're in the      *
+     * lower priority interrupt handler.                                  */
+    #if defined CFG_MCU_FAMILY_LPC11UXX
+      NVIC_SetPriority(TIMER_16_0_IRQn, (1<<__NVIC_PRIO_BITS) - 2);
+    #elif defined CFG_MCU_FAMILY_LPC13UXX
+      NVIC_SetPriority(CT16B0_IRQn, (1<<__NVIC_PRIO_BITS) - 2);
+    #endif
+    
+    /* Enable the interrupt */
+    #if defined CFG_MCU_FAMILY_LPC11UXX
+    NVIC_EnableIRQ(TIMER_16_0_IRQn);
+    #elif defined CFG_MCU_FAMILY_LPC13UXX
+    NVIC_EnableIRQ(CT16B0_IRQn);
+    #endif
+
+    LPC_CT16B0->TCR  = 0x01;            /* Start timer */
+  #else
+    uint32_t ticks = (SystemCoreClock / 1000);
+
+    /* Reset counter */
+    delayTicks = 0;
+
+    /* Set reload register */
+    SysTick->LOAD  = (ticks & SYSTICK_STRELOAD_MASK) - 1;
+
+    /* Load the systick counter value */
+    SysTick->VAL = 0;
+
+    /* Make sure the systick IRQ has one higher priority than the         *
+     * lowest level (to allow for some IRQs to still use delay if         *
+     * absolutely necessary, even if it's not ideal). By default, the     *
+     * CMSIS SysTick_Config function sets the systick IRQ to the lowest   *
+     * priority at startup (see core_cm0/3.h).                            */
+    #if defined CFG_MCU_FAMILY_LPC11UXX
+      NVIC_SetPriority(SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 2);
+    #elif defined CFG_MCU_FAMILY_LPC13UXX
+      NVIC_SetPriority(SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 2);
+    #endif
+    
+    /* Enable systick IRQ and timer */
+    SysTick->CTRL = SYSTICK_STCTRL_CLKSOURCE |
+                    SYSTICK_STCTRL_TICKINT |
+                    SYSTICK_STCTRL_ENABLE;
+  #endif
+}
+
+/**************************************************************************/
+/*!
+    @brief      Causes a blocking delay for 'ticks' on the timer.  For
+                example: delay(100) would cause a blocking delay for 100
+                ticks of the timer.
+
+    @param[in]  ticks
+                The number of ticks to cause a blocking delay for, with
+                the exact duration of one tick set via delayInit()
+
+    @note       This function takes into account the fact that the tick
+                counter may eventually roll over to 0 once it reaches
+                0xFFFFFFFF.
+*/
+/**************************************************************************/
+void delay (uint32_t ticks)
+{
+  uint32_t curTicks;
+  curTicks = delayTicks;
+
+  // Make sure delay is at least 1 tick in case of division, etc.
+  if (ticks == 0) return;
+
+  if (curTicks > 0xFFFFFFFF - ticks)
+  {
+    // Rollover will occur during delay
+    while (delayTicks >= curTicks)
+    {
+      while (delayTicks < (ticks - (0xFFFFFFFF - curTicks)));
+    }
+  }
+  else
+  {
+    while ((delayTicks - curTicks) < ticks);
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief      Returns the current value of the timer counter.
+                This value is incremented by one every time an interrupt
+                fires for the timer.
+*/
+/**************************************************************************/
+uint32_t delayGetTicks(void)
+{
+  return delayTicks;
+}
+
+/**************************************************************************/
+/*!
+    @brief      Returns the current value of the timer rollover
+                counter. This value is incremented by one every time the
+                tick counter rolls over from 0xFFFFFFFF to 0.
+*/
+/**************************************************************************/
+uint32_t delayGetRollovers(void)
+{
+  return delayRollovers;
+}
+
+/**************************************************************************/
+/*!
+    @brief      Returns the approximate number of seconds that the
+                timer has been running.
+*/
+/**************************************************************************/
+uint32_t delayGetSecondsActive(void)
+{
+  uint32_t currentTick = delayTicks;
+  uint32_t rollovers = delayRollovers;
+  uint32_t secsActive = currentTick / 1000;
+  secsActive += rollovers * (0xFFFFFFFF / 1000);
+
+  return secsActive;
+}
+
diff --git a/reform2-lpc-fw/src/core/delay/delay.h b/reform2-lpc-fw/src/core/delay/delay.h
new file mode 100644
index 0000000000000000000000000000000000000000..647668e51c28410405494d92b07159bd179415f0
--- /dev/null
+++ b/reform2-lpc-fw/src/core/delay/delay.h
@@ -0,0 +1,85 @@
+/**************************************************************************/
+/*!
+    @file     delay.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _DELAY_H_
+#define _DELAY_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+/*  STCTRL (System Timer Control and status register)
+    The STCTRL register contains control information for the System Tick Timer, and provides
+    a status flag.  */
+
+#define SYSTICK_STCTRL_ENABLE                     (0x00000001)    // System tick counter enable
+#define SYSTICK_STCTRL_TICKINT                    (0x00000002)    // System tick interrupt enable
+#define SYSTICK_STCTRL_CLKSOURCE                  (0x00000004)    // NOTE: This isn't documented but is based on NXP examples
+#define SYSTICK_STCTRL_COUNTFLAG                  (0x00010000)    // System tick counter flag
+
+/*  STRELOAD (System Timer Reload value register)
+    The STRELOAD register is set to the value that will be loaded into the System Tick Timer
+    whenever it counts down to zero. This register is loaded by software as part of timer
+    initialization. The STCALIB register may be read and used as the value for STRELOAD if
+    the CPU or external clock is running at the frequency intended for use with the STCALIB
+    value.  */
+
+#define SYSTICK_STRELOAD_MASK                     (0x00FFFFFF)
+
+/*  STCURR (System Timer Current value register)
+    The STCURR register returns the current count from the System Tick counter when it is
+    read by software. */
+
+#define SYSTICK_STCURR_MASK                       (0x00FFFFFF)
+
+/*  STCALIB (System Timer Calibration value register) */
+
+#define SYSTICK_STCALIB_TENMS_MASK                (0x00FFFFFF)
+#define SYSTICK_STCALIB_SKEW_MASK                 (0x40000000)
+#define SYSTICK_STCALIB_NOREF_MASK                (0x80000000)
+
+void     delayInit (void);
+void     delay (uint32_t ticks);
+uint32_t delayGetTicks(void);
+uint32_t delayGetRollovers(void);
+uint32_t delayGetSecondsActive(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/core/dwt/dwt.h b/reform2-lpc-fw/src/core/dwt/dwt.h
new file mode 100644
index 0000000000000000000000000000000000000000..63f820b556c519ef4f222cb361e5b3e07200bc88
--- /dev/null
+++ b/reform2-lpc-fw/src/core/dwt/dwt.h
@@ -0,0 +1,119 @@
+/**************************************************************************/
+/*!
+    @file     dwt.h
+    @author   K. Townsend (microBuilder.eu)
+
+    Data Watchpoint and Trace Unit (DWT)
+
+    @section DESCRIPTION
+
+    For more information, see Cortex-M3 Technical Reference Manual 8.3
+    This block is optional and not all comparators or functionality may
+    be present on all chips, though basic DWT functionality is present
+    on the LPC1347 since CYCNT works
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microbuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _DWT_H_
+#define _DWT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+/* DWT is only supported on the Cortex M3, so make sure this isn't an M0 */
+#if defined CFG_MCU_FAMILY_LPC13UXX
+
+// Macro to initialise, reset and enable the cycle counter.
+// This can be used for rough timing and performance tests
+// by resetting the cycle counter before a function, and
+// then reading the value after with "int count = DWT->CYCCNT"
+//
+//    DWT_RESET_CYCLECOUNTER;
+//    ... do something
+//    int count = DWT->CYCCNT;
+
+#define DWT_RESET_CYCLECOUNTER    do { CoreDebug->DEMCR = CoreDebug->DEMCR | 0x01000000;  \
+                                       DWT->CYCCNT = 0;                                   \
+                                       DWT->CTRL = DWT->CTRL | 1 ; } while(0)
+
+/* Inline Functions */
+static INLINE void dwtDelay(uint32_t ticks) INLINE_POST;
+
+/**************************************************************************/
+/*!
+    @brief  Causes a delay for approximately the specified number of ticks
+
+    @note   This function has the following overhead:
+            Release mode:   ~21 cycles
+            Debug mode:     ~36 cycles
+
+    @param[in]  ticks
+                The number of clock cycles to wait
+
+    @section EXAMPLE
+
+    @code
+
+    // Test DWT delay
+    uint32_t usec = 3;
+    uint32_t ticks = (SystemCoreClock / 1000000) * usec;
+    dwtDelay(ticks);                      // Delay (stays low)
+    uint32_t oh = DWT->CYCCNT - ticks;    // Calculate function overhead
+
+    @endcode
+*/
+/**************************************************************************/
+static INLINE void dwtDelay(uint32_t ticks)
+{
+  // Use the DWT core clock cycle counter for reasonably precise
+  // microsecond delays.  This is only supported by the Cortex M3 (not
+  // the Cortex M0), and is an optional component present on the LPC1343
+  // and LPC1347 ... but a less chip-dependent solution should be
+  // implemented that also works with the LPC11U37 and LPC11U24.
+
+  // Reset the cycle counter to 0 (good for up to 59 seconds @ 72MHz)
+  DWT_RESET_CYCLECOUNTER;
+  while (DWT->CYCCNT < ticks)
+  {
+    __asm volatile ("NOP");
+  }
+}
+
+#endif // CFG_MCU_FAMILY_LPC13UXX
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/core/eeprom/eeprom.c b/reform2-lpc-fw/src/core/eeprom/eeprom.c
new file mode 100644
index 0000000000000000000000000000000000000000..30a02789c9bb6f1e65ce3b1705dba7a990435790
--- /dev/null
+++ b/reform2-lpc-fw/src/core/eeprom/eeprom.c
@@ -0,0 +1,160 @@
+/**************************************************************************/
+/*!
+    @file     eeprom.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+
+
+#include "projectconfig.h"
+
+#include <string.h>
+#include "eeprom.h"
+
+typedef void (*IAP)(unsigned int [],unsigned int[]);
+static const IAP iap_entry = (IAP) 0x1FFF1FF1;
+
+/**************************************************************************/
+/*!
+    @brief   Writes a byte array to the on-chip EEPROM memory
+
+    @code
+    uint8_t buffer[4];
+    uint32_t address = 0x00000000;
+
+    buffer[0] = 0x87;
+    buffer[1] = 0x65;
+    buffer[2] = 0x43;
+    buffer[3] = 0x21;
+
+    // Write four bytes starting at address
+    writeEEPROM((uint8_t*)address, buffer, 4);
+    @endcode
+*/
+/**************************************************************************/
+RAMFUNC err_t writeEEPROM( uint8_t* eeAddress, uint8_t* buffAddress, uint32_t byteCount )
+{
+  unsigned int command[5], result[4];
+
+  /* EEPROM Write     : IAP Command Code : 61
+     Param 1          : EEPROM address
+     Param 2          : RAM address of data/buffer to write
+     Param 3          : Number of bytes to be written
+     Param 4          : System clock frequency in kHz (SystemCoreClock/1000)
+     Return Codes     : 0 - CMD_SUCCESS
+                        4 - SRC_ADDR_NOT_MAPPED
+                        5 - DST_ADDR_NOT_MAPPED */
+  command[0] = 61;
+  command[1] = (uint32_t) eeAddress;
+  command[2] = (uint32_t) buffAddress;
+  command[3] = byteCount;
+  command[4] = (uint32_t) (SystemCoreClock/1000);
+
+  /* Invoke IAP call (interrupts need to be disabled during IAP calls)...*/
+  __disable_irq();
+  iap_entry(command, result);
+  __enable_irq();
+  if (0 != result[0])
+  {
+    return ERROR_ADDRESSOUTOFRANGE;
+  }
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief   Reads a byte array from the on-chip EEPROM memory
+
+    @code
+    uint8_t buffer[4] = { 0x00, 0x00, 0x00, 0x00 };
+    uint32_t address = 0x00000000;
+
+    // Read four bytes starting at address
+    readEEPROM((uint8_t*) address, buffer, 4);
+    @endcode
+*/
+/**************************************************************************/
+RAMFUNC err_t readEEPROM( uint8_t* eeAddress, uint8_t* buffAddress, uint32_t byteCount )
+{
+  unsigned int command[5], result[4];
+
+  /* EEPROM Read      : IAP Command Code : 62
+     Param 1          : EEPROM address
+     Param 2          : RAM address to store data
+     Param 3          : Number of bytes to read
+     Param 4          : System clock frequency in kHz (SystemCoreClock/1000)
+     Return Codes     : 0 - CMD_SUCCESS
+                        4 - SRC_ADDR_NOT_MAPPED
+                        5 - DST_ADDR_NOT_MAPPED */
+  command[0] = 62;
+  command[1] = (uint32_t) eeAddress;
+  command[2] = (uint32_t) buffAddress;
+  command[3] = byteCount;
+  command[4] = (uint32_t) (SystemCoreClock/1000);
+
+  /* Invoke IAP call (interrupts need to be disabled during IAP calls)...*/
+  __disable_irq();
+  iap_entry(command, result);
+  __enable_irq();
+  if (0 != result[0])
+  {
+    return ERROR_ADDRESSOUTOFRANGE;
+  }
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief   Dumps the entire contents of EEPROM via printf
+*/
+/**************************************************************************/
+void eepromDump(void)
+{
+  uint32_t i,j;
+  uint8_t z;
+
+  char valBuff[12];
+  char lineBuff[80];
+
+  for (i=0; i<CFG_EEPROM_SIZE; i+=16)
+  {
+    sprintf(lineBuff,"0x%03X ", (unsigned int)i);
+    for (j=0; j<16; j++)
+    {
+      readEEPROM( (uint8_t*) i+j, (uint8_t*) &z, 1);
+      sprintf(valBuff,"%02X ", (unsigned int)z);
+      strcat(lineBuff,valBuff);
+    }
+    strcat(lineBuff,"\r\n");
+    printf((char*) lineBuff);
+  }
+}
diff --git a/reform2-lpc-fw/src/core/eeprom/eeprom.h b/reform2-lpc-fw/src/core/eeprom/eeprom.h
new file mode 100644
index 0000000000000000000000000000000000000000..7da4ac777d276adce34817d8a45e722649f59e2d
--- /dev/null
+++ b/reform2-lpc-fw/src/core/eeprom/eeprom.h
@@ -0,0 +1,55 @@
+/**************************************************************************/
+/*!
+    @file     eeprom.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __EEPROM_H__
+#define __EEPROM_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+/* IAP functions need to be placed in SRAM */
+RAMFUNC err_t writeEEPROM( uint8_t* eeAddress, uint8_t* buffAddress, uint32_t byteCount );
+RAMFUNC err_t readEEPROM( uint8_t* eeAddress, uint8_t* buffAddress, uint32_t byteCount );
+
+void eepromDump(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/core/fifo/README.md b/reform2-lpc-fw/src/core/fifo/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..3b1893849736b170b6c29db559c74dd55ce649a3
--- /dev/null
+++ b/reform2-lpc-fw/src/core/fifo/README.md
@@ -0,0 +1,53 @@
+# FIFO #
+
+**fifo.c** attempts to provide a generic buffer that can be used as either a **classic FIFO** (first in, first out), or as a **circular buffer** (by making the fifo 'overwrittable').  Various type lengths can be assigned, so it can also be used with structs, or any arbitrary data type.
+
+## Using fifo.c as a Classic FIFO Buffer ##
+
+The following code will create a FIFO buffer named 'buffer' that is 8 int32\_t values long, with the 'overwrittable' flag set to false, meaning that when the buffer is full we won't be able to add new values via 'fifo\_write' until a previous value is read out.
+
+The last argument is option, but in the case we will disable the USB interrupt while the FIFO is being manipulated to avoid any conflicts from incoming USB interrupts.  Simple assign NULL to this parameter if you don't want to enable the IRQ mutex support.
+```
+  FIFO_DEF(buffer, 8, int32_t, false, USB_IRQn);
+```
+To write an entry into the fifo, we call the 'fifo\_write' function, which will return either true or false depending on if the data was successfully written (for example if the fifo is already full):
+```
+  bool success;
+  success = fifo_write(&buffer, 12345);
+```
+To read an entry from the fifo, we call the 'fifo\_read' or 'fifo\_readarray' functions:
+```
+  bool success;
+  int32_t val;
+  success = fifo_read(&buffer, &val);  // True if the buffer is not empty
+```
+We can also clear the fifo with the 'fifo\_clear' function:
+```
+  fifo_clear(&buffer);
+```
+
+## Using fifo.c as a Circular Buffer ##
+
+The following code will create a circular buffer named 'cbuffer' using fifo.c, configuring it to be 8 samples wide, and using floating point data (meaning 32 bytes of memory will be used, since a single float takes 4 bytes, multiplied by our buffer size of 8 samples).  Notice the 'true' parameter, which means that this fifo instance is overwrittable, which is what allows us to emulate a circular buffer:
+```
+  // Create a circular buffer named 'cbuffer' 8 float values wide
+  FIFO_DEF(cbuffer, 8, float, true, NULL);
+```
+To do the same for uint16\_t data, we would use the following code, which would require 16 bytes of memory since uint16\_t uses two bytes compared to four for float:
+```
+  // Create a circular buffer named 'cbuffer' 8 uint16_t values wide
+  FIFO_DEF(cbuffer, 8, uint16_t, true, NULL);
+```
+To add samples into the circular buffer, we simple call the 'add' function as follows (assuming we are using float values):
+```
+  fifo_write(&cbuffer, 1.5F);
+```
+To read the samples back, we need to use the 'fifo\_peek' function (since fifo\_read is destructive and is used for a classic FIFO configuration):
+```
+  bool success;
+  float val;
+  // Assign item 1 in the circular buffer to 'val'
+  success = fifo_peek(&cbuffer, 1, &val);   // Peek since read is destructive!
+  // Assign item 3 in the circular buffer to 'val'
+  success = fifo_peek(&cbuffer, 3, &val);   // Peek since read is destructive!
+```
diff --git a/reform2-lpc-fw/src/core/fifo/fifo.c b/reform2-lpc-fw/src/core/fifo/fifo.c
new file mode 100644
index 0000000000000000000000000000000000000000..4ade5072c595323f59c51a14f4da21fb6337fa13
--- /dev/null
+++ b/reform2-lpc-fw/src/core/fifo/fifo.c
@@ -0,0 +1,278 @@
+/**************************************************************************/
+/*!
+    @file     fifo.c
+    @author   Thach Ha (tinyusb.org)
+
+    @section DESCRIPTION
+
+    Light-weight FIFO buffer with basic mutex support
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <string.h>
+#include "fifo.h"
+
+static inline void mutex_lock   (fifo_t* f) INLINE_POST;
+static inline void mutex_unlock (fifo_t* f) INLINE_POST;
+static inline bool is_fifo_initalized(fifo_t* f) INLINE_POST;
+
+/**************************************************************************/
+/*!
+    @brief Initialises the FIFO buffer
+
+    @param[in]  f
+                Pointer to the fifo_t object to intiialize
+    @param[in]  buffer
+                Pointer to the buffer's location in memory
+    @param[in]  size
+                The buffer size in bytes
+    @param[in]  overwritable
+                Set to TRUE is the FIFO is overwritable when the FIFO
+                is full (the first element will be overwritten)
+    @param[in]  irq
+                The IRQ number to disable for MUTEX protection.
+                Set the -1 if not required.
+
+    @returns TRUE if the initialisation was successful
+
+    @code
+    static uint8_t buffer[512];  // Create FIFO buffer in memory
+    static fifo_t ff;
+
+    // Initialise a non-overwriteable buffer with MUTEX on USB IRQ
+    fifo_init (&ff, buffer, 512, false, USB_IRQn);
+    @endcode
+*/
+/**************************************************************************/
+//bool fifo_init(fifo_t* f, uint8_t* buffer, uint16_t size, bool overwritable, IRQn_Type irq)
+//{
+//  ASSERT(size > 0, false);
+//
+//  f->buf = buffer;
+//  f->depth = size;
+//  f->rd_idx = f->wr_idx = f->count = 0;
+//  f->overwritable = overwritable;
+//  f->irq = irq;
+//
+//  return true;
+//}
+
+/**************************************************************************/
+/*!
+    @brief Read one byte out of the RX buffer.
+
+    This function will return the byte located at the array index of the
+    read pointer, and then increment the read pointer index.  If the read
+    pointer exceeds the maximum buffer size, it will roll over to zero.
+
+    @param[in]  f
+                Pointer to the FIFO buffer to manipulate
+    @param[in]  data
+                Pointer to the place holder for data read from the buffer
+
+    @returns TRUE if the queue is not empty
+*/
+/**************************************************************************/
+bool fifo_read(fifo_t* f, void * p_buffer)
+{
+  if( !is_fifo_initalized(f) || fifo_isEmpty(f) )
+  {
+    return false;
+  }
+
+  mutex_lock(f);
+
+  memcpy(p_buffer,
+         f->buffer + (f->rd_idx * f->item_size),
+         f->item_size);
+  f->rd_idx = (f->rd_idx + 1) % f->depth;
+  f->count--;
+
+  mutex_unlock(f);
+
+  return true;
+}
+
+/**************************************************************************/
+/*!
+    @brief Read a byte array from FIFO
+
+    @param[in]  f
+                Pointer to the FIFO buffer to manipulate
+    @param[in]  rx
+                Pointer to the place holder for data read from the buffer
+    @param[in]  maxlen
+                The maximum number of bytes to read from the FIFO
+
+    @returns The actual number of bytes read from the FIFO
+ */
+/**************************************************************************/
+uint16_t fifo_readArray(fifo_t* f, void * p_buffer, uint16_t maxlen)
+{
+  uint16_t count = 0;
+  
+  while ( count < maxlen && fifo_read(f, p_buffer) )
+  {
+    count++;
+    p_buffer += f->item_size;
+  }
+  
+  return count;
+}
+
+bool fifo_peek(fifo_t* f, uint16_t position, void * p_buffer)
+{
+  if( !is_fifo_initalized(f) || fifo_isEmpty(f) || (position >= f->count) )
+  {
+    return false;
+  }
+
+  uint16_t index = (f->rd_idx + position) % f->depth; // rd_idx is position=0
+  memcpy(p_buffer,
+         f->buffer + (index * f->item_size),
+         f->item_size);
+
+  return true;
+}
+
+/**************************************************************************/
+/*!
+    @brief Write one byte into the RX buffer.
+
+    This function will write one byte into the array index specified by
+    the write pointer and increment the write index. If the write index
+    exceeds the max buffer size, then it will roll over to zero.
+
+    @param[in]  f
+                Pointer to the FIFO buffer to manipulate
+    @param[in]  data
+                The byte to add to the FIFO
+
+    @returns TRUE if the data was written to the FIFO (overwrittable
+             FIFO will always return TRUE)
+*/
+/**************************************************************************/
+bool fifo_write(fifo_t* f, void const * p_data)
+{
+  if ( !is_fifo_initalized(f) || (fifo_isFull(f) && !f->overwritable) )
+  {
+    return false;
+  }
+
+  mutex_lock(f);
+
+  memcpy( f->buffer + (f->wr_idx * f->item_size),
+          p_data,
+          f->item_size);
+
+  f->wr_idx = (f->wr_idx + 1) % f->depth;
+
+  if (fifo_isFull(f))
+  {
+    f->rd_idx = f->wr_idx; // keep the full state (rd == wr && len = size)
+  }else
+  {
+    f->count++;
+  }
+
+  mutex_unlock(f);
+
+  return true;
+}
+
+/**************************************************************************/
+/*!
+    @brief Clear the fifo read and write pointers and set length to zero
+
+    @param[in]  f
+                Pointer to the FIFO buffer to manipulate
+*/
+/**************************************************************************/
+void fifo_clear(fifo_t *f)
+{
+  mutex_lock(f);
+
+  f->rd_idx = f->wr_idx = f->count = 0;
+
+  mutex_unlock(f);
+}
+
+//--------------------------------------------------------------------+
+// HELPER FUNCTIONS
+//--------------------------------------------------------------------+
+
+/**************************************************************************/
+/*!
+    @brief Disables the IRQ specified in the FIFO's 'irq' field
+           to prevent reads/write issues with interrupts
+
+    @param[in]  f
+                Pointer to the FIFO that should be protected
+*/
+/**************************************************************************/
+static inline void mutex_lock (fifo_t* f)
+{
+  if (f->irq > 0)
+  {
+    #ifndef _TEST_
+    NVIC_DisableIRQ(f->irq);
+    #endif
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief Re-enables the IRQ specified in the FIFO's 'irq' field
+
+    @param[in]  f
+                Pointer to the FIFO that should be protected
+*/
+/**************************************************************************/
+static inline void mutex_unlock (fifo_t* f)
+{
+  if (f->irq > 0)
+  {
+    #ifndef _TEST_
+    NVIC_EnableIRQ(f->irq);
+    #endif
+  }
+}
+
+static inline bool is_fifo_initalized(fifo_t* f)
+{
+  if( f->buffer == NULL || f->depth == 0 || f->item_size == 0)
+  {
+    return false;
+  }else
+  {
+    return true;
+  }
+}
diff --git a/reform2-lpc-fw/src/core/fifo/fifo.h b/reform2-lpc-fw/src/core/fifo/fifo.h
new file mode 100644
index 0000000000000000000000000000000000000000..3d6338ec865d8fe0747fb32e8d62f7515574dcb6
--- /dev/null
+++ b/reform2-lpc-fw/src/core/fifo/fifo.h
@@ -0,0 +1,96 @@
+/**************************************************************************/
+/*!
+    @file     fifo.h
+    @author   Thach Ha
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __FIFO_H__
+#define __FIFO_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+typedef struct _fifo_t
+{
+           void *  const buffer    ; ///< buffer pointer
+           uint16_t const depth     ; ///< max items
+           uint16_t const item_size ; ///< size of each item
+  volatile uint16_t count           ; ///< number of items in queue
+  volatile uint16_t wr_idx          ; ///< write pointer
+  volatile uint16_t rd_idx          ; ///< read pointer
+  bool overwritable;
+  IRQn_Type irq;
+} fifo_t;
+
+#define FIFO_DEF(name, ff_depth, type, is_overwritable, irq_mutex)\
+  type name##_buffer[ff_depth];\
+  fifo_t name = {\
+      .buffer       = name##_buffer,\
+      .depth        = ff_depth,\
+      .item_size    = sizeof(type),\
+      .overwritable = is_overwritable,\
+      .irq          = irq_mutex\
+  }
+
+//bool fifo_init(fifo_t* f, uint8_t* buffer, uint16_t size, bool overwritable, IRQn_Type irq);
+bool fifo_write(fifo_t* f, void const * p_data);
+bool fifo_read(fifo_t* f, void * p_buffer);
+bool fifo_peek(fifo_t* f, uint16_t position, void * p_buffer);
+uint16_t fifo_readArray(fifo_t* f, void * p_buffer, uint16_t maxlen);
+void fifo_clear(fifo_t *f);
+
+static inline bool fifo_isEmpty(fifo_t* f) INLINE_POST;
+static inline bool fifo_isEmpty(fifo_t* f)
+{
+  return (f->count == 0);
+}
+
+static inline bool fifo_isFull(fifo_t* f) INLINE_POST;
+static inline bool fifo_isFull(fifo_t* f)
+{
+  return (f->count == f->depth);
+}
+
+static inline uint16_t fifo_getLength(fifo_t* f) INLINE_POST;
+static inline uint16_t fifo_getLength(fifo_t* f)
+{
+  return f->count;
+}
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/core/gpio/gpio.c b/reform2-lpc-fw/src/core/gpio/gpio.c
new file mode 100644
index 0000000000000000000000000000000000000000..ccdad6d07ffc831c6515a3628c6274e83716e709
--- /dev/null
+++ b/reform2-lpc-fw/src/core/gpio/gpio.c
@@ -0,0 +1,557 @@
+/**************************************************************************/
+/*!
+    @file     gpio.c
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "gpio.h"
+
+/**************************************************************************/
+/*!
+    @brief Initialises the GPIO block
+*/
+/**************************************************************************/
+void GPIOInit( void )
+{
+  /* Enable AHB clock to the GPIO domain. */
+  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
+
+  /* Enable AHB clock to the PinInt, GroupedInt domain. */
+  LPC_SYSCON->SYSAHBCLKCTRL |= ((1<<19) | (1<<23) | (1<<24));
+
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Sets up a GPIO interrupt, including sense and polarity (event)
+
+    @param[in]  channelNum
+                Interrupt channel number (0..7)
+    @param[in]  portNum
+                Port number for the pin to setup as the interrupt source
+    @param[in]  bitPosi
+                Bit position of the pin to setup as the interrupt source
+    @param[in]  sense
+                Edge or level sensitive (0 = edge, 1 = level)
+    @param[in]  event
+                Polarity for the interrupt (0 = active low/falling-edge,
+                1 = active high/rising edge)
+*/
+/**************************************************************************/
+void GPIOSetPinInterrupt( uint32_t channelNum, uint32_t portNum,
+    uint32_t bitPosi, uint32_t sense, uint32_t event )
+{
+  /* Pair the interrupt channel to the specified pin */
+  switch ( channelNum )
+  {
+    case CHANNEL0:
+      if ( portNum )
+      {
+        #if defined CFG_MCU_FAMILY_LPC11UXX
+            LPC_SYSCON->PINTSEL[0] = bitPosi + 24;
+        #elif defined CFG_MCU_FAMILY_LPC13UXX
+            LPC_SYSCON->PINSEL[0] = bitPosi + 24;
+        #endif
+      }
+      else
+      {
+        #if defined CFG_MCU_FAMILY_LPC11UXX
+            LPC_SYSCON->PINTSEL[0] = bitPosi;
+        #elif defined CFG_MCU_FAMILY_LPC13UXX
+            LPC_SYSCON->PINSEL[0] = bitPosi;
+        #endif
+      }
+      #if defined CFG_MCU_FAMILY_LPC11UXX
+        NVIC_EnableIRQ(FLEX_INT0_IRQn);
+      #elif defined CFG_MCU_FAMILY_LPC13UXX
+        NVIC_EnableIRQ(PIN_INT0_IRQn);
+      #endif
+    break;
+    case CHANNEL1:
+      if ( portNum )
+      {
+        #if defined CFG_MCU_FAMILY_LPC11UXX
+            LPC_SYSCON->PINTSEL[1] = bitPosi + 24;
+        #elif defined CFG_MCU_FAMILY_LPC13UXX
+            LPC_SYSCON->PINSEL[1] = bitPosi + 24;
+        #endif
+      }
+      else
+      {
+        #if defined CFG_MCU_FAMILY_LPC11UXX
+            LPC_SYSCON->PINTSEL[1] = bitPosi;
+        #elif defined CFG_MCU_FAMILY_LPC13UXX
+            LPC_SYSCON->PINSEL[1] = bitPosi;
+        #endif
+      }
+      #if defined CFG_MCU_FAMILY_LPC11UXX
+        NVIC_EnableIRQ(FLEX_INT1_IRQn);
+      #elif defined CFG_MCU_FAMILY_LPC13UXX
+        NVIC_EnableIRQ(PIN_INT1_IRQn);
+      #endif
+    break;
+    case CHANNEL2:
+      if ( portNum )
+      {
+        #if defined CFG_MCU_FAMILY_LPC11UXX
+            LPC_SYSCON->PINTSEL[2] = bitPosi + 24;
+        #elif defined CFG_MCU_FAMILY_LPC13UXX
+            LPC_SYSCON->PINSEL[2] = bitPosi + 24;
+        #endif
+      }
+      else
+      {
+        #if defined CFG_MCU_FAMILY_LPC11UXX
+            LPC_SYSCON->PINTSEL[2] = bitPosi;
+        #elif defined CFG_MCU_FAMILY_LPC13UXX
+            LPC_SYSCON->PINSEL[2] = bitPosi;
+        #endif
+      }
+      #if defined CFG_MCU_FAMILY_LPC11UXX
+        NVIC_EnableIRQ(FLEX_INT2_IRQn);
+      #elif defined CFG_MCU_FAMILY_LPC13UXX
+        NVIC_EnableIRQ(PIN_INT2_IRQn);
+      #endif
+    break;
+    case CHANNEL3:
+      if ( portNum )
+      {
+        #if defined CFG_MCU_FAMILY_LPC11UXX
+            LPC_SYSCON->PINTSEL[3] = bitPosi + 24;
+        #elif defined CFG_MCU_FAMILY_LPC13UXX
+            LPC_SYSCON->PINSEL[3] = bitPosi + 24;
+        #endif
+      }
+      else
+      {
+        #if defined CFG_MCU_FAMILY_LPC11UXX
+            LPC_SYSCON->PINTSEL[3] = bitPosi;
+        #elif defined CFG_MCU_FAMILY_LPC13UXX
+            LPC_SYSCON->PINSEL[3] = bitPosi;
+        #endif
+      }
+      #if defined CFG_MCU_FAMILY_LPC11UXX
+        NVIC_EnableIRQ(FLEX_INT3_IRQn);
+      #elif defined CFG_MCU_FAMILY_LPC13UXX
+        NVIC_EnableIRQ(PIN_INT3_IRQn);
+      #endif
+    break;
+    case CHANNEL4:
+      if ( portNum )
+      {
+        #if defined CFG_MCU_FAMILY_LPC11UXX
+            LPC_SYSCON->PINTSEL[4] = bitPosi + 24;
+        #elif defined CFG_MCU_FAMILY_LPC13UXX
+            LPC_SYSCON->PINSEL[4] = bitPosi + 24;
+        #endif
+      }
+      else
+      {
+        #if defined CFG_MCU_FAMILY_LPC11UXX
+            LPC_SYSCON->PINTSEL[4] = bitPosi;
+        #elif defined CFG_MCU_FAMILY_LPC13UXX
+            LPC_SYSCON->PINSEL[4] = bitPosi;
+        #endif
+      }
+      #if defined CFG_MCU_FAMILY_LPC11UXX
+        NVIC_EnableIRQ(FLEX_INT4_IRQn);
+      #elif defined CFG_MCU_FAMILY_LPC13UXX
+        NVIC_EnableIRQ(PIN_INT4_IRQn);
+      #endif
+    break;
+    case CHANNEL5:
+      if ( portNum )
+      {
+        #if defined CFG_MCU_FAMILY_LPC11UXX
+            LPC_SYSCON->PINTSEL[5] = bitPosi + 24;
+        #elif defined CFG_MCU_FAMILY_LPC13UXX
+            LPC_SYSCON->PINSEL[5] = bitPosi + 24;
+        #endif
+      }
+      else
+      {
+        #if defined CFG_MCU_FAMILY_LPC11UXX
+            LPC_SYSCON->PINTSEL[5] = bitPosi;
+        #elif defined CFG_MCU_FAMILY_LPC13UXX
+            LPC_SYSCON->PINSEL[5] = bitPosi;
+        #endif
+      }
+      #if defined CFG_MCU_FAMILY_LPC11UXX
+        NVIC_EnableIRQ(FLEX_INT5_IRQn);
+      #elif defined CFG_MCU_FAMILY_LPC13UXX
+        NVIC_EnableIRQ(PIN_INT5_IRQn);
+      #endif
+    break;
+    case CHANNEL6:
+      if ( portNum )
+      {
+        #if defined CFG_MCU_FAMILY_LPC11UXX
+            LPC_SYSCON->PINTSEL[6] = bitPosi + 24;
+        #elif defined CFG_MCU_FAMILY_LPC13UXX
+            LPC_SYSCON->PINSEL[6] = bitPosi + 24;
+        #endif
+      }
+      else
+      {
+        #if defined CFG_MCU_FAMILY_LPC11UXX
+            LPC_SYSCON->PINTSEL[6] = bitPosi;
+        #elif defined CFG_MCU_FAMILY_LPC13UXX
+            LPC_SYSCON->PINSEL[6] = bitPosi;
+        #endif
+      }
+      #if defined CFG_MCU_FAMILY_LPC11UXX
+        NVIC_EnableIRQ(FLEX_INT6_IRQn);
+      #elif defined CFG_MCU_FAMILY_LPC13UXX
+        NVIC_EnableIRQ(PIN_INT6_IRQn);
+      #endif
+    break;
+    case CHANNEL7:
+      if ( portNum )
+      {
+        #if defined CFG_MCU_FAMILY_LPC11UXX
+            LPC_SYSCON->PINTSEL[7] = bitPosi + 24;
+        #elif defined CFG_MCU_FAMILY_LPC13UXX
+            LPC_SYSCON->PINSEL[7] = bitPosi + 24;
+        #endif
+      }
+      else
+      {
+        #if defined CFG_MCU_FAMILY_LPC11UXX
+            LPC_SYSCON->PINTSEL[7] = bitPosi;
+        #elif defined CFG_MCU_FAMILY_LPC13UXX
+            LPC_SYSCON->PINSEL[7] = bitPosi;
+        #endif
+      }
+      #if defined CFG_MCU_FAMILY_LPC11UXX
+        NVIC_EnableIRQ(FLEX_INT7_IRQn);
+      #elif defined CFG_MCU_FAMILY_LPC13UXX
+        NVIC_EnableIRQ(PIN_INT7_IRQn);
+      #endif
+    break;
+    default:
+      break;
+  }
+
+  /* Configure for edge (0) or level (1) sensitivity */
+  if ( sense == 0 )
+  {
+    /* Interrupt is edge sensitive */
+    LPC_GPIO_PIN_INT->ISEL &= ~(0x1<<channelNum);       /* Edge trigger */
+    if ( event == 0 )
+    {
+      LPC_GPIO_PIN_INT->IENF |= (0x1<<channelNum);      /* Falling edge */
+    }
+    else
+    {
+      LPC_GPIO_PIN_INT->IENR |= (0x1<<channelNum);      /* Rising edge */
+    }
+  }
+  else
+  {
+    /* Interrupt is level sensitive */
+    LPC_GPIO_PIN_INT->ISEL |= (0x1<<channelNum);        /* Level trigger. */
+    LPC_GPIO_PIN_INT->IENR |= (0x1<<channelNum);        /* Level enable */
+    if ( event == 0 )
+    {
+      LPC_GPIO_PIN_INT->IENF &= ~(0x1<<channelNum);      /* active-low */
+    }
+    else
+    {
+      LPC_GPIO_PIN_INT->IENF |= (0x1<<channelNum);      /* active-high */
+    }
+  }
+
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Enables the specified interrupt
+
+    @param[in]  channelNum
+                Interrupt channel number (0..7)
+    @param[in]  event
+                Polarity for the interrupt (0 = active low/falling-edge,
+                1 = active high/rising edge)
+*/
+/**************************************************************************/
+void GPIOPinIntEnable( uint32_t channelNum, uint32_t event )
+{
+  if ( !( LPC_GPIO_PIN_INT->ISEL & (0x1<<channelNum) ) )
+  {
+    if ( event == 0 )
+    {
+      LPC_GPIO_PIN_INT->SIENF |= (0x1<<channelNum);      /* Falling edge */
+    }
+    else
+    {
+      LPC_GPIO_PIN_INT->SIENR |= (0x1<<channelNum);      /* Rising edge */
+    }
+  }
+  else
+  {
+    LPC_GPIO_PIN_INT->SIENR |= (0x1<<channelNum);        /* Level */
+  }
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Disables the specified interrupt
+
+    @param[in]  channelNum
+                Interrupt channel number (0..7)
+    @param[in]  event
+                Polarity for the interrupt (0 = active low/falling-edge,
+                1 = active high/rising edge)
+*/
+/**************************************************************************/
+void GPIOPinIntDisable( uint32_t channelNum, uint32_t event )
+{
+  if ( !( LPC_GPIO_PIN_INT->ISEL & (0x1<<channelNum) ) )
+  {
+    if ( event == 0 )
+    {
+      LPC_GPIO_PIN_INT->CIENF |= (0x1<<channelNum);      /* Falling edge */
+    }
+    else
+    {
+      LPC_GPIO_PIN_INT->CIENR |= (0x1<<channelNum);      /* Rising edge */
+    }
+  }
+  else
+  {
+    LPC_GPIO_PIN_INT->CIENR |= (0x1<<channelNum);        /* Level */
+  }
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Gets the interrupt status
+
+    @param[in]  channelNum
+                Interrupt channel number (0..7)
+*/
+/**************************************************************************/
+uint32_t GPIOPinIntStatus( uint32_t channelNum )
+{
+  if ( LPC_GPIO_PIN_INT->IST & (0x1<<channelNum) )
+  {
+    return( 1 );
+  }
+  else
+  {
+    return( 0 );
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief Clears the specified interrupt
+
+    @param[in]  channelNum
+                Interrupt channel number (0..7)
+*/
+/**************************************************************************/
+void GPIOPinIntClear( uint32_t channelNum )
+{
+  if ( !( LPC_GPIO_PIN_INT->ISEL & (0x1<<channelNum) ) )
+  {
+    LPC_GPIO_PIN_INT->IST = (1<<channelNum);
+  }
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets up the interrupt logic (sense, eventPattern, etc.) for
+            a grouped interrupt
+
+    @param[in]  groupNum
+                Grouped interrupt number (0..1)
+    @param[in]  bitPattern
+                Bit pattern to match
+    @param[in]  logic
+                AND or OR logic (0 = OR, 1 = AND)
+    @param[in]  sense
+                Edge or level sensitive (0 = edge, 1 = level)
+    @param[in]  eventPattern
+                Polarity pattern for the interrupt (0 = low/falling-edge,
+                1 = high/rising edge)
+*/
+/**************************************************************************/
+void GPIOSetGroupedInterrupt( uint32_t groupNum, uint32_t *bitPattern,
+      uint32_t logic, uint32_t sense, uint32_t *eventPattern )
+{
+  switch ( groupNum )
+  {
+    case GROUP0:
+      if ( sense == 0 )
+      {
+        LPC_GPIO_GROUP_INT0->CTRL &= ~(0x1<<2);        /* Edge trigger */
+      }
+      else
+      {
+        LPC_GPIO_GROUP_INT0->CTRL |= (0x1<<2);        /* Level trigger. */
+      }
+      if ( logic == 0 )
+      {
+        LPC_GPIO_GROUP_INT0->CTRL &= ~(0x1<<1);        /* OR */
+      }
+      else
+      {
+        LPC_GPIO_GROUP_INT0->CTRL |= (0x1<<1);        /* AND */
+      }
+      LPC_GPIO_GROUP_INT0->PORT_POL[0] = *((uint32_t *)(eventPattern + 0));
+      LPC_GPIO_GROUP_INT0->PORT_POL[1] = *((uint32_t *)(eventPattern + 1));
+      LPC_GPIO_GROUP_INT0->PORT_ENA[0] = *((uint32_t *)(bitPattern + 0));
+      LPC_GPIO_GROUP_INT0->PORT_ENA[1] = *((uint32_t *)(bitPattern + 1));
+      /* As soon as enabled, an edge may be generated       */
+      /* clear interrupt flag and NVIC pending interrupt to */
+      /* workaround the potential edge generated as enabled */
+      LPC_GPIO_GROUP_INT0->CTRL |= (1<<0);
+      NVIC_ClearPendingIRQ(GINT0_IRQn);
+      NVIC_EnableIRQ(GINT0_IRQn);
+      break;
+    case GROUP1:
+      if ( sense == 0 )
+      {
+        LPC_GPIO_GROUP_INT1->CTRL &= ~(0x1<<2);        /* Edge trigger */
+      }
+      else
+      {
+        LPC_GPIO_GROUP_INT1->CTRL |= (0x1<<2);        /* Level trigger. */
+      }
+      if ( logic == 0 )
+      {
+        LPC_GPIO_GROUP_INT1->CTRL &= ~(0x1<<1);        /* OR */
+      }
+      else
+      {
+        LPC_GPIO_GROUP_INT1->CTRL |= (0x1<<1);        /* AND */
+      }
+      LPC_GPIO_GROUP_INT1->PORT_POL[0] = *((uint32_t *)(eventPattern + 0));
+      LPC_GPIO_GROUP_INT1->PORT_POL[1] = *((uint32_t *)(eventPattern + 1));
+      LPC_GPIO_GROUP_INT1->PORT_ENA[0] = *((uint32_t *)(bitPattern + 0));
+      LPC_GPIO_GROUP_INT1->PORT_ENA[1] = *((uint32_t *)(bitPattern + 1));
+      /* As soon as enabled, an edge may be generated       */
+      /* clear interrupt flag and NVIC pending interrupt to */
+      /* workaround the potential edge generated as enabled */
+      LPC_GPIO_GROUP_INT1->CTRL |= (1<<0);
+      NVIC_ClearPendingIRQ(GINT1_IRQn);
+      NVIC_EnableIRQ(GINT1_IRQn);
+      break;
+    default:
+      break;
+  }
+
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Reads the current state of the specified pin
+
+    @param[in]  portNum
+                Port number for the pin
+    @param[in]  bitPosi
+                Bit position of the pin
+*/
+/**************************************************************************/
+uint32_t GPIOGetPinValue( uint32_t portNum, uint32_t bitPosi )
+{
+  uint32_t regVal = 0;
+
+  if( bitPosi < 0x20 )
+  {
+    if ( LPC_GPIO->PIN[portNum] & (0x1<<bitPosi) )
+    {
+      regVal = 1;
+    }
+  }
+  else if( bitPosi == 0xFF )
+  {
+    regVal = LPC_GPIO->PIN[portNum];
+  }
+  return ( regVal );
+}
+
+/**************************************************************************/
+/*!
+    @brief Sets the state of the specified pin
+
+    @param[in]  portNum
+                Port number for the pin
+    @param[in]  bitPosi
+                Bit position of the pin
+    @param[in]  bitVal
+                1 to set the pin high, 0 to set it low
+*/
+/**************************************************************************/
+void GPIOSetBitValue( uint32_t portNum, uint32_t bitPosi, uint32_t bitVal )
+{
+  if ( bitVal )
+  {
+        LPC_GPIO->SET[portNum] = 1<<bitPosi;
+  }
+  else
+  {
+        LPC_GPIO->CLR[portNum] = 1<<bitPosi;
+  }
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Sets the pin direction (input or output)
+
+    @param[in]  portNum
+                Port number for the pin
+    @param[in]  bitPosi
+                Bit position of the pin
+    @param[in]  dir
+                Pin direction (1 = output, 0 = input)
+*/
+/**************************************************************************/
+void GPIOSetDir( uint32_t portNum, uint32_t bitPosi, uint32_t dir )
+{
+  if( dir )
+  {
+        LPC_GPIO->DIR[portNum] |= (1<<bitPosi);
+  }
+  else
+  {
+        LPC_GPIO->DIR[portNum] &= ~(1<<bitPosi);
+  }
+  return;
+}
diff --git a/reform2-lpc-fw/src/core/gpio/gpio.h b/reform2-lpc-fw/src/core/gpio/gpio.h
new file mode 100644
index 0000000000000000000000000000000000000000..6348a505ef5feec69db152b075ffae65d3923e55
--- /dev/null
+++ b/reform2-lpc-fw/src/core/gpio/gpio.h
@@ -0,0 +1,74 @@
+/**************************************************************************/
+/*!
+    @file     gpio.h
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __GPIO_H__
+#define __GPIO_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+#define CHANNEL0        (0)
+#define CHANNEL1        (1)
+#define CHANNEL2        (2)
+#define CHANNEL3        (3)
+#define CHANNEL4        (4)
+#define CHANNEL5        (5)
+#define CHANNEL6        (6)
+#define CHANNEL7        (7)
+
+#define PORT0           (0)
+#define PORT1           (1)
+
+#define GROUP0          (0)
+#define GROUP1          (1)
+
+void     GPIOInit ( void );
+void     GPIOSetPinInterrupt ( uint32_t channelNum, uint32_t portNum, uint32_t bitPosi, uint32_t sense, uint32_t event );
+void     GPIOPinIntEnable ( uint32_t channelNum, uint32_t event );
+void     GPIOPinIntDisable ( uint32_t channelNum, uint32_t event );
+uint32_t GPIOPinIntStatus ( uint32_t channelNum );
+void     GPIOPinIntClear ( uint32_t channelNum );
+void     GPIOSetGroupedInterrupt ( uint32_t groupNum, uint32_t *bitPattern, uint32_t logic, uint32_t sense, uint32_t *eventPattern );
+uint32_t GPIOGetPinValue ( uint32_t portNum, uint32_t bitPosi );
+void     GPIOSetBitValue ( uint32_t portNum, uint32_t bitPosi, uint32_t bitVal );
+void     GPIOSetDir ( uint32_t portNum, uint32_t bitPosi, uint32_t dir );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/core/i2c/i2c.c b/reform2-lpc-fw/src/core/i2c/i2c.c
new file mode 100644
index 0000000000000000000000000000000000000000..21b77a7b2afb0014caf54356aa37ea47dd47a712
--- /dev/null
+++ b/reform2-lpc-fw/src/core/i2c/i2c.c
@@ -0,0 +1,404 @@
+/*****************************************************************************
+ *   i2c.c:  I2C C file for NXP LPC11xx/13xx Family Microprocessors
+ *
+ *   Copyright(C) 2008, NXP Semiconductor
+ *   Parts of this code are (C) 2010, MyVoice CAD/CAM Services
+ *   All rights reserved.
+ *
+ *   History
+ *   2009.12.07  ver 1.00    Preliminary version, first Release
+ *   2010.07.19  ver 1.10    Rob Jansen - MyVoice CAD/CAM Services:
+ *                           Major cleaning and a rewrite of some functions
+ *                           - adding ACK/NACK handling to the state machine
+ *                           - adding a return result to the I2CEngine()
+ *
+*****************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_ENABLE_I2C
+
+#include "i2c.h"
+
+volatile uint32_t I2CMasterState = I2CSTATE_IDLE;
+volatile uint32_t I2CSlaveState = I2CSTATE_IDLE;
+
+volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE];    // Master Mode
+volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE];     // Master Mode
+
+volatile uint32_t I2CReadLength;
+volatile uint32_t I2CWriteLength;
+
+volatile uint32_t I2CRdIndex;
+volatile uint32_t I2CWrIndex;
+
+volatile uint32_t _I2cMode;                       // I2CMASTER or I2CSLAVE (only master is used at present)
+
+/*****************************************************************************
+** Function name:                I2C_IRQHandler
+**
+** Descriptions:                I2C interrupt handler, deal with master mode only.
+**
+** parameters:                        None
+** Returned value:                None
+**
+*****************************************************************************/
+void I2C_IRQHandler(void)
+{
+        uint8_t StatValue;
+
+        /* this handler deals with master read and master write only */
+        StatValue = LPC_I2C->STAT;
+        switch ( StatValue )
+        {
+        case 0x08:
+                /*
+                 * A START condition has been transmitted.
+                 * We now send the slave address and initialize
+                 * the write buffer
+                 * (we always start with a write after START+SLA)
+                 */
+                I2CWrIndex = 0;
+                LPC_I2C->DAT = I2CMasterBuffer[I2CWrIndex++];
+                LPC_I2C->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
+                I2CMasterState = I2CSTATE_PENDING;
+                break;
+
+        case 0x10:
+                /*
+                 * A repeated START condition has been transmitted.
+                 * Now a second, read, transaction follows so we
+                 * initialize the read buffer.
+                 */
+                I2CRdIndex = 0;
+                /* Send SLA with R bit set, */
+                LPC_I2C->DAT = I2CMasterBuffer[I2CWrIndex++];
+                LPC_I2C->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
+        break;
+
+        case 0x18:
+                /*
+                 * SLA+W has been transmitted; ACK has been received.
+                 * We now start writing bytes.
+                 */
+                LPC_I2C->DAT = I2CMasterBuffer[I2CWrIndex++];
+                LPC_I2C->CONCLR = I2CONCLR_SIC;
+                break;
+
+        case 0x20:
+                /*
+                 * SLA+W has been transmitted; NOT ACK has been received.
+                 * Send a stop condition to terminate the transaction
+                 * and signal I2CEngine the transaction is aborted.
+                 */
+                LPC_I2C->CONSET = I2CONSET_STO;
+                LPC_I2C->CONCLR = I2CONCLR_SIC;
+                I2CMasterState = I2CSTATE_SLA_NACK;
+                break;
+
+        case 0x28:
+                /*
+                 * Data in I2DAT has been transmitted; ACK has been received.
+                 * Continue sending more bytes as long as there are bytes to send
+                 * and after this check if a read transaction should follow.
+                 */
+                if ( I2CWrIndex < I2CWriteLength )
+                {
+                        /* Keep writing as long as bytes avail */
+                        LPC_I2C->DAT = I2CMasterBuffer[I2CWrIndex++];
+                }
+                else
+                {
+                        if ( I2CReadLength != 0 )
+                        {
+                                /* Send a Repeated START to initialize a read transaction */
+                                /* (handled in state 0x10)                                */
+                                LPC_I2C->CONSET = I2CONSET_STA;        /* Set Repeated-start flag */
+                        }
+                        else
+                        {
+                                I2CMasterState = I2CSTATE_ACK;
+                                LPC_I2C->CONSET = I2CONSET_STO;      /* Set Stop flag */
+                        }
+                }
+                LPC_I2C->CONCLR = I2CONCLR_SIC;
+                break;
+
+        case 0x30:
+                /*
+                 * Data byte in I2DAT has been transmitted; NOT ACK has been received
+                 * Send a STOP condition to terminate the transaction and inform the
+                 * I2CEngine that the transaction failed.
+                 */
+                LPC_I2C->CONSET = I2CONSET_STO;
+                LPC_I2C->CONCLR = I2CONCLR_SIC;
+                I2CMasterState = I2CSTATE_NACK;
+                break;
+
+        case 0x38:
+                /*
+                 * Arbitration loss in SLA+R/W or Data bytes.
+                 * This is a fatal condition, the transaction did not complete due
+                 * to external reasons (e.g. hardware system failure).
+                 * Inform the I2CEngine of this and cancel the transaction
+                 * (this is automatically done by the I2C hardware)
+                 */
+                I2CMasterState = I2CSTATE_ARB_LOSS;
+                LPC_I2C->CONCLR = I2CONCLR_SIC;
+                break;
+
+        case 0x40:
+                /*
+                 * SLA+R has been transmitted; ACK has been received.
+                 * Initialize a read.
+                 * Since a NOT ACK is sent after reading the last byte,
+                 * we need to prepare a NOT ACK in case we only read 1 byte.
+                 */
+                if ( I2CReadLength == 1 )
+                {
+                        /* last (and only) byte: send a NACK after data is received */
+                        LPC_I2C->CONCLR = I2CONCLR_AAC;
+                }
+                else
+                {
+                        /* more bytes to follow: send an ACK after data is received */
+                        LPC_I2C->CONSET = I2CONSET_AA;
+                }
+                LPC_I2C->CONCLR = I2CONCLR_SIC;
+                break;
+
+        case 0x48:
+                /*
+                 * SLA+R has been transmitted; NOT ACK has been received.
+                 * Send a stop condition to terminate the transaction
+                 * and signal I2CEngine the transaction is aborted.
+                 */
+                LPC_I2C->CONSET = I2CONSET_STO;
+                LPC_I2C->CONCLR = I2CONCLR_SIC;
+                I2CMasterState = I2CSTATE_SLA_NACK;
+                break;
+
+        case 0x50:
+                /*
+                 * Data byte has been received; ACK has been returned.
+                 * Read the byte and check for more bytes to read.
+                 * Send a NOT ACK after the last byte is received
+                 */
+                I2CSlaveBuffer[I2CRdIndex++] = LPC_I2C->DAT;
+                if ( I2CRdIndex < (I2CReadLength-1) )
+                {
+                        /* lmore bytes to follow: send an ACK after data is received */
+                        LPC_I2C->CONSET = I2CONSET_AA;
+                }
+                else
+                {
+                        /* last byte: send a NACK after data is received */
+                        LPC_I2C->CONCLR = I2CONCLR_AAC;
+                }
+                LPC_I2C->CONCLR = I2CONCLR_SIC;
+                break;
+
+        case 0x58:
+                /*
+                 * Data byte has been received; NOT ACK has been returned.
+                 * This is the last byte to read.
+                 * Generate a STOP condition and flag the I2CEngine that the
+                 * transaction is finished.
+                 */
+                I2CSlaveBuffer[I2CRdIndex++] = LPC_I2C->DAT;
+                I2CMasterState = I2CSTATE_ACK;
+                LPC_I2C->CONSET = I2CONSET_STO;        /* Set Stop flag */
+                LPC_I2C->CONCLR = I2CONCLR_SIC;        /* Clear SI flag */
+                break;
+
+        default:
+                LPC_I2C->CONCLR = I2CONCLR_SIC;
+                break;
+  }
+  return;
+}
+
+/*****************************************************************************
+** Function name:        I2CStart
+**
+** Descriptions:        Create I2C start condition, a timeout
+**                        value is set if the I2C never gets started,
+**                        and timed out. It's a fatal error.
+**
+** parameters:                None
+** Returned value:        true or false, return false if timed out
+**
+*****************************************************************************/
+static uint32_t I2CStart( void )
+{
+  uint32_t timeout = 0;
+
+  /*--- Issue a start condition ---*/
+  LPC_I2C->CONSET = I2CONSET_STA;      /* Set Start flag */
+
+  while((I2CMasterState != I2CSTATE_PENDING) && (timeout < MAX_TIMEOUT))
+  {
+    timeout++;
+  }
+
+  return (timeout < MAX_TIMEOUT);
+}
+
+/*****************************************************************************
+** Function name:        I2CStop
+**
+** Descriptions:        Set the I2C stop condition
+**
+** parameters:                None
+** Returned value:        true or never return
+**
+*****************************************************************************/
+static uint32_t I2CStop( void )
+{
+  uint32_t timeout = 0;
+
+  LPC_I2C->CONSET = I2CONSET_STO;  /* Set Stop flag */
+  LPC_I2C->CONCLR = I2CONCLR_SIC;  /* Clear SI flag */
+
+  /*--- Wait for STOP detected ---*/
+  while((LPC_I2C->CONSET & I2CONSET_STO) && (timeout < MAX_TIMEOUT))
+  {
+    timeout++;
+  }
+  return (timeout >= MAX_TIMEOUT);
+}
+
+/*****************************************************************************
+** Function name:        I2CInit
+**
+** Descriptions:        Initialize I2C controller
+**
+** parameters:                I2c mode is either MASTER or SLAVE
+** Returned value:        true or false, return false if the I2C
+**                        interrupt handler was not installed correctly
+**
+*****************************************************************************/
+uint32_t i2cInit( uint32_t I2cMode )
+{
+  _I2cMode = I2cMode;
+
+  LPC_SYSCON->PRESETCTRL |= (0x1<<1);
+
+  /* Enable AHB clock to the I2C domain. */
+  LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 5);
+
+  /* Set P0.4 to SCL and I2C mode (open drain) */
+  LPC_IOCON->PIO0_4 &= ~0x07 | 0x300; /* Add I2C mode mask */
+  LPC_IOCON->PIO0_4 |= 0x01;
+
+  /* Set P0.5 to SDA and I2C mode (open drain) */
+  LPC_IOCON->PIO0_5 &= ~0x07 | 0x300; /* Add I2C mode mask */
+  LPC_IOCON->PIO0_5 |= 0x01;
+
+  // Clear flags
+  LPC_I2C->CONCLR = I2CONCLR_AAC |
+                  I2CONCLR_SIC |
+                  I2CONCLR_STAC |
+                  I2CONCLR_I2ENC;
+
+#if I2C_FAST_MODE_PLUS
+  LPC_IOCON->PIO0_4 |= (0x200); /* Fast mode plus */
+  LPC_IOCON->PIO0_5 |= (0x200); /* Fast mode plus */
+  LPC_I2C->SCLL   = I2C_SCLL_HS_SCLL;
+  LPC_I2C->SCLH   = I2C_SCLH_HS_SCLH;
+#else
+  LPC_I2C->SCLL   = I2SCLL_SCLL;
+  LPC_I2C->SCLH   = I2SCLH_SCLH;
+#endif
+
+  if ( _I2cMode == I2CSLAVE )
+  {
+    LPC_I2C->ADR0 = SLAVE_ADDR;
+    I2CSlaveState = I2C_IDLE;
+  }
+
+  /* Enable the I2C Interrupt */
+  NVIC_EnableIRQ(I2C_IRQn);
+  if ( _I2cMode == I2CMASTER )
+  {
+    LPC_I2C->CONSET = I2CONSET_I2EN;
+  }
+
+  return( TRUE );
+}
+
+/*****************************************************************************
+** Function name:        I2CEngine
+**
+** Descriptions:        The routine to complete a I2C transaction
+**                        from start to stop. All the intermitten
+**                        steps are handled in the interrupt handler.
+**                        Before this routine is called, the read
+**                        length, write length and I2C master buffer
+**                        need to be filled.
+**
+** parameters:                None
+** Returned value:        Any of the I2CSTATE_... values. See i2c.h
+**
+*****************************************************************************/
+uint32_t i2cEngine( void )
+{
+  I2CMasterState = I2CSTATE_IDLE;
+  I2CRdIndex = 0;
+  I2CWrIndex = 0;
+  if ( I2CStart() != TRUE )
+  {
+        // I2C timed out
+    I2CStop();
+    return ( I2CSTATE_TIMEOUT );
+  }
+
+  /* wait until the state is a terminal state */
+  while (I2CMasterState < 0x100);
+
+  return ( I2CMasterState );
+}
+
+/*****************************************************************************
+** Function name:        i2cCheckAddress
+**
+** Descriptions:        The routine checks if a device is present at
+**                        the specified address.
+**
+** parameters:                8-bit address byte including the read bit
+** Returned value:        True if a device ACKed, otherwise False
+**
+*****************************************************************************/
+bool i2cCheckAddress( uint8_t addr )
+{
+  uint32_t i2cState;
+
+  // Send the addr byte and check for ACK
+  I2CWriteLength = 1;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = addr;
+  i2cState = i2cEngine();
+
+  // Check if we got an ACK
+  if ((i2cState == I2CSTATE_NACK) || (i2cState == I2CSTATE_SLA_NACK))
+  {
+    // I2C slave didn't acknowledge the master transfer
+    // The device probably isn't connected
+    return false;
+  }
+  else if (i2cState == I2CSTATE_TIMEOUT)
+  {
+    // I2C timed out waiting for start/stop
+        return false;
+  }
+  else
+  {
+    // I2C device found
+    return true;
+  }
+}
+
+/******************************************************************************
+**                            End Of File
+******************************************************************************/
+
+#endif
diff --git a/reform2-lpc-fw/src/core/i2c/i2c.h b/reform2-lpc-fw/src/core/i2c/i2c.h
new file mode 100644
index 0000000000000000000000000000000000000000..12144fa1f6164fb9547ca978ed27f0df48927087
--- /dev/null
+++ b/reform2-lpc-fw/src/core/i2c/i2c.h
@@ -0,0 +1,134 @@
+/*****************************************************************************
+ *   i2c.h:  Header file for NXP LPC11xx Family Microprocessors
+ *
+ *   Copyright(C) 2006, NXP Semiconductor
+ *   Parts of this code are (C) 2010, MyVoice CAD/CAM Services
+ *   All rights reserved.
+ *
+ *   History
+ *   2006.07.19  ver 1.00    Preliminary version, first Release
+ *   2010.07.19  ver 1.10    Rob Jansen - MyVoice CAD/CAM Services
+ *                           Updated to reflect new code
+ *   2011.02.19  ver 1.20    KTownsend - microBuilder.eu
+ *                           - Added slave mode status values to
+ *                             I2C_IRQHandler
+ *
+******************************************************************************/
+#ifndef __I2C_H
+#define __I2C_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+/*
+ * These are states returned by the I2CEngine:
+ *
+ * IDLE     - is never returned but only used internally
+ * PENDING  - is never returned but only used internally in the I2C functions
+ * ACK      - The transaction finished and the slave returned ACK (on all bytes)
+ * NACK     - The transaction is aborted since the slave returned a NACK
+ * SLA_NACK - The transaction is aborted since the slave returned a NACK on the SLA
+ *            this can be intentional (e.g. an 24LC08 EEPROM states it is busy)
+ *            or the slave is not available/accessible at all.
+ * ARB_LOSS - Arbitration loss during any part of the transaction.
+ *            This could only happen in a multi master system or could also
+ *            identify a hardware problem in the system.
+ */
+#define I2CSTATE_IDLE       0x000
+#define I2CSTATE_PENDING    0x001
+#define I2CSTATE_ACK        0x101
+#define I2CSTATE_NACK       0x102
+#define I2CSTATE_SLA_NACK   0x103
+#define I2CSTATE_ARB_LOSS   0x104
+#define I2CSTATE_TIMEOUT    0x105  // Timeout reached in I2CStart or I2CStop
+
+#define FAST_MODE_PLUS      0
+
+#define I2C_BUFSIZE         64
+#define MAX_TIMEOUT         0x0000FFFF
+
+#define I2CMASTER           0x01
+#define I2CSLAVE            0x02
+
+#define SLAVE_ADDR          0xA0
+#define READ_WRITE          0x01
+
+#define RD_BIT              0x01
+
+#define I2C_GENERALCALL     0x00        /* General Call Address (to 'ping' I2C bus for devices) */
+
+#define I2C_IDLE            0
+#define I2C_STARTED         1
+#define I2C_RESTARTED       2
+#define I2C_REPEATED_START  3
+#define DATA_ACK            4
+#define DATA_NACK           5
+#define I2C_WR_STARTED      6
+#define I2C_RD_STARTED      7
+
+/* I2C Control Set Register */
+#define I2CONSET_I2EN       0x00000040  /* I2C Interface Enable */
+#define I2CONSET_AA         0x00000004  /* Assert acknowledge flag */
+#define I2CONSET_SI         0x00000008  /* I2C interrupt flag */
+#define I2CONSET_STO        0x00000010  /* STOP flag */
+#define I2CONSET_STA        0x00000020  /* START flag */
+
+/* I2C Control clear Register */
+#define I2CONCLR_AAC        0x00000004  /* Assert acklnowedge clear bit*/
+#define I2CONCLR_SIC        0x00000008  /* I2C interrupt clear bit */
+#define I2CONCLR_STAC       0x00000020  /* START flag clear bit */
+#define I2CONCLR_I2ENC      0x00000040  /* I2C interface disable bit */
+
+#define I2DAT_I2C           0x00000000  /* I2C Data Reg */
+#define I2ADR_I2C           0x00000000  /* I2C Slave Address Reg */
+
+/* SCLH and SCLL = I2C PCLK High/Low cycles for I2C clock and
+  determine the data rate/duty cycle for I2C:
+
+  I2CBitFrequency = I2CPCLK / (I2CSCLH + I2CSCLL)
+
+  Standard Mode   (100KHz) = SystemCoreClock / 200000
+  Fast Mode       (400KHz) = SystemCoreClock / 800000
+  Fast- Mode Plus (1MHz)   = SystemCoreClock / 2000000       */
+
+#define I2SCLH_SCLH       SystemCoreClock / 800000  /* Standard Mode I2C SCL Duty Cycle High (400KHz) */
+#define I2SCLL_SCLL       SystemCoreClock / 800000  /* Fast Mode I2C SCL Duty Cycle Low (400KHz) */
+#define I2SCLH_HS_SCLH    SystemCoreClock / 2000000  /* Fast Plus I2C SCL Duty Cycle High Reg */
+#define I2SCLL_HS_SCLL    SystemCoreClock / 2000000  /* Fast Plus I2C SCL Duty Cycle Low Reg */
+
+
+/* This macro can be used to check the response from i2cEngine for common errors
+ * and return an appropriate global error code. */
+#define ASSERT_I2C_STATUS_MESSAGE(sts, message) \
+        do{\
+      int32_t _status = (sts); \
+          if ((I2CSTATE_NACK == _status) || (I2CSTATE_SLA_NACK == _status)) { \
+                return ERROR_I2C_NOACK; \
+          } \
+          if (I2CSTATE_TIMEOUT == _status) {\
+            return ERROR_I2C_TIMEOUT;\
+          }\
+        } while(0)
+
+#define ASSERT_I2C_STATUS(sts)                ASSERT_I2C_STATUS_MESSAGE(sts, NULL)
+
+extern volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE];    // Master Mode
+extern volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE];     // Master Mode
+extern volatile uint32_t I2CReadLength, I2CWriteLength;
+
+extern void     I2C_IRQHandler( void );
+extern uint32_t i2cInit( uint32_t I2cMode );
+extern uint32_t i2cEngine( void );
+bool            i2cCheckAddress( uint8_t addr );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end __I2C_H */
+/****************************************************************************
+**                            End Of File
+*****************************************************************************/
diff --git a/reform2-lpc-fw/src/core/iap/iap.c b/reform2-lpc-fw/src/core/iap/iap.c
new file mode 100644
index 0000000000000000000000000000000000000000..5380d7649cf52d2a0545c9b48ecd759ce7c0c191
--- /dev/null
+++ b/reform2-lpc-fw/src/core/iap/iap.c
@@ -0,0 +1,67 @@
+/**************************************************************************/
+/*!
+    @file     iap.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#include <stdio.h>
+#include <string.h>
+#include "iap.h"
+
+typedef void (*IAP)(unsigned int [],unsigned int[]);
+static const IAP iap_entry = (IAP) 0x1FFF1FF1;
+
+/**************************************************************************/
+/*!
+    @brief Reads the 128-bit unique chip ID via an IAP call
+
+    @param[in]  uid
+                4-word buffer to hold the 128-bit ID
+*/
+/**************************************************************************/
+err_t iapReadUID(uint32_t uid[])
+{
+  unsigned int command[5] = {58};
+  unsigned int response[5] = { 0 };
+
+  /* Invoke IAP call...*/
+  __disable_irq();
+  iap_entry(command, response);
+  __enable_irq();
+
+  /* Drop the error bit */
+  memcpy(uid, &response[1], 16);
+
+  return ERROR_NONE;
+}
diff --git a/reform2-lpc-fw/src/core/iap/iap.h b/reform2-lpc-fw/src/core/iap/iap.h
new file mode 100644
index 0000000000000000000000000000000000000000..69ef7fcf740f6b058cd9d85c1cc6e42373a78de2
--- /dev/null
+++ b/reform2-lpc-fw/src/core/iap/iap.h
@@ -0,0 +1,51 @@
+/**************************************************************************/
+/*!
+    @file     iap.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __IAP_H__
+#define __IAP_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+err_t iapReadUID(uint32_t uid[]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/core/libc/stdio.c b/reform2-lpc-fw/src/core/libc/stdio.c
new file mode 100644
index 0000000000000000000000000000000000000000..11f9eaeba209292968f47dee75d73cb1df453b06
--- /dev/null
+++ b/reform2-lpc-fw/src/core/libc/stdio.c
@@ -0,0 +1,650 @@
+/*
+ * Software License Agreement (BSD License)
+ *
+ * Based on original stdio.c released by Atmel
+ * Copyright (c) 2008, Atmel Corporation
+ * All rights reserved.
+ *
+ * Modified by Roel Verdult, Copyright (c) 2010
+ * Modified by Pito 2013 (%f, %e, %E)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+//------------------------------------------------------------------------------
+//         Headers
+//------------------------------------------------------------------------------
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdint.h>
+
+#include "projectconfig.h" // For CFG_PRINTF_MAXSTRINGSIZE
+
+//------------------------------------------------------------------------------
+//         Global Variables
+//------------------------------------------------------------------------------
+
+// Required for proper compilation.
+//struct _reent r = {0, (FILE*) 0, (FILE*) 1, (FILE*) 0};
+//struct _reent *_impure_ptr = &r;
+
+//------------------------------------------------------------------------------
+//         Local Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Writes a character inside the given string. Returns 1.
+// \param pStr  Storage string.
+// \param c  Character to write.
+//------------------------------------------------------------------------------
+signed int append_char(char *pStr, char c)
+{
+    *pStr = c;
+    return 1;
+}
+
+//------------------------------------------------------------------------------
+// Writes a string inside the given string.
+// Returns the size of the written
+// string.
+// \param pStr  Storage string.
+// \param pSource  Source string.
+//------------------------------------------------------------------------------
+signed int PutString(char *pStr, char fill, signed int width, const char *pSource)
+{
+    signed int num = 0;
+
+    while (*pSource != 0) {
+
+        *pStr++ = *pSource++;
+        num++;
+    }
+
+        width -= num;
+        while (width > 0) {
+
+        *pStr++ = fill;
+                num++;
+                width--;
+        }
+
+    return num;
+}
+
+//------------------------------------------------------------------------------
+// Writes an unsigned int inside the given string, using the provided fill &
+// width parameters.
+// Returns the size in characters of the written integer.
+// \param pStr  Storage string.
+// \param fill  Fill character.
+// \param width  Minimum integer width.
+// \param value  Integer value.
+//------------------------------------------------------------------------------
+signed int PutUnsignedInt(
+    char *pStr,
+    char fill,
+    signed int width,
+    unsigned int value)
+{
+    signed int num = 0;
+
+    // Take current digit into account when calculating width
+    width--;
+
+    // Recursively write upper digits
+    if ((value / 10) > 0) {
+
+        num = PutUnsignedInt(pStr, fill, width, value / 10);
+        pStr += num;
+    }
+    // Write filler characters
+    else {
+
+        while (width > 0) {
+
+            append_char(pStr, fill);
+            pStr++;
+            num++;
+            width--;
+        }
+    }
+
+    // Write lower digit
+    num += append_char(pStr, (value % 10) + '0');
+
+    return num;
+}
+
+//------------------------------------------------------------------------------
+// Writes a signed int inside the given string, using the provided fill & width
+// parameters.
+// Returns the size of the written integer.
+// \param pStr  Storage string.
+// \param fill  Fill character.
+// \param width  Minimum integer width.
+// \param value  Signed integer value.
+//------------------------------------------------------------------------------
+signed int PutSignedInt(
+    char *pStr,
+    char fill,
+    signed int width,
+    signed int value)
+{
+    signed int num = 0;
+    unsigned int absolute;
+
+    // Compute absolute value
+    if (value < 0) {
+
+        absolute = -value;
+    }
+    else {
+
+        absolute = value;
+    }
+
+    // Take current digit into account when calculating width
+    width--;
+
+    // Recursively write upper digits
+    if ((absolute / 10) > 0) {
+
+        if (value < 0) {
+
+            num = PutSignedInt(pStr, fill, width, -(absolute / 10));
+        }
+        else {
+
+            num = PutSignedInt(pStr, fill, width, absolute / 10);
+        }
+        pStr += num;
+    }
+    else {
+
+        // Reserve space for sign
+        if (value < 0) {
+
+            width--;
+        }
+
+        // Write filler characters
+        while (width > 0) {
+
+            append_char(pStr, fill);
+            pStr++;
+            num++;
+            width--;
+        }
+
+        // Write sign
+        if (value < 0) {
+
+            num += append_char(pStr, '-');
+            pStr++;
+        }
+    }
+
+    // Write lower digit
+    num += append_char(pStr, (absolute % 10) + '0');
+
+    return num;
+}
+
+//------------------------------------------------------------------------------
+// Writes an hexadecimal value into a string, using the given fill, width &
+// capital parameters.
+// Returns the number of char written.
+// \param pStr  Storage string.
+// \param fill  Fill character.
+// \param width  Minimum integer width.
+// \param maj  Indicates if the letters must be printed in lower- or upper-case.
+// \param value  Hexadecimal value.
+//------------------------------------------------------------------------------
+signed int PutHexa(
+    char *pStr,
+    char fill,
+    signed int width,
+    unsigned char maj,
+    unsigned int value)
+{
+    signed int num = 0;
+
+    // Decrement width
+    width--;
+
+    // Recursively output upper digits
+    if ((value >> 4) > 0) {
+
+        num += PutHexa(pStr, fill, width, maj, value >> 4);
+        pStr += num;
+    }
+    // Write filler chars
+    else {
+
+        while (width > 0) {
+
+            append_char(pStr, fill);
+            pStr++;
+            num++;
+            width--;
+        }
+    }
+
+    // Write current digit
+    if ((value & 0xF) < 10) {
+
+        append_char(pStr, (value & 0xF) + '0');
+    }
+    else if (maj) {
+
+        append_char(pStr, (value & 0xF) - 10 + 'A');
+    }
+    else {
+
+        append_char(pStr, (value & 0xF) - 10 + 'a');
+    }
+    num++;
+
+    return num;
+}
+
+
+//------------------------------------------------------------------------------
+// Writes a float inside the given string, using the provided fill & width
+// parameters.
+// Returns the size of the written integer.
+// \param pStr Storage string.
+// \param fill Fill character.
+// \param width Minimum width.
+// \param value Float value.
+// Pito 6/2013
+// +nnnnnnn.nnnnnnn, -nnnnnnn.nnnnnnn
+//------------------------------------------------------------------------------
+signed int PutFloat(
+    char *pStr,
+    char fill,
+    signed int width,
+    double value)
+{
+
+    int num = 0;
+    int intpart;
+    int fraction;
+
+    if (value < 0.0f)
+    {
+      num+=append_char(pStr+num, '-');
+      value = -value;
+    }
+
+    intpart = (int)value;
+    fraction = (int)((value - intpart) * 1000000.0f + 0.5f );
+
+    num+=PutUnsignedInt(pStr+num,fill,1,(int)(intpart));
+
+    num+=append_char(pStr+num, '.');
+
+    num+=PutUnsignedInt(pStr+num,'0',6,(int)(fraction));
+
+    return num;
+}
+
+
+//------------------------------------------------------------------------------
+// Writes a SCI notation float inside the given string, using the provided fill & width
+// parameters.
+// Returns the size of the written integer.
+// \param pStr Storage string.
+// \param fill Fill character.
+// \param width Minimum width.
+// \param value Float value.
+// Pito 6/2013
+// n.nnnnnnE+nnn, -n.nnnnnnE-nnn
+//------------------------------------------------------------------------------
+signed int PutFloatE(
+    char *pStr,
+    char fill,
+    signed int width,
+    double value)
+{
+    int num = 0;
+    int exponent = 0;
+    int intpart;
+    int fraction;
+
+    if (value < 0.0f)
+    {
+      num+=append_char(pStr+num, '-');
+      value = -value;
+    }
+
+    while (value >= 10.0f)
+    {
+      value /= 10.0f;
+      exponent++;
+    }
+    if (value != 0.0f)
+    {
+      while (value < 1.0f)
+      {
+        value *= 10.0f;
+        exponent--;
+      }
+    }
+
+    intpart = (int)value;
+    fraction = (int)((value-intpart) * 1000000.0f + 0.5f);
+
+    num+=PutUnsignedInt(pStr+num,fill,1,(int)(intpart));
+    num+=append_char(pStr+num, '.');
+    num+=PutUnsignedInt(pStr+num,'0',6,(int)(fraction));
+    num+=append_char(pStr+num, 'E');
+
+    if (exponent >= 0)
+    {
+      num+=append_char(pStr+num, '+');
+    }
+    else
+    {
+      num+=append_char(pStr+num, '-');
+      exponent = -exponent;
+    }
+
+    num+=PutSignedInt(pStr+num,'0',2,(int)(exponent));
+
+    return num;
+}
+
+
+//------------------------------------------------------------------------------
+// Writes an Engineering notation float inside the given string, using the provided fill & width
+// parameters.
+// Returns the size of the written integer.
+// \param pStr Storage string.
+// \param fill Fill character.
+// \param width Minimum width.
+// \param value Float value.
+// Pito 6/2013
+// nnn.nnnE+mmm, -nnn.nnnE-mmm, mmm is multiply of 3
+//------------------------------------------------------------------------------
+signed int PutFloatEE(
+    char *pStr,
+    char fill,
+    signed int width,
+    double value)
+{
+
+    int num = 0;
+        int exponent = 0;
+    int intpart;
+    int fraction;
+
+    if (value < 0.0f) 
+    {
+      num+=append_char(pStr+num, '-');
+      value = -value;
+    }
+
+    while (value >= 1000.0f)
+    {
+      value /= 1000.0f;
+      exponent += 3;
+    }
+    if (value != 0.0f)
+    {
+      while (value < 1.0f)
+      {
+        value *= 1000.0f;
+        exponent -= 3;
+      }
+    }
+
+    intpart = (int)value;
+    fraction = (int)((value - intpart) * 1000.0f + 0.5f);
+
+    num+=PutUnsignedInt(pStr+num,fill,1,(int)(intpart));
+    num+=append_char(pStr+num, '.');
+    num+=PutUnsignedInt(pStr+num,'0',3,(int)(fraction));
+    num+=append_char(pStr+num, 'E');
+
+    if (exponent >= 0) 
+    {
+      num+=append_char(pStr+num, '+');
+    }
+    else 
+    {
+      num+=append_char(pStr+num, '-');
+      exponent = -exponent;
+    }
+
+    num+=PutSignedInt(pStr+num,'0',2,(int)(exponent));
+
+    return num;
+}
+
+
+//------------------------------------------------------------------------------
+//         Global Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Stores the result of a formatted string into another string. Format
+/// arguments are given in a va_list instance.
+/// Return the number of characters written.
+/// \param pStr    Destination string.
+/// \param length  Length of Destination string.
+/// \param pFormat Format string.
+/// \param ap      Argument list.
+//------------------------------------------------------------------------------
+signed int vsnprintf(char *pStr, size_t length, const char *pFormat, va_list ap)
+{
+    char          fill;
+    unsigned char width;
+    signed int    num = 0;
+    signed int    size = 0;
+
+    // Clear the string
+    if (pStr) {
+
+        *pStr = 0;
+    }
+
+    // Phase string
+    while (*pFormat != 0 && size < length) {
+
+        // Normal character
+        if (*pFormat != '%') {
+
+            *pStr++ = *pFormat++;
+            size++;
+        }
+        // Escaped '%'
+        else if (*(pFormat+1) == '%') {
+
+            *pStr++ = '%';
+            pFormat += 2;
+            size++;
+        }
+        // Token delimiter
+        else {
+
+            fill = ' ';
+            width = 0;
+            pFormat++;
+
+            // Parse filler
+            if (*pFormat == '0') {
+
+                fill = '0';
+                pFormat++;
+            }
+
+            // Ignore justifier
+            if (*pFormat == '-') {
+                pFormat++;
+            }
+
+            // Parse width
+            while ((*pFormat >= '0') && (*pFormat <= '9')) {
+
+                width = (width*10) + *pFormat-'0';
+                pFormat++;
+            }
+
+            // Check if there is enough space
+            if (size + width > length) {
+
+                width = length - size;
+            }
+
+            // Parse type
+            // %f, %e, %E Pito 2013
+            switch (*pFormat) {
+            case 'd':
+            case 'i': num = PutSignedInt(pStr, fill, width, va_arg(ap, signed int)); break;
+            case 'u': num = PutUnsignedInt(pStr, fill, width, va_arg(ap, unsigned int)); break;
+            case 'f': num = PutFloat(pStr, fill, width, va_arg(ap, double)); break;
+            case 'e': num = PutFloatE(pStr, fill, width, va_arg(ap, double)); break;
+            case 'E': num = PutFloatEE(pStr, fill, width, va_arg(ap, double)); break;
+            case 'x': num = PutHexa(pStr, fill, width, 0, va_arg(ap, unsigned int)); break;
+            case 'X': num = PutHexa(pStr, fill, width, 1, va_arg(ap, unsigned int)); break;
+            case 's': num = PutString(pStr, fill, width, va_arg(ap, char *)); break;
+            case 'c': num = append_char(pStr, va_arg(ap, unsigned int)); break;
+            default:
+                return EOF;
+            }
+
+            pFormat++;
+            pStr += num;
+            size += num;
+        }
+    }
+
+    // NULL-terminated (final \0 is not counted)
+    if (size < length) {
+
+        *pStr = 0;
+    }
+    else {
+
+        *(--pStr) = 0;
+        size--;
+    }
+
+    return size;
+}
+
+//------------------------------------------------------------------------------
+/// Stores the result of a formatted string into another string. Format
+/// arguments are given in a va_list instance.
+/// Return the number of characters written.
+/// \param pString Destination string.
+/// \param length  Length of Destination string.
+/// \param pFormat Format string.
+/// \param ...     Other arguments
+//------------------------------------------------------------------------------
+signed int snprintf(char *pString, size_t length, const char *pFormat, ...)
+{
+    va_list    ap;
+    signed int rc;
+
+    va_start(ap, pFormat);
+    rc = vsnprintf(pString, length, pFormat, ap);
+    va_end(ap);
+
+    return rc;
+}
+
+//------------------------------------------------------------------------------
+/// Stores the result of a formatted string into another string. Format
+/// arguments are given in a va_list instance.
+/// Return the number of characters written.
+/// \param pString  Destination string.
+/// \param pFormat  Format string.
+/// \param ap       Argument list.
+//------------------------------------------------------------------------------
+signed int vsprintf(char *pString, const char *pFormat, va_list ap)
+{
+    return vsnprintf(pString, CFG_PRINTF_MAXSTRINGSIZE, pFormat, ap);
+}
+
+//------------------------------------------------------------------------------
+/// Outputs a formatted string on the DBGU stream. Format arguments are given
+/// in a va_list instance.
+/// \param pFormat  Format string
+/// \param ap  Argument list.
+//------------------------------------------------------------------------------
+signed int vprintf(const char *pFormat, va_list ap)
+{
+  char pStr[CFG_PRINTF_MAXSTRINGSIZE];
+  char pError[] = "stdio.c: increase CFG_PRINTF_MAXSTRINGSIZE\r\n";
+
+  // Write formatted string in buffer
+  if (vsprintf(pStr, pFormat, ap) >= CFG_PRINTF_MAXSTRINGSIZE) {
+
+    puts(pError);
+    while (1); // Increase CFG_PRINTF_MAXSTRINGSIZE
+  }
+
+  // Display string
+  return puts(pStr);
+}
+
+//------------------------------------------------------------------------------
+/// Outputs a formatted string on the DBGU stream, using a variable number of
+/// arguments.
+/// \param pFormat  Format string.
+//------------------------------------------------------------------------------
+signed int printf(const char *pFormat, ...)
+{
+    va_list ap;
+    signed int result;
+
+    // Forward call to vprintf
+    va_start(ap, pFormat);
+    result = vprintf(pFormat, ap);
+    va_end(ap);
+
+    return result;
+}
+
+
+//------------------------------------------------------------------------------
+/// Writes a formatted string inside another string.
+/// \param pStr  Storage string.
+/// \param pFormat  Format string.
+//------------------------------------------------------------------------------
+signed int sprintf(char *pStr, const char *pFormat, ...)
+{
+    va_list ap;
+    signed int result;
+
+    // Forward call to vsprintf
+    va_start(ap, pFormat);
+    result = vsprintf(pStr, pFormat, ap);
+    va_end(ap);
+
+    return result;
+}
\ No newline at end of file
diff --git a/reform2-lpc-fw/src/core/libc/string.c b/reform2-lpc-fw/src/core/libc/string.c
new file mode 100644
index 0000000000000000000000000000000000000000..c50ad0228e2617b653a6324cb4fc76aaedd73363
--- /dev/null
+++ b/reform2-lpc-fw/src/core/libc/string.c
@@ -0,0 +1,329 @@
+/*
+ * Software License Agreement (BSD License)
+ *
+ * Based on original stdio.c released by Atmel
+ * Copyright (c) 2008, Atmel Corporation
+ * All rights reserved.
+ *
+ * Modified by Roel Verdult, Copyright (c) 2010
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+//------------------------------------------------------------------------------
+//         Headers
+//------------------------------------------------------------------------------
+
+#include <string.h>
+
+//------------------------------------------------------------------------------
+//         Global Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Copies data from a source buffer into a destination buffer. The two buffers
+/// must NOT overlap. Returns the destination buffer.
+/// \param pDestination  Destination buffer.
+/// \param pSource  Source buffer.
+/// \param num  Number of bytes to copy.
+//------------------------------------------------------------------------------
+void * memcpy(void *pDestination, const void *pSource, size_t num)
+{
+    unsigned char *pByteDestination;
+    unsigned char *pByteSource;
+    unsigned int *pAlignedSource = (unsigned int *) pSource;
+    unsigned int *pAlignedDestination = (unsigned int *) pDestination;
+
+    // If num is more than 4 bytes, and both dest. and source are aligned,
+    // then copy dwords
+    if ((((unsigned int) pAlignedDestination & 0x3) == 0)
+        && (((unsigned int) pAlignedSource & 0x3) == 0)
+        && (num >= 4)) {
+
+        while (num >= 4) {
+
+            *pAlignedDestination++ = *pAlignedSource++;
+            num -= 4;
+        }
+    }
+
+    // Copy remaining bytes
+    pByteDestination = (unsigned char *) pAlignedDestination;
+    pByteSource = (unsigned char *) pAlignedSource;
+    while (num--) {
+
+        *pByteDestination++ = *pByteSource++;
+    }
+
+    return pDestination;
+}
+
+//------------------------------------------------------------------------------
+/// Fills a memory region with the given value. Returns a pointer to the
+/// memory region.
+/// \param pBuffer  Pointer to the start of the memory region to fill
+/// \param value    Value to fill the region with
+/// \param num      Size to fill in bytes
+//------------------------------------------------------------------------------
+void * memset(void *pBuffer, int value, size_t num)
+{
+    unsigned char *pByteDestination;
+    unsigned int  *pAlignedDestination = (unsigned int *) pBuffer;
+    unsigned int  alignedValue = (value << 24) | (value << 16) | (value << 8) | value;
+
+    // Set words if possible
+    if ((((unsigned int) pAlignedDestination & 0x3) == 0) && (num >= 4)) {
+        while (num >= 4) {
+            *pAlignedDestination++ = alignedValue;
+            num -= 4;
+        }
+    }
+    // Set remaining bytes
+    pByteDestination = (unsigned char *) pAlignedDestination;
+    while (num--) {
+        *pByteDestination++ = value;
+    }
+    return pBuffer;
+}
+
+void* memmove(void *s1, const void *s2, size_t n)
+{
+  char *s=(char*)s2, *d=(char*)s1;
+  
+  if(d > s){
+    s+=n-1;
+    d+=n-1;
+    while(n){
+      *d--=*s--;
+      n--;
+    }
+  }else if(d < s)
+    while(n){
+      *d++=*s++;
+      n--;
+    }
+  return s1;
+}
+
+int memcmp(const void *av, const void *bv, size_t len)
+{
+  const unsigned char *a = av;
+  const unsigned char *b = bv;
+  size_t i;
+
+  for (i=0; i<len; i++) 
+  {
+    if (a[i] != b[i]) 
+    {
+      return (int)(a[i] - b[i]);
+    }
+  }
+  return 0;
+}
+
+
+
+//-----------------------------------------------------------------------------
+/// Search a character in the given string.
+/// Returns a pointer to the character location.
+/// \param pString   Pointer to the start of the string to search.
+/// \param character The character to find.
+//-----------------------------------------------------------------------------
+char * strchr(const char *pString, int character)
+{
+    char * p = (char *)pString;
+    char   c = character & 0xFF;
+
+    while(*p != c) {
+        if (*p == 0) {
+            return 0;
+        }
+        p++;
+    }
+    return p;
+}
+
+//-----------------------------------------------------------------------------
+/// Return the length of a given string
+/// \param pString Pointer to the start of the string.
+//-----------------------------------------------------------------------------
+size_t strlen(const char *pString)
+{
+    unsigned int length = 0;
+
+    while(*pString++ != 0) {
+        length++;
+    }
+    return length;
+}
+
+
+//-----------------------------------------------------------------------------
+/// Search a character backword from the end of given string.
+/// Returns a pointer to the character location.
+/// \param pString   Pointer to the start of the string to search.
+/// \param character The character to find.
+//-----------------------------------------------------------------------------
+char * strrchr(const char *pString, int character)
+{
+    char *p = 0;
+
+    while(*pString != 0) {
+        if (*pString++ == character) {
+            p = (char*)pString;
+        }
+    }
+    return p;
+}
+
+//-----------------------------------------------------------------------------
+/// Copy from source string to destination string
+/// Return a pointer to the destination string
+/// \param pDestination Pointer to the destination string.
+/// \param pSource      Pointer to the source string.
+//-----------------------------------------------------------------------------
+char * strcpy(char *pDestination, const char *pSource)
+{
+    char *pSaveDest = pDestination;
+
+    for(; (*pDestination = *pSource) != 0; ++pSource, ++pDestination);
+    return pSaveDest;
+}
+
+//-----------------------------------------------------------------------------
+/// Compare the first specified bytes of 2 given strings
+/// Return 0 if equals
+/// Return >0 if 1st string > 2nd string
+/// Return <0 if 1st string < 2nd string
+/// \param pString1 Pointer to the start of the 1st string.
+/// \param pString2 Pointer to the start of the 2nd string.
+/// \param count    Number of bytes that should be compared.
+//-----------------------------------------------------------------------------
+int strncmp(const char *pString1, const char *pString2, size_t count)
+{
+    int r;
+
+    while(count) {
+        r = *pString1 - *pString2;
+        if (r == 0) {
+            if (*pString1 == 0) {
+                break;
+            }
+            pString1++;
+            pString2++;
+            count--;
+            continue;
+        }
+        return r;
+    }
+    return 0;
+}
+
+//-----------------------------------------------------------------------------
+/// Copy the first number of bytes from source string to destination string
+/// Return the pointer to the destination string.
+/// \param pDestination Pointer to the start of destination string.
+/// \param pSource      Pointer to the start of the source string.
+/// \param count        Number of bytes that should be copied.
+//-----------------------------------------------------------------------------
+char * strncpy(char *pDestination, const char *pSource, size_t count)
+{
+    char *pSaveDest = pDestination;
+
+    while (count) {
+        *pDestination = *pSource;
+        if (*pSource == 0) {
+            break;
+        }
+        pDestination++;
+        pSource++;
+        count--;
+    }
+    return pSaveDest;
+}
+
+// Following code is based on the BSD licensed code released by UoC 
+// Copyright (c) 1988 Regents of the University of California
+
+int strcmp(const char *s1, const char *s2)
+{
+  while (*s1 == *s2++)
+    if (*s1++ == 0)
+      return (0);
+  return (*(unsigned char *)s1 - *(unsigned char *)--s2);
+}
+
+char *strtok_r(char *s, const char *delim, char **last)
+{
+  char *spanp;
+  int c, sc;
+  char *tok;
+  
+  
+  if (s == NULL && (s = *last) == NULL)
+    return (NULL);
+  
+  /*
+   * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
+   */
+cont:
+  c = *s++;
+  for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
+    if (c == sc)
+      goto cont;
+  }
+  
+  if (c == 0) {           /* no non-delimiter characters */
+    *last = NULL;
+    return (NULL);
+  }
+  tok = s - 1;
+  
+  /*
+   * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
+   * Note that delim must have one NUL; we stop if we see that, too.
+   */
+  for (;;) {
+    c = *s++;
+    spanp = (char *)delim;
+    do {
+      if ((sc = *spanp++) == c) {
+        if (c == 0)
+          s = NULL;
+        else
+          s[-1] = 0;
+        *last = s;
+        return (tok);
+      }
+    } while (sc != 0);
+  }
+  /* NOTREACHED */
+  return (NULL);
+}
+
+char *strtok(char *s, const char *delim)
+{
+  static char *last;
+  return strtok_r(s, delim, &last);
+}
diff --git a/reform2-lpc-fw/src/core/pmu/pmu.c b/reform2-lpc-fw/src/core/pmu/pmu.c
new file mode 100644
index 0000000000000000000000000000000000000000..f484fa8bfe1a47da4337e7e0c43d7664c693cce3
--- /dev/null
+++ b/reform2-lpc-fw/src/core/pmu/pmu.c
@@ -0,0 +1,72 @@
+/**************************************************************************/
+/*!
+    @file     pmu.c
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "pmu.h"
+
+/**************************************************************************/
+/*!
+    @brief  Configures the appropriate peripherals and puts the MCU in
+            sleep mode
+
+    @param[in]  SleepMode
+                Sleep = 0, Deep Sleep = 1, Power Down = 2
+    @param[in]  SleepCtrl
+                Config bits to assign to LPC_SYSCON->PDSLEEPCFG
+*/
+/**************************************************************************/
+void PMU_Sleep( uint32_t SleepMode, uint32_t SleepCtrl )
+{
+  LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG;
+  LPC_SYSCON->PDSLEEPCFG = SleepCtrl;
+
+  switch ( SleepMode )
+  {
+    case MCU_POWER_DOWN:
+      SCB->SCR |= NVIC_LP_SLEEPDEEP;
+      LPC_PMU->PCON = 0x2;
+      break;
+    case MCU_DEEP_SLEEP:
+      SCB->SCR |= NVIC_LP_SLEEPDEEP;
+      LPC_PMU->PCON = 0x1;
+      break;
+    case MCU_SLEEP:
+    default:
+      break;
+  }
+
+  /* Enter the appropriate sleep mode */
+  __WFI();
+
+  return;
+}
diff --git a/reform2-lpc-fw/src/core/pmu/pmu.h b/reform2-lpc-fw/src/core/pmu/pmu.h
new file mode 100644
index 0000000000000000000000000000000000000000..e17bcdc72b2514b3666dbfa82c0a0cc982a559a8
--- /dev/null
+++ b/reform2-lpc-fw/src/core/pmu/pmu.h
@@ -0,0 +1,69 @@
+/**************************************************************************/
+/*!
+    @file     pmu.c
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __PMU_H__
+#define __PMU_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+#define MCU_SLEEP           (0)
+#define MCU_DEEP_SLEEP      (1)
+#define MCU_POWER_DOWN      (2)
+
+#define NVIC_LP_SEVONPEND   (0x10)
+#define NVIC_LP_SLEEPDEEP   (0x04)
+#define NVIC_LP_SLEEPONEXIT (0x02)
+
+#define IRC_OUT_PD          (0x1<<0)
+#define IRC_PD              (0x1<<1)
+#define FLASH_PD            (0x1<<2)
+#define BOD_PD              (0x1<<3)
+#define ADC_PD              (0x1<<4)
+#define SYS_OSC_PD          (0x1<<5)
+#define WDT_OSC_PD          (0x1<<6)
+#define SYS_PLL_PD          (0x1<<7)
+#define USBPLL_PD           (0x1<<8)
+#define USBPAD_PD           (0x1<<10)
+
+void PMU_Sleep( uint32_t SleepMode, uint32_t SleepCtrl );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/core/power_api.h b/reform2-lpc-fw/src/core/power_api.h
new file mode 100644
index 0000000000000000000000000000000000000000..6ded7322ce9b1650e62648f13e41580b99c8ddc9
--- /dev/null
+++ b/reform2-lpc-fw/src/core/power_api.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+ *   $Id:: power_api.h 6249 2011-01-25 19:23:47Z usb01267                   $
+ *   Project: NXP LPC13Uxx software example  
+ *
+ *   Description:
+ *     Power API Header File for NXP LPC13Uxx Device Series 
+ *
+ ****************************************************************************
+ * Software that is described herein is for illustrative purposes only
+ * which provides customers with programming information regarding the
+ * products. This software is supplied "AS IS" without any warranties.
+ * NXP Semiconductors assumes no responsibility or liability for the
+ * use of the software, conveys no license or title under any patent,
+ * copyright, or mask work right to the product. NXP Semiconductors
+ * reserves the right to make changes in the software without
+ * notification. NXP Semiconductors also make no representation or
+ * warranty that such application will be suitable for the specified
+ * use without further testing or modification.
+****************************************************************************/
+#ifndef __LPC13UXX_POWER_API_H__
+#define __LPC13UXX_POWER_API_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif 
+
+#define PWRROMD_PRESENT
+
+#define USBROMD_PRESENT
+
+#ifdef USBROMD_PRESENT
+#include "usb/romdriver/mw_usbd_rom_api.h"
+#endif
+
+typedef	struct _PWRD {
+  void (*set_pll)(unsigned int cmd[], unsigned int resp[]);
+  void (*set_power)(unsigned int cmd[], unsigned int resp[]);
+}  PWRD;
+
+typedef	struct _ROM {
+#ifdef USBROMD_PRESENT
+   const USBD_API_T * pUSBD;
+#else
+   const unsigned p_usbd;
+#endif /* USBROMD_PRESENT */
+   const unsigned p_clib;
+   const unsigned p_cand;
+#ifdef PWRROMD_PRESENT
+   const PWRD * pPWRD;
+#else
+   const unsigned p_pwrd;
+#endif /* PWRROMD_PRESENT */
+   const unsigned p_dev1;
+   const unsigned p_dev2;
+   const unsigned p_dev3;
+   const unsigned p_dev4; 
+}  ROM;
+
+//PLL setup related definitions
+#define	CPU_FREQ_EQU  		0       //main PLL freq must be equal to the specified 
+#define	CPU_FREQ_LTE		1       //main PLL freq must be less than or equal the specified
+#define	CPU_FREQ_GTE		2       //main PLL freq must be greater than or equal the specified
+#define	CPU_FREQ_APPROX		3       //main PLL freq must be as close as possible the specified
+
+#define	PLL_CMD_SUCCESS		0       //PLL setup successfully found
+#define	PLL_INVALID_FREQ	1       //specified freq out of range (either input or output)
+#define	PLL_INVALID_MODE	2       //invalid mode (see above for valid) specified
+#define	PLL_FREQ_NOT_FOUND	3       //specified freq not found under specified conditions
+#define	PLL_NOT_LOCKED		4       //PLL not locked => no changes to the PLL setup
+
+//power setup elated definitions
+#define	PARAM_DEFAULT			0   //default power settings (voltage regulator, flash interface)
+#define	PARAM_CPU_PERFORMANCE	1   //setup for maximum CPU performance (higher current, more computation)
+#define	PARAM_EFFICIENCY		2   //balanced setting (power vs CPU performance)
+#define	PARAM_LOW_CURRENT		3   //lowest active current, lowest CPU performance
+
+#define	PARAM_CMD_SUCCESS		0   //power setting successfully found
+#define	PARAM_INVALID_FREQ		1   //specified freq out of range (=0 or > 50 MHz)
+#define	PARAM_INVALID_MODE		2   //specified mode not valid (see above for valid)
+
+#define MAX_CLOCK_KHZ_PARAM                50000
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* __LPC13UXX_POWER_API_H__ */
+
diff --git a/reform2-lpc-fw/src/core/ssp0/ssp0.c b/reform2-lpc-fw/src/core/ssp0/ssp0.c
new file mode 100644
index 0000000000000000000000000000000000000000..cbd4555fe5bbaac96bc374b8c34340a414b76a49
--- /dev/null
+++ b/reform2-lpc-fw/src/core/ssp0/ssp0.c
@@ -0,0 +1,209 @@
+/**************************************************************************/
+/*!
+    @file     ssp0.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#include "core/gpio/gpio.h"
+#include "core/ssp0/ssp0.h"
+
+/**************************************************************************/
+/*!
+    Set SSP clock to slow (400 KHz)
+*/
+/**************************************************************************/
+void ssp0ClockSlow()
+{
+  /* Divide by 15 for SSPCLKDIV */
+  LPC_SYSCON->SSP0CLKDIV = SCB_CLKDIV_DIV15;
+
+  /* (PCLK / (CPSDVSR * [SCR+1])) = (4,800,000 / (2 x [5 + 1])) = 400 KHz */
+  LPC_SSP0->CR0 = ( (7u << 0)     // Data size = 8-bit  (bits 3:0)
+           | (0 << 4)             // Frame format = SPI (bits 5:4)
+           #if CFG_SSP_CPOL0 == 1
+           | (1  << 6)            // CPOL = 1           (bit 6)
+           #else
+           | (0  << 6)            // CPOL = 0           (bit 6)
+           #endif
+           #if CFG_SSP_CPHA0 == 1
+           | (1 << 7)             // CPHA = 1           (bit 7)
+           #else
+           | (0 << 7)             // CPHA = 0           (bit 7)
+           #endif
+           | SSP0_SCR_5);         // Clock rate = 5     (bits 15:8)
+
+  /* Clock prescale register must be even and at least 2 in master mode */
+  LPC_SSP0->CPSR = 2;
+}
+
+/**************************************************************************/
+/*!
+    Set SSP clock to fast (6.0 MHz)
+*/
+/**************************************************************************/
+void ssp0ClockFast()
+{
+  /* Divide by 1 for SSPCLKDIV */
+  LPC_SYSCON->SSP0CLKDIV = SCB_CLKDIV_DIV1;
+
+  /* (PCLK / (CPSDVSR * [SCR+1])) = (72,000,000 / (2 * [5 + 1])) = 6.0 MHz */
+  LPC_SSP0->CR0 = ( (7u << 0)     // Data size = 8-bit  (bits 3:0)
+           | (0 << 4)             // Frame format = SPI (bits 5:4)
+           #if CFG_SSP_CPOL0 == 1
+           | (1  << 6)            // CPOL = 1           (bit 6)
+           #else
+           | (0  << 6)            // CPOL = 0           (bit 6)
+           #endif
+           #if CFG_SSP_CPHA0 == 1
+           | (1 << 7)             // CPHA = 1           (bit 7)
+           #else
+           | (0 << 7)             // CPHA = 0           (bit 7)
+           #endif
+           | SSP0_SCR_5);         // Clock rate = 5     (bits 15:8)
+
+  /* Clock prescale register must be even and at least 2 in master mode */
+  LPC_SSP0->CPSR = 2;
+}
+
+/**************************************************************************/
+/*!
+    @brief Initialise SSP0
+*/
+/**************************************************************************/
+void ssp0Init(void)
+{
+  uint8_t i, Dummy=Dummy;
+
+  /* Reset SSP */
+  LPC_SYSCON->PRESETCTRL &= ~0x1;
+  LPC_SYSCON->PRESETCTRL |= 0x01;
+
+  /* Enable AHB clock to the SSP domain. */
+  LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 11);
+
+  /* Set P0.8 to SSP MISO0 */
+  LPC_IOCON->PIO0_8 &= ~0x07;
+  LPC_IOCON->PIO0_8 |= 0x01;
+
+  /* Set P0.9 to SSP MOSI0 */
+  LPC_IOCON->PIO0_9 &= ~0x07;
+  LPC_IOCON->PIO0_9 |= 0x01;
+
+  /* No LPC_IOCON->SCKLOC register on LPC11Uxx/13Uxx? */
+  #if (CFG_SSP_SCK0_LOCATION == CFG_SSP_SCK0_1_29)
+    /* Set 1.29 to SSP SCK0 (0.6 is often used by USB and 0.10 for SWD) */
+    LPC_IOCON->PIO1_29 = 0x01;
+  #elif (CFG_SSP_SCK0_LOCATION == CFG_SSP_SCK0_0_10)
+    /* Set 0.10 to SSP SCK0 (may be required for SWD!) */
+    LPC_IOCON->SWCLK_PIO0_10 = 0x02;
+  #elif (CFG_SSP_SCK0_LOCATION == CFG_SSP_SCK0_0_6)
+    /* Set 0.6 to SSP SCK0 (may be required for USB!) */
+    LPC_IOCON->PIO0_6 = 0x02;
+  #else
+    #error "Invalid CFG_SSP_SCK0_LOCATION"
+  #endif
+
+  /* Set SPI clock to high-speed by default */
+  ssp0ClockFast();
+
+  /* Clear the Rx FIFO */
+  for ( i = 0; i < SSP0_FIFOSIZE; i++ )
+  {
+    Dummy = LPC_SSP0->DR;
+  }  
+  
+  /* Enable device and set it to master mode, no loopback */
+  LPC_SSP0->CR1 = SSP0_CR1_SSE_ENABLED | SSP0_CR1_MS_MASTER | SSP0_CR1_LBM_NORMAL;
+}
+
+/**************************************************************************/
+/*!
+    @brief Sends a block of data using SSP0
+
+    @param[in]  buf
+                Pointer to the data buffer
+    @param[in]  length
+                Block length of the data buffer
+*/
+/**************************************************************************/
+void ssp0Send (uint8_t *buf, uint32_t length)
+{
+  uint32_t i;
+  uint8_t Dummy = Dummy;
+
+  for (i = 0; i < length; i++)
+  {
+    /* Move on only if NOT busy and TX FIFO not full. */
+    while ((LPC_SSP0->SR & (SSP0_SR_TNF_NOTFULL | SSP0_SR_BSY_BUSY)) != SSP0_SR_TNF_NOTFULL);
+    LPC_SSP0->DR = *buf;
+    buf++;
+
+    while ( (LPC_SSP0->SR & (SSP0_SR_BSY_BUSY|SSP0_SR_RNE_NOTEMPTY)) != SSP0_SR_RNE_NOTEMPTY );
+    /* Whenever a byte is written, MISO FIFO counter increments, Clear FIFO
+    on MISO. Otherwise, when sspReceive is called, previous data byte
+    is left in the FIFO. */
+    Dummy = LPC_SSP0->DR;
+  }
+
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Receives a block of data using SSP0
+
+    @param[in]  buf
+                Pointer to the data buffer
+    @param[in]  length
+                Block length of the data buffer
+*/
+/**************************************************************************/
+void ssp0Receive(uint8_t *buf, uint32_t length)
+{
+  uint32_t i;
+
+  for ( i = 0; i < length; i++ )
+  {
+    /* As long as the receive FIFO is not empty, data can be received. */
+    LPC_SSP0->DR = 0xFF;
+
+    /* Wait until the Busy bit is cleared */
+    while ( (LPC_SSP0->SR & (SSP0_SR_BSY_BUSY|SSP0_SR_RNE_NOTEMPTY)) != SSP0_SR_RNE_NOTEMPTY );
+
+    *buf = LPC_SSP0->DR;
+    buf++;
+  }
+
+  return;
+}
diff --git a/reform2-lpc-fw/src/core/ssp0/ssp0.h b/reform2-lpc-fw/src/core/ssp0/ssp0.h
new file mode 100644
index 0000000000000000000000000000000000000000..955e87d67ad7ed74285f03afd35ed7f469e2c0bd
--- /dev/null
+++ b/reform2-lpc-fw/src/core/ssp0/ssp0.h
@@ -0,0 +1,116 @@
+/**************************************************************************/
+/*!
+    @file     ssp0.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __SSP0_H__
+#define __SSP0_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SSP0_FIFOSIZE            8       /* SPI read and write buffer size */
+
+/* SSP Clock div (0..255) */
+#define SCB_CLKDIV_DISABLE (0x00000000)
+#define SCB_CLKDIV_DIV1    (0x00000001)
+#define SCB_CLKDIV_DIV2    (0x00000002)
+#define SCB_CLKDIV_DIV3    (0x00000003)
+#define SCB_CLKDIV_DIV4    (0x00000004)
+#define SCB_CLKDIV_DIV6    (0x00000006)
+#define SCB_CLKDIV_DIV10   (0x0000000A)
+#define SCB_CLKDIV_DIV12   (0x0000000C)
+#define SCB_CLKDIV_DIV15   (0x0000000F)
+#define SCB_CLKDIV_DIV20   (0x00000014)
+#define SCB_CLKDIV_DIV40   (0x00000028)
+#define SCB_CLKDIV_MASK    (0x000000FF)
+
+/* SSP Serial Clock Rate Values */
+#define SSP0_SCR_1          (0x00000100)
+#define SSP0_SCR_2          (0x00000200)
+#define SSP0_SCR_3          (0x00000300)
+#define SSP0_SCR_4          (0x00000400)
+#define SSP0_SCR_5          (0x00000500)
+#define SSP0_SCR_6          (0x00000600)
+#define SSP0_SCR_7          (0x00000700)
+#define SSP0_SCR_8          (0x00000800)
+#define SSP0_SCR_9          (0x00000900)
+#define SSP0_SCR_10         (0x00000A00)
+#define SSP0_SCR_11         (0x00000B00)
+#define SSP0_SCR_12         (0x00000C00)
+#define SSP0_SCR_13         (0x00000D00)
+#define SSP0_SCR_14         (0x00000E00)
+#define SSP0_SCR_15         (0x00000F00)
+#define SSP0_SCR_16         (0x00001000)
+
+/*  Current status of the SSP controller.  */
+#define SSP0_SR_TFE_MASK      (0x00000001) // Transmit FIFO empty
+#define SSP0_SR_TFE_EMPTY     (0x00000001)
+#define SSP0_SR_TFE_NOTEMPTY  (0x00000000)
+#define SSP0_SR_TNF_MASK      (0x00000002) // Transmit FIFO not full
+#define SSP0_SR_TNF_NOTFULL   (0x00000002)
+#define SSP0_SR_TNF_FULL      (0x00000000)
+#define SSP0_SR_RNE_MASK      (0x00000004) // Receive FIFO not empty
+#define SSP0_SR_RNE_NOTEMPTY  (0x00000004)
+#define SSP0_SR_RNE_EMPTY     (0x00000000)
+#define SSP0_SR_RFF_MASK      (0x00000008) // Receive FIFO full
+#define SSP0_SR_RFF_FULL      (0x00000008)
+#define SSP0_SR_RFF_NOTFULL   (0x00000000)
+#define SSP0_SR_BSY_MASK      (0x00000010) // Busy Flag
+#define SSP0_SR_BSY_IDLE      (0x00000000)
+#define SSP0_SR_BSY_BUSY      (0x00000010)
+
+/* Control Register 1 */
+#define SSP0_CR1_LBM_MASK     (0x00000001) // Loop back mode
+#define SSP0_CR1_LBM_NORMAL   (0x00000000)
+#define SSP0_CR1_LBM_INVERTED (0x00000001) // MISO/MOSI are reversed
+#define SSP0_CR1_SSE_MASK     (0x00000002) // SSP enable
+#define SSP0_CR1_SSE_DISABLED (0x00000000)
+#define SSP0_CR1_SSE_ENABLED  (0x00000002)
+#define SSP0_CR1_MS_MASK      (0x00000004) // Master/Slave Mode
+#define SSP0_CR1_MS_MASTER    (0x00000000)
+#define SSP0_CR1_MS_SLAVE     (0x00000004)
+#define SSP0_CR1_SOD_MASK     (0x00000008) // Slave output disable
+
+void ssp0ClockSlow(void);
+void ssp0ClockFast(void);
+void ssp0Init(void);
+void ssp0Send(uint8_t *buf, uint32_t length);
+void ssp0Receive(uint8_t *buf, uint32_t length);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/core/ssp1/ssp1.c b/reform2-lpc-fw/src/core/ssp1/ssp1.c
new file mode 100644
index 0000000000000000000000000000000000000000..5bb592c525ad1c1d23ebc4724b3c0704f0757bd1
--- /dev/null
+++ b/reform2-lpc-fw/src/core/ssp1/ssp1.c
@@ -0,0 +1,218 @@
+/**************************************************************************/
+/*!
+    @file     ssp1.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#include "core/gpio/gpio.h"
+#include "core/ssp1/ssp1.h"
+
+/**************************************************************************/
+/*!
+    Set SSP clock to slow (400 KHz)
+*/
+/**************************************************************************/
+void ssp1ClockSlow()
+{
+  /* Divide by 15 for SSPCLKDIV */
+  LPC_SYSCON->SSP1CLKDIV = SCB_CLKDIV_DIV15;
+
+  /* (PCLK / (CPSDVSR * [SCR+1])) = (4,800,000 / (2 x [5 + 1])) = 400 KHz */
+  LPC_SSP1->CR0 = ( (7u << 0)     // Data size = 8-bit  (bits 3:0)
+           | (0 << 4)             // Frame format = SPI (bits 5:4)
+           #if CFG_SSP_CPOL1 == 1
+           | (1  << 6)            // CPOL = 1           (bit 6)
+           #else
+           | (0  << 6)            // CPOL = 0           (bit 6)
+           #endif
+           #if CFG_SSP_CPHA1 == 1
+           | (1 << 7)             // CPHA = 1           (bit 7)
+           #else
+           | (0 << 7)             // CPHA = 0           (bit 7)
+           #endif
+           | SSP1_SCR_5);         // Clock rate = 5     (bits 15:8)
+
+  /* Clock prescale register must be even and at least 2 in master mode */
+  LPC_SSP1->CPSR = 2;
+}
+
+/**************************************************************************/
+/*!
+    Set SSP clock to fast (6.0 MHz)
+*/
+/**************************************************************************/
+void ssp1ClockFast()
+{
+  /* Divide by 1 for SSPCLKDIV */
+  LPC_SYSCON->SSP1CLKDIV = SCB_CLKDIV_DIV1;
+
+  /* (PCLK / (CPSDVSR * [SCR+1])) = (72,000,000 / (2 * [5 + 1])) = 6.0 MHz */
+  LPC_SSP1->CR0 = ( (7u << 0)     // Data size = 8-bit  (bits 3:0)
+           | (0 << 4)             // Frame format = SPI (bits 5:4)
+           #if CFG_SSP_CPOL1 == 1
+           | (1  << 6)            // CPOL = 1           (bit 6)
+           #else
+           | (0  << 6)            // CPOL = 0           (bit 6)
+           #endif
+           #if CFG_SSP_CPHA1 == 1
+           | (1 << 7)             // CPHA = 1           (bit 7)
+           #else
+           | (0 << 7)             // CPHA = 0           (bit 7)
+           #endif
+           | SSP1_SCR_5);         // Clock rate = 5     (bits 15:8)
+
+  /* Clock prescale register must be even and at least 2 in master mode */
+  LPC_SSP1->CPSR = 2;
+}
+
+/**************************************************************************/
+/*!
+    @brief Initialise SSP1
+*/
+/**************************************************************************/
+void ssp1Init(void)
+{
+  uint8_t i, Dummy=Dummy;
+
+  /* Reset SSP */
+  LPC_SYSCON->PRESETCTRL |= (0x1<<2);
+
+  /* Enable AHB clock to the SSP domain. */
+  LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 18);
+
+  #if CFG_SSP_MOSI1_LOCATION == CFG_SSP_MOSI1_0_21
+    /* Set P0.21 to SSP MOSI1 */
+    LPC_IOCON->PIO0_21 &= ~0x07;
+    LPC_IOCON->PIO0_21 |= 0x02;
+  #elif CFG_SSP_MOSI1_LOCATION == CFG_SSP_MOSI1_1_22
+    /* Set P1.22 to SSP MOSI1 */
+    LPC_IOCON->PIO1_22 &= ~0x07;
+    LPC_IOCON->PIO1_22 |= 0x02;
+  #endif
+
+  #if CFG_SSP_MISO1_LOCATION == CFG_SSP_MISO1_0_22
+    /* Set P0.22 to SSP MISO1 */
+    LPC_IOCON->PIO0_22 &= ~0x07;
+    LPC_IOCON->PIO0_22 |= (0x03); // | (0<<3) | (1<<7);   // MISO1, No pull-up/down, ADMODE = digital
+  #elif CFG_SSP_MISO1_LOCATION == CFG_SSP_MISO1_1_21
+    /* Set P1.21 to SSP MISO1 */
+    LPC_IOCON->PIO1_21 &= ~0x07;
+    LPC_IOCON->PIO1_21 |= 0x02;
+  #endif
+
+  #if CFG_SSP_SCK1_LOCATION == CFG_SSP_SCK1_1_20
+    /* Set 1.20 to SSP SCK1 */
+    LPC_IOCON->PIO1_20 &= ~0x07;
+    LPC_IOCON->PIO1_20 |= 0x02;
+  #elif CFG_SSP_SCK1_LOCATION == CFG_SSP_SCK1_1_15
+    /* Set 1.15 to SSP SCK1 */
+    LPC_IOCON->PIO1_15 &= ~0x07;
+    LPC_IOCON->PIO1_15 |= 0x03;
+  #else
+    #error "Invalid CFG_SSP_SCK0_LOCATION"
+  #endif
+
+  /* Set SPI clock to high-speed by default */
+  ssp1ClockFast();
+
+  /* Clear the Rx FIFO */
+  for ( i = 0; i < SSP1_FIFOSIZE; i++ )
+  {
+    Dummy = LPC_SSP1->DR;
+  }
+
+  /* Enable device and set it to master mode, no loopback */
+  LPC_SSP1->CR1 = SSP1_CR1_SSE_ENABLED | SSP1_CR1_MS_MASTER | SSP1_CR1_LBM_NORMAL;
+}
+
+/**************************************************************************/
+/*!
+    @brief Sends a block of data using SSP1
+
+    @param[in]  buf
+                Pointer to the data buffer
+    @param[in]  length
+                Block length of the data buffer
+*/
+/**************************************************************************/
+void ssp1Send (uint8_t *buf, uint32_t length)
+{
+  uint32_t i;
+  uint8_t Dummy = Dummy;
+
+  for (i = 0; i < length; i++)
+  {
+    /* Move on only if NOT busy and TX FIFO not full. */
+    while ((LPC_SSP1->SR & (SSP1_SR_TNF_NOTFULL | SSP1_SR_BSY_BUSY)) != SSP1_SR_TNF_NOTFULL);
+    LPC_SSP1->DR = *buf;
+    buf++;
+
+    while ( (LPC_SSP1->SR & (SSP1_SR_BSY_BUSY|SSP1_SR_RNE_NOTEMPTY)) != SSP1_SR_RNE_NOTEMPTY );
+    /* Whenever a byte is written, MISO FIFO counter increments, Clear FIFO
+    on MISO. Otherwise, when sspReceive is called, previous data byte
+    is left in the FIFO. */
+    Dummy = LPC_SSP1->DR;
+  }
+
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Receives a block of data using SSP1
+
+    @param[in]  buf
+                Pointer to the data buffer
+    @param[in]  length
+                Block length of the data buffer
+*/
+/**************************************************************************/
+void ssp1Receive(uint8_t *buf, uint32_t length)
+{
+  uint32_t i;
+
+  for ( i = 0; i < length; i++ )
+  {
+    /* As long as the receive FIFO is not empty, data can be received. */
+    LPC_SSP1->DR = 0xFF;
+
+    /* Wait until the Busy bit is cleared */
+    while ( (LPC_SSP1->SR & (SSP1_SR_BSY_BUSY|SSP1_SR_RNE_NOTEMPTY)) != SSP1_SR_RNE_NOTEMPTY );
+
+    *buf = LPC_SSP1->DR;
+    buf++;
+  }
+
+  return;
+}
diff --git a/reform2-lpc-fw/src/core/ssp1/ssp1.h b/reform2-lpc-fw/src/core/ssp1/ssp1.h
new file mode 100644
index 0000000000000000000000000000000000000000..5dcf11c5536d712f11af66d600c7d39da21c336c
--- /dev/null
+++ b/reform2-lpc-fw/src/core/ssp1/ssp1.h
@@ -0,0 +1,116 @@
+/**************************************************************************/
+/*!
+    @file     ssp1.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __SSP1_H__
+#define __SSP1_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SSP1_FIFOSIZE            8       /* SPI read and write buffer size */
+
+/* SSP Clock div (0..255) */
+#define SCB_CLKDIV_DISABLE (0x00000000)
+#define SCB_CLKDIV_DIV1    (0x00000001)
+#define SCB_CLKDIV_DIV2    (0x00000002)
+#define SCB_CLKDIV_DIV3    (0x00000003)
+#define SCB_CLKDIV_DIV4    (0x00000004)
+#define SCB_CLKDIV_DIV6    (0x00000006)
+#define SCB_CLKDIV_DIV10   (0x0000000A)
+#define SCB_CLKDIV_DIV12   (0x0000000C)
+#define SCB_CLKDIV_DIV15   (0x0000000F)
+#define SCB_CLKDIV_DIV20   (0x00000014)
+#define SCB_CLKDIV_DIV40   (0x00000028)
+#define SCB_CLKDIV_MASK    (0x000000FF)
+
+/* SSP Serial Clock Rate Values */
+#define SSP1_SCR_1          (0x00000100)
+#define SSP1_SCR_2          (0x00000200)
+#define SSP1_SCR_3          (0x00000300)
+#define SSP1_SCR_4          (0x00000400)
+#define SSP1_SCR_5          (0x00000500)
+#define SSP1_SCR_6          (0x00000600)
+#define SSP1_SCR_7          (0x00000700)
+#define SSP1_SCR_8          (0x00000800)
+#define SSP1_SCR_9          (0x00000900)
+#define SSP1_SCR_10         (0x00000A00)
+#define SSP1_SCR_11         (0x00000B00)
+#define SSP1_SCR_12         (0x00000C00)
+#define SSP1_SCR_13         (0x00000D00)
+#define SSP1_SCR_14         (0x00000E00)
+#define SSP1_SCR_15         (0x00000F00)
+#define SSP1_SCR_16         (0x00001000)
+
+/*  Current status of the SSP controller.  */
+#define SSP1_SR_TFE_MASK      (0x00000001) // Transmit FIFO empty
+#define SSP1_SR_TFE_EMPTY     (0x00000001)
+#define SSP1_SR_TFE_NOTEMPTY  (0x00000000)
+#define SSP1_SR_TNF_MASK      (0x00000002) // Transmit FIFO not full
+#define SSP1_SR_TNF_NOTFULL   (0x00000002)
+#define SSP1_SR_TNF_FULL      (0x00000000)
+#define SSP1_SR_RNE_MASK      (0x00000004) // Receive FIFO not empty
+#define SSP1_SR_RNE_NOTEMPTY  (0x00000004)
+#define SSP1_SR_RNE_EMPTY     (0x00000000)
+#define SSP1_SR_RFF_MASK      (0x00000008) // Receive FIFO full
+#define SSP1_SR_RFF_FULL      (0x00000008)
+#define SSP1_SR_RFF_NOTFULL   (0x00000000)
+#define SSP1_SR_BSY_MASK      (0x00000010) // Busy Flag
+#define SSP1_SR_BSY_IDLE      (0x00000000)
+#define SSP1_SR_BSY_BUSY      (0x00000010)
+
+/* Control Register 1 */
+#define SSP1_CR1_LBM_MASK     (0x00000001) // Loop back mode
+#define SSP1_CR1_LBM_NORMAL   (0x00000000)
+#define SSP1_CR1_LBM_INVERTED (0x00000001) // MISO/MOSI are reversed
+#define SSP1_CR1_SSE_MASK     (0x00000002) // SSP enable
+#define SSP1_CR1_SSE_DISABLED (0x00000000)
+#define SSP1_CR1_SSE_ENABLED  (0x00000002)
+#define SSP1_CR1_MS_MASK      (0x00000004) // Master/Slave Mode
+#define SSP1_CR1_MS_MASTER    (0x00000000)
+#define SSP1_CR1_MS_SLAVE     (0x00000004)
+#define SSP1_CR1_SOD_MASK     (0x00000008) // Slave output disable
+
+void ssp1ClockSlow(void);
+void ssp1ClockFast(void);
+void ssp1Init(void);
+void ssp1Send(uint8_t *buf, uint32_t length);
+void ssp1Receive(uint8_t *buf, uint32_t length);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/core/timer16/timer16.c b/reform2-lpc-fw/src/core/timer16/timer16.c
new file mode 100644
index 0000000000000000000000000000000000000000..b39cd88bb5ebb4dd10bb791db912964be6ae18cf
--- /dev/null
+++ b/reform2-lpc-fw/src/core/timer16/timer16.c
@@ -0,0 +1,426 @@
+/**************************************************************************/
+/*!
+    @file     timer16.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "timer16.h"
+
+volatile uint32_t timer16_0_counter[4] = {0,0,0,0};
+volatile uint32_t timer16_1_counter[4] = {0,0,0,0};
+volatile uint32_t timer16_0_capture[4] = {0,0,0,0};
+volatile uint32_t timer16_1_capture[4] = {0,0,0,0};
+
+// NOTE: 16-bit Timer 0 is used by src/core/delay/delay.c
+// NOTE: 16-bit Timer 1 is used by src/drivers/sensors/sensorpoll.c
+
+///**************************************************************************/
+///*!
+//    @brief Interrupt handler for 16-bit timer 0
+//*/
+///**************************************************************************/
+//#if defined CFG_MCU_FAMILY_LPC11UXX
+//void TIMER16_0_IRQHandler(void)
+//#elif defined CFG_MCU_FAMILY_LPC13UXX
+//void CT16B0_IRQHandler(void)
+//#else
+//  #error "timer16.c: No MCU defined"
+//#endif
+//{
+//  /* Handle match events */
+//  if (LPC_CT16B0->IR & (0x01 << 0))
+//  {
+//    LPC_CT16B0->IR = 0x1 << 0;
+//    timer16_0_counter[0]++;
+//  }
+//  if (LPC_CT16B0->IR & (0x01 << 1))
+//  {
+//    LPC_CT16B0->IR = 0x1 << 1;
+//    timer16_0_counter[1]++;
+//  }
+//  if (LPC_CT16B0->IR & (0x01 << 2))
+//  {
+//    LPC_CT16B0->IR = 0x1 << 2;
+//    timer16_0_counter[2]++;
+//  }
+//  if (LPC_CT16B0->IR & (0x01 << 3))
+//  {
+//    LPC_CT16B0->IR = 0x1 << 3;
+//    timer16_0_counter[3]++;
+//  }
+//
+//  /* Handle capture events */
+//  if (LPC_CT16B0->IR & (0x1 << 4))
+//  {
+//    LPC_CT16B0->IR = 0x1 << 4;
+//    timer16_0_capture[0]++;
+//  }
+//  if (LPC_CT16B0->IR & (0x1 << 5))
+//  {
+//    LPC_CT16B0->IR = 0x1 << 5;
+//    timer16_0_capture[1]++;
+//  }
+//  if (LPC_CT16B0->IR & (0x1 << 6))
+//  {
+//    LPC_CT16B0->IR = 0x1 << 6;
+//    timer16_0_capture[2]++;
+//  }
+//  if (LPC_CT16B0->IR & (0x1 << 7))
+//  {
+//    LPC_CT16B0->IR = 0x1 << 7;
+//    timer16_0_capture[3]++;
+//  }
+//
+//  return;
+//}
+
+///**************************************************************************/
+///*!
+//    @brief Interrupt handler for 16-bit timer 1
+//*/
+///**************************************************************************/
+//#if defined CFG_MCU_FAMILY_LPC11UXX
+//void TIMER16_1_IRQHandler(void)
+//#elif defined CFG_MCU_FAMILY_LPC13UXX
+//void CT16B1_IRQHandler(void)
+//#else
+//  #error "timer16.c: No MCU defined"
+//#endif
+//{
+//  /* Handle match events */
+//  if (LPC_CT16B1->IR & (0x01 << 0))
+//  {
+//    LPC_CT16B1->IR = 0x1 << 0;
+//    timer16_1_counter[0]++;
+//  }
+//  if (LPC_CT16B1->IR & (0x01 << 1))
+//  {
+//    LPC_CT16B1->IR = 0x1 << 1;
+//    timer16_1_counter[1]++;
+//  }
+//  if (LPC_CT16B1->IR & (0x01 << 2))
+//  {
+//    LPC_CT16B1->IR = 0x1 << 2;
+//    timer16_1_counter[2]++;
+//  }
+//  if (LPC_CT16B1->IR & (0x01 << 3))
+//  {
+//    LPC_CT16B1->IR = 0x1 << 3;
+//    timer16_1_counter[3]++;
+//  }
+//
+//  /* Handle capture events */
+//  if (LPC_CT16B1->IR & (0x1 << 4))
+//  {
+//    LPC_CT16B1->IR = 0x1 << 4;
+//    timer16_1_capture[0]++;
+//  }
+//  if (LPC_CT16B1->IR & (0x1 << 5))
+//  {
+//    LPC_CT16B1->IR = 0x1 << 5;
+//    timer16_1_capture[1]++;
+//  }
+//  if (LPC_CT16B1->IR & (0x1 << 6))
+//  {
+//    LPC_CT16B1->IR = 0x1 << 6;
+//    timer16_1_capture[2]++;
+//  }
+//  if (LPC_CT16B1->IR & (0x1 << 7))
+//  {
+//    LPC_CT16B1->IR = 0x1 << 7;
+//    timer16_1_capture[3]++;
+//  }
+//
+//  return;
+//}
+
+/**************************************************************************/
+/*!
+    @brief Initialises the specified 16-bit timer
+
+    @param[in]  timer
+                The 16-bit timer to use (must be 0 or 1)
+*/
+/**************************************************************************/
+void timer16Init(uint8_t timer)
+{
+  uint32_t i;
+
+  if ( timer == 0 )
+  {
+    LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 7);
+    for ( i = 0; i < 4; i++ )
+    {
+      timer16_0_counter[i] = 0;
+      timer16_0_capture[i] = 0;
+    }
+    #if defined CFG_MCU_FAMILY_LPC11UXX
+    NVIC_EnableIRQ(TIMER_16_0_IRQn);
+    #elif defined CFG_MCU_FAMILY_LPC13UXX
+    NVIC_EnableIRQ(CT16B0_IRQn);
+    #endif
+  }
+  else if ( timer == 1 )
+  {
+    LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 8);
+    for ( i = 0; i < 4; i++ )
+    {
+      timer16_1_counter[i] = 0;
+      timer16_1_capture[i] = 0;
+    }
+    #if defined CFG_MCU_FAMILY_LPC11UXX
+    NVIC_EnableIRQ(TIMER_16_1_IRQn);
+    #elif defined CFG_MCU_FAMILY_LPC13UXX
+    NVIC_EnableIRQ(CT16B1_IRQn);
+    #endif
+  }
+
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Enables the specified 16-bit timer
+
+    @param[in]  timer
+                The 16-bit timer to use (must be 0 or 1)
+*/
+/**************************************************************************/
+void timer16Enable(uint8_t timer)
+{
+  if ( timer == 0 )
+  {
+    LPC_CT16B0->TCR = 1;
+  }
+  else if (timer == 1)
+  {
+    LPC_CT16B1->TCR = 1;
+  }
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Disables the specified 16-bit timer
+
+    @param[in]  timer
+                The 16-bit timer to use (must be 0 or 1)
+*/
+/**************************************************************************/
+void timer16Disable(uint8_t timer)
+{
+  if ( timer == 0 )
+  {
+    LPC_CT16B0->TCR = 0;
+  }
+  else if (timer == 1)
+  {
+    LPC_CT16B1->TCR = 0;
+  }
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Resets the specified 16-bit timer
+
+    @param[in]  timer
+                The 16-bit timer to use (must be 0 or 1)
+*/
+/**************************************************************************/
+void timer16Reset(uint8_t timer)
+{
+  uint32_t regVal;
+
+  if ( timer == 0 )
+  {
+    regVal = LPC_CT16B0->TCR;
+    regVal |= 0x02;
+    LPC_CT16B0->TCR = regVal;
+  }
+  else if (timer == 1)
+  {
+    regVal = LPC_CT16B1->TCR;
+    regVal |= 0x02;
+    LPC_CT16B1->TCR = regVal;
+  }
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Causes a blocking delay on the specified 16-bit timer
+
+    @param[in]  timer
+                The 16-bit timer to use (must be 0 or 1)
+    @param[in]  delayInTicks
+                The number of clock cycles ('ticks') to wait
+*/
+/**************************************************************************/
+void timer16DelayTicks(uint8_t timer, uint16_t delayInTicks)
+{
+  if (timer == 0)
+  {
+    LPC_CT16B0->TCR  = 0x02;            /* Reset the timer */
+    LPC_CT16B0->PR   = 0x00;            /* Set prescaler to zero */
+    LPC_CT16B0->PWMC = 0x00;            /* Disable PWM mode */
+    LPC_CT16B0->MR0  = delayInTicks;
+    LPC_CT16B0->IR   = 0xff;            /* Reset all interrrupts */
+    LPC_CT16B0->MCR  = 0x04;            /* Stop the timer on match */
+    LPC_CT16B0->TCR  = 0x01;            /* Start timer */
+
+    /* Wait until delay time has elapsed */
+    while (LPC_CT16B0->TCR & 0x01);
+  }
+  else if (timer == 1)
+  {
+    LPC_CT16B1->TCR  = 0x02;            /* Reset the timer */
+    LPC_CT16B1->PR   = 0x00;            /* Set prescaler to zero */
+    LPC_CT16B1->PWMC = 0x00;            /* Disable PWM mode */
+    LPC_CT16B1->MR0  = delayInTicks;
+    LPC_CT16B1->IR   = 0xff;            /* Reset all interrrupts */
+    LPC_CT16B1->MCR  = 0x04;            /* Stop the timer on match */
+    LPC_CT16B1->TCR  = 0x01;            /* Start timer */
+
+    /* Wait until delay time has elapsed */
+    while (LPC_CT16B1->TCR & 0x01);
+  }
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Configures the match register for the specified 16-bit timer
+
+    @param[in]  timer
+                The 16-bit timer to use (must be 0 or 1)
+    @param[in]  matchNum
+                The match register to set (must be 0..3)
+    @param[in]  value
+                The value to assign to the specified match register
+
+    @code
+    // Set MAT1 on timer 0 to 12000 ticks
+    timer16SetMatch(0, 1, 12000);
+    @endcode
+*/
+/**************************************************************************/
+void timer16SetMatch(uint8_t timer, uint8_t matchNum, uint16_t value)
+{
+  if (timer)
+  {
+    switch (matchNum)
+    {
+      case 0:
+        LPC_CT16B1->MR0 = value;
+        break;
+      case 1:
+        LPC_CT16B1->MR1 = value;
+        break;
+      case 2:
+        LPC_CT16B1->MR2 = value;
+        break;
+      case 3:
+        LPC_CT16B1->MR3 = value;
+        break;
+      default:
+        break;
+    }
+  }
+  else
+  {
+    switch (matchNum)
+    {
+      case 0:
+        LPC_CT16B0->MR0 = value;
+        break;
+      case 1:
+        LPC_CT16B0->MR1 = value;
+        break;
+      case 2:
+        LPC_CT16B0->MR2 = value;
+        break;
+      case 3:
+        LPC_CT16B0->MR3 = value;
+        break;
+      default:
+        break;
+    }
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Configures 16-bit Timer 1 for PWM output using MR0 to control
+            the period, and MR1, MR2 and MR3 for duty cycle.  Duty cycle
+            can be adjusted via timer16SetMatch.
+
+    @param[in]  period
+                The period in timer clock ticks
+
+    @code
+    // Setup PWM with 12,000 cycle period (MAT0 used for period)
+    timer16SetPWM1(12000);
+
+    // PWM Match Settings
+    timer16SetMatch(1, 1, 12000); // MAT1 will go high on last cycle
+    timer16SetMatch(1, 2, 8000);  // MAT2 will go high for final 1/3
+    timer16SetMatch(1, 3, 4000);  // MAT3 will go high for final 2/3
+
+    // Enable to PWM output
+    timer16Enable(1);
+    @endcode
+*/
+/**************************************************************************/
+void timer16SetPWM1(uint16_t period)
+{
+  timer16Disable(1);
+
+  /* Make sure 16-bit timer 1 is enabled */
+  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<8);
+
+  /* Setup the external match register (clear on match) */
+  LPC_CT16B1->EMR =  (1<<10) | (1<<8) | (1<<6) | (1<<4) |
+                     (1<<0)  | (1<<1) | (1<<2) | (1<<3);
+
+  /* Set MAT0..3 to PWM mode via the PWM Control register */
+  LPC_CT16B1->PWMC = (1<<0)  | (1<<1) | (1<<2) | (1<<3);
+
+  /* MAT0 controls period, set MAT1..3 to 50% duty cycle to start */
+  timer16SetMatch(1, 0, period);
+  timer16SetMatch(1, 1, period / 2);
+  timer16SetMatch(1, 2, period / 2);
+  timer16SetMatch(1, 3, period / 2);
+
+  /* Reset on MR0 */
+  LPC_CT16B1->MCR = 1 << 1;
+}
diff --git a/reform2-lpc-fw/src/core/timer16/timer16.h b/reform2-lpc-fw/src/core/timer16/timer16.h
new file mode 100644
index 0000000000000000000000000000000000000000..227fb6e755fad8313fba5c2effc2eb30eebd44b5
--- /dev/null
+++ b/reform2-lpc-fw/src/core/timer16/timer16.h
@@ -0,0 +1,57 @@
+/**************************************************************************/
+/*!
+    @file     timer16.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _TIMER16_H_
+#define _TIMER16_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+void timer16Init       ( uint8_t timer );
+void timer16Enable     ( uint8_t timer );
+void timer16Disable    ( uint8_t timer );
+void timer16Reset      ( uint8_t timer );
+void timer16DelayTicks ( uint8_t timer, uint16_t delayInTicks );
+void timer16SetMatch   ( uint8_t timer, uint8_t matchNum, uint16_t value );
+void timer16SetPWM1    ( uint16_t period );
+
+#ifdef __cplusplus0
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/core/timer32/timer32.c b/reform2-lpc-fw/src/core/timer32/timer32.c
new file mode 100644
index 0000000000000000000000000000000000000000..525f561ecf6a26d39849f6899e6a884c0f4d0c7c
--- /dev/null
+++ b/reform2-lpc-fw/src/core/timer32/timer32.c
@@ -0,0 +1,449 @@
+/**************************************************************************/
+/*!
+    @file     timer32.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_ENABLE_TIMER32
+
+#include "timer32.h"
+
+/**************************************************************************/
+/*!
+    @brief Interrupt handler for 32-bit timer 0
+*/
+/**************************************************************************/
+#if defined CFG_MCU_FAMILY_LPC11UXX
+void TIMER32_0_IRQHandler(void)
+#elif defined CFG_MCU_FAMILY_LPC13UXX
+void CT32B0_IRQHandler(void)
+#else
+  #error "timer32.c: No MCU defined"
+#endif
+{
+  /* Handle match events */
+  if (LPC_CT32B0->IR & (0x01 << 0))
+  {
+    LPC_CT32B0->IR = 0x1 << 0;
+  }
+  if (LPC_CT32B0->IR & (0x01 << 1))
+  {
+    LPC_CT32B0->IR = 0x1 << 1;
+  }
+  if (LPC_CT32B0->IR & (0x01 << 2))
+  {
+    LPC_CT32B0->IR = 0x1 << 2;
+  }
+  if (LPC_CT32B0->IR & (0x01 << 3))
+  {
+    LPC_CT32B0->IR = 0x1 << 3;
+  }
+
+  /* Handle capture events */
+  if (LPC_CT32B0->IR & (0x1 << 4))
+  {
+    LPC_CT32B0->IR = 0x1 << 4;
+  }
+  if (LPC_CT32B0->IR & (0x1 << 5))
+  {
+    LPC_CT32B0->IR = 0x1 << 5;
+  }
+  if (LPC_CT32B0->IR & (0x1 << 6))
+  {
+    LPC_CT32B0->IR = 0x1 << 6;
+  }
+  if (LPC_CT32B0->IR & (0x1 << 7))
+  {
+    LPC_CT32B0->IR = 0x1 << 7;
+  }
+
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Interrupt handler for 32-bit timer 1
+*/
+/**************************************************************************/
+#if defined CFG_MCU_FAMILY_LPC11UXX
+void TIMER32_1_IRQHandler(void)
+#elif defined CFG_MCU_FAMILY_LPC13UXX
+void CT32B1_IRQHandler(void)
+#else
+  #error "timer32.c: No MCU defined"
+#endif
+{
+  /* Handle match events */
+  if (LPC_CT32B1->IR & (0x01 << 0))
+  {
+    LPC_CT32B1->IR = 0x1 << 0;
+  }
+  if (LPC_CT32B1->IR & (0x01 << 1))
+  {
+    LPC_CT32B1->IR = 0x1 << 1;
+  }
+  if (LPC_CT32B1->IR & (0x01 << 2))
+  {
+    LPC_CT32B1->IR = 0x1 << 2;
+  }
+  if (LPC_CT32B1->IR & (0x01 << 3))
+  {
+    LPC_CT32B1->IR = 0x1 << 3;
+  }
+
+  /* Handle capture events */
+  if (LPC_CT32B1->IR & (0x1 << 4))
+  {
+    LPC_CT32B1->IR = 0x1 << 4;
+  }
+  if (LPC_CT32B1->IR & (0x1 << 5))
+  {
+    LPC_CT32B1->IR = 0x1 << 5;
+  }
+  if (LPC_CT32B1->IR & (0x1 << 6))
+  {
+    LPC_CT32B1->IR = 0x1 << 6;
+  }
+  if (LPC_CT32B1->IR & (0x1 << 7))
+  {
+    LPC_CT32B1->IR = 0x1 << 7;
+  }
+
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Initialises the specified 32-bit timer
+
+    @param[in]  timer
+                The 32-bit timer to use (must be 0 or 1)
+*/
+/**************************************************************************/
+void timer32Init(uint8_t timer)
+{
+  if ( timer == 0 )
+  {
+    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<9);
+    #if defined CFG_MCU_FAMILY_LPC11UXX
+    NVIC_EnableIRQ(TIMER_32_0_IRQn);
+    #elif defined CFG_MCU_FAMILY_LPC13UXX
+    NVIC_EnableIRQ(CT32B0_IRQn);
+    #endif
+  }
+  else if ( timer == 1 )
+  {
+    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<10);
+    #if defined CFG_MCU_FAMILY_LPC11UXX
+    NVIC_EnableIRQ(TIMER_32_1_IRQn);
+    #elif defined CFG_MCU_FAMILY_LPC13UXX
+    NVIC_EnableIRQ(CT32B1_IRQn);
+    #endif
+  }
+
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Enables the specified 32-bit timer
+
+    @param[in]  timer
+                The 32-bit timer to use (must be 0 or 1)
+*/
+/**************************************************************************/
+void timer32Enable(uint8_t timer)
+{
+  if ( timer == 0 )
+  {
+    LPC_CT32B0->TCR = 1;
+  }
+  else if (timer == 1)
+  {
+    LPC_CT32B1->TCR = 1;
+  }
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Disables the specified 32-bit timer
+
+    @param[in]  timer
+                The 32-bit timer to use (must be 0 or 1)
+*/
+/**************************************************************************/
+void timer32Disable(uint8_t timer)
+{
+  if ( timer == 0 )
+  {
+    LPC_CT32B0->TCR = 0;
+  }
+  else if (timer == 1)
+  {
+    LPC_CT32B1->TCR = 0;
+  }
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Resets the specified 32-bit timer
+
+    @param[in]  timer
+                The 32-bit timer to use (must be 0 or 1)
+*/
+/**************************************************************************/
+void timer32Reset(uint8_t timer)
+{
+  uint32_t regVal;
+
+  if ( timer == 0 )
+  {
+    regVal = LPC_CT32B0->TCR;
+    regVal |= 0x02;
+    LPC_CT32B0->TCR = regVal;
+  }
+  else if (timer == 1)
+  {
+    regVal = LPC_CT32B1->TCR;
+    regVal |= 0x02;
+    LPC_CT32B1->TCR = regVal;
+  }
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Causes a blocking delay on the specified 32-bit timer
+
+    @param[in]  timer
+                The 32-bit timer to use (must be 0 or 1)
+    @param[in]  delayInMs
+                The number of milliseconds to wait
+*/
+/**************************************************************************/
+void timer32DelayMs(uint8_t timer, uint32_t delayInMs)
+{
+  if (timer == 0)
+  {
+    LPC_CT32B0->TCR  = 0x02;            /* Reset the timer */
+    LPC_CT32B0->PR   = 0x00;            /* Set prescaler to zero */
+    LPC_CT32B0->PWMC = 0x00;            /* Disable PWM mode */
+    LPC_CT32B0->MR0  = delayInMs * (SystemCoreClock / 1000);
+    LPC_CT32B0->IR   = 0xff;            /* Reset all interrrupts */
+    LPC_CT32B0->MCR  = 0x04;            /* Stop the timer on match */
+    LPC_CT32B0->TCR  = 0x01;            /* Start timer */
+
+    /* Wait until delay time has elapsed */
+    while (LPC_CT32B0->TCR & 0x01);
+  }
+  else if (timer == 1)
+  {
+    LPC_CT32B1->TCR  = 0x02;            /* Reset the timer */
+    LPC_CT32B1->PR   = 0x00;            /* Set prescaler to zero */
+    LPC_CT32B1->PWMC = 0x00;            /* Disable PWM mode */
+    LPC_CT32B1->MR0  = delayInMs * (SystemCoreClock / 1000);
+    LPC_CT32B1->IR   = 0xff;            /* Reset all interrrupts */
+    LPC_CT32B1->MCR  = 0x04;            /* Stop the timer on match */
+    LPC_CT32B1->TCR  = 0x01;            /* Start timer */
+
+    /* Wait until delay time has elapsed */
+    while (LPC_CT32B1->TCR & 0x01);
+  }
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Causes a blocking delay on the specified 32-bit timer
+
+    @param[in]  timer
+                The 32-bit timer to use (must be 0 or 1)
+    @param[in]  delayInTicks
+                The number of clock cycles ('ticks') to wait
+*/
+/**************************************************************************/
+void timer32DelayTicks(uint8_t timer, uint32_t delayInTicks)
+{
+  if (timer == 0)
+  {
+    LPC_CT32B0->TCR  = 0x02;            /* Reset the timer */
+    LPC_CT32B0->PR   = 0x00;            /* Set prescaler to zero */
+    LPC_CT32B0->PWMC = 0x00;            /* Disable PWM mode */
+    LPC_CT32B0->MR0  = delayInTicks;
+    LPC_CT32B0->IR   = 0xff;            /* Reset all interrrupts */
+    LPC_CT32B0->MCR  = 0x04;            /* Stop the timer on match */
+    LPC_CT32B0->TCR  = 0x01;            /* Start timer */
+
+    /* Wait until delay time has elapsed */
+    while (LPC_CT32B0->TCR & 0x01);
+  }
+  else if (timer == 1)
+  {
+    LPC_CT32B1->TCR  = 0x02;            /* Reset the timer */
+    LPC_CT32B1->PR   = 0x00;            /* Set prescaler to zero */
+    LPC_CT32B1->PWMC = 0x00;            /* Disable PWM mode */
+    LPC_CT32B1->MR0  = delayInTicks;
+    LPC_CT32B1->IR   = 0xff;            /* Reset all interrrupts */
+    LPC_CT32B1->MCR  = 0x04;            /* Stop the timer on match */
+    LPC_CT32B1->TCR  = 0x01;            /* Start timer */
+
+    /* Wait until delay time has elapsed */
+    while (LPC_CT32B1->TCR & 0x01);
+  }
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Configures the match register for the specified 32-bit timer
+
+    @param[in]  timer
+                The 32-bit timer to use (must be 0 or 1)
+    @param[in]  matchNum
+                The match register to set (must be 0..3)
+    @param[in]  value
+                The value to assign to the specified match register
+
+    @code
+    // Set MAT1 on timer 0 to 12000 ticks
+    timer32SetMatch(0, 1, 12000);
+    @endcode
+*/
+/**************************************************************************/
+void timer32SetMatch(uint8_t timer, uint8_t matchNum, uint32_t value)
+{
+  if (timer)
+  {
+    switch (matchNum)
+    {
+      case 0:
+        LPC_CT32B1->MR0 = value;
+        break;
+      case 1:
+        LPC_CT32B1->MR1 = value;
+        break;
+      case 2:
+        LPC_CT32B1->MR2 = value;
+        break;
+      case 3:
+        LPC_CT32B1->MR3 = value;
+        break;
+      default:
+        break;
+    }
+  }
+  else
+  {
+    switch (matchNum)
+    {
+      case 0:
+        LPC_CT32B0->MR0 = value;
+        break;
+      case 1:
+        LPC_CT32B0->MR1 = value;
+        break;
+      case 2:
+        LPC_CT32B0->MR2 = value;
+        break;
+      case 3:
+        LPC_CT32B0->MR3 = value;
+        break;
+      default:
+        break;
+    }
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Configures 32-bit Timer 0 for PWM output using MR0 to control
+            the period, and MR1, MR2 and MR3 for duty cycle.  Duty cycle
+            can be adjusted via timer32SetMatch.
+
+    @param[in]  period
+                The period in timer clock ticks
+
+    @code
+    // Set 1.25 to T320_MAT1
+    LPC_IOCON->PIO1_25 &= ~0x07;
+    LPC_IOCON->PIO1_25 |= 0x01;
+
+    // Set 1.26 to T320_MAT2
+    LPC_IOCON->PIO1_26 &= ~0x07;
+    LPC_IOCON->PIO1_26 |= 0x01;
+
+    // Set 1.27 to T320_MAT3
+    LPC_IOCON->PIO1_27 &= ~0x07;
+    LPC_IOCON->PIO1_27 |= 0x01;
+
+    // Setup PWM with 12,000 cycle period (MAT0 used for period)
+    timer32SetPWM0(12000);
+
+    // PWM Match Settings
+    timer32SetMatch(0, 1, 12000); // MAT1 will go high on last cycle
+    timer32SetMatch(0, 2, 8000);  // MAT2 will go high for final 1/3
+    timer32SetMatch(0, 3, 4000);  // MAT3 will go high for final 2/3
+
+    // Enable to PWM output
+    timer32Enable(0);
+    @endcode
+*/
+/**************************************************************************/
+void timer32SetPWM0(uint32_t period)
+{
+  timer32Disable(0);
+
+  /* Make sure 32-bit timer 0 is enabled */
+  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<9);
+
+  /* Setup the external match register (clear on match) */
+  LPC_CT32B0->EMR =  (1<<10) | (1<<8) | (1<<6) | (1<<4) |
+                     (1<<0)  | (1<<1) | (1<<2) | (1<<3);
+
+  /* Set MAT0..3 to PWM mode via the PWM Control register */
+  LPC_CT32B0->PWMC = (1<<0)  | (1<<1) | (1<<2) | (1<<3);
+
+  /* MAT0 controls period, set MAT1..3 to 50% duty cycle to start */
+  timer32SetMatch(0, 0, period);
+  timer32SetMatch(0, 1, period / 2);
+  timer32SetMatch(0, 2, period / 2);
+  timer32SetMatch(0, 3, period / 2);
+
+  /* Reset on MR0 */
+  LPC_CT32B0->MCR = 1 << 1;
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/core/timer32/timer32.h b/reform2-lpc-fw/src/core/timer32/timer32.h
new file mode 100644
index 0000000000000000000000000000000000000000..f598b606f92b3120d31e4d4faccbac5193970b84
--- /dev/null
+++ b/reform2-lpc-fw/src/core/timer32/timer32.h
@@ -0,0 +1,56 @@
+/**************************************************************************/
+/*!
+    @file     timer32.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _TIMER32_H_
+#define _TIMER32_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void timer32Init       ( uint8_t timer );
+void timer32Enable     ( uint8_t timer );
+void timer32Disable    ( uint8_t timer );
+void timer32Reset      ( uint8_t timer );
+void timer32DelayMs    ( uint8_t timer, uint32_t delayInMs );
+void timer32DelayTicks ( uint8_t timer, uint32_t delayInTicks );
+void timer32SetMatch   ( uint8_t timer, uint8_t matchNum, uint32_t value );
+void timer32SetPWM0    ( uint32_t period );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/core/uart/uart.c b/reform2-lpc-fw/src/core/uart/uart.c
new file mode 100644
index 0000000000000000000000000000000000000000..3f056d06a09d438adfaddc960ec523b303c5efec
--- /dev/null
+++ b/reform2-lpc-fw/src/core/uart/uart.c
@@ -0,0 +1,344 @@
+/**************************************************************************/
+/*!
+    @file     uart.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section DESCRIPTION
+
+    Generic code for UART-based communication.  Incoming text is stored
+    in a FIFO Queue for safer processing.
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012 K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_ENABLE_UART
+
+#include <string.h>
+
+#include "uart.h"
+
+/**************************************************************************/
+/*!
+    UART protocol control block, which is used to safely access the
+    RX FIFO buffer from elsewhere in the code.  This should be accessed
+    through 'uartGetPCB()'.
+*/
+/**************************************************************************/
+static uart_pcb_t uart_pcb;
+
+/**************************************************************************/
+/*!
+    IRQ to handle incoming data, etc.
+*/
+/**************************************************************************/
+#if defined CFG_MCU_FAMILY_LPC11UXX
+void UART_IRQHandler(void)
+#elif defined CFG_MCU_FAMILY_LPC13UXX
+void USART_IRQHandler(void)
+#else
+  #error "uart.c: No MCU defined"
+#endif
+{
+  uint8_t IIRValue, LSRValue;
+  uint8_t Dummy = Dummy;
+
+  IIRValue = LPC_USART->IIR;
+  IIRValue &= ~(USART_IIR_IntStatus_MASK); /* skip pending bit in IIR */
+  IIRValue &= USART_IIR_IntId_MASK;        /* check bit 1~3, interrupt identification */
+
+  // 1.) Check receiver line status
+  if (IIRValue == USART_IIR_IntId_RLS)
+  {
+    LSRValue = LPC_USART->LSR;
+    // Check for errors
+    if (LSRValue & (USART_LSR_OE | USART_LSR_PE | USART_LSR_FE | USART_LSR_RXFE | USART_LSR_BI))
+    {
+      /* There are errors or break interrupt */
+      /* Read LSR will clear the interrupt */
+      uart_pcb.status = LSRValue;
+      Dummy = LPC_USART->RBR;  /* Dummy read on RX to clear interrupt, then bail out */
+      return;
+    }
+    // No error and receive data is ready
+    if (LSRValue & USART_LSR_RDR_DATA)
+    {
+      /* If no error on RLS, normal ready, save into the data buffer. */
+      /* Note: read RBR will clear the interrupt */
+      uartRxBufferWrite(LPC_USART->RBR);
+    }
+  }
+
+  // 2.) Check receive data available
+  else if (IIRValue == USART_IIR_IntId_RDA)
+  {
+    // Add incoming text to UART buffer
+    uartRxBufferWrite(LPC_USART->RBR);
+  }
+
+  // 3.) Check character timeout indicator
+  else if (IIRValue == USART_IIR_IntId_CTI)
+  {
+    /* Bit 9 as the CTI error */
+    uart_pcb.status |= 0x100;
+  }
+
+  // 4.) Check THRE (transmit holding register empty)
+  else if (IIRValue == USART_IIR_IntId_THRE)
+  {
+    /* Check status in the LSR to see if valid data in U0THR or not */
+    LSRValue = LPC_USART->LSR;
+    if (LSRValue & USART_LSR_THRE)
+    {
+      uart_pcb.pending_tx_data = 0;
+    }
+    else
+    {
+      uart_pcb.pending_tx_data= 1;
+    }
+  }
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Get a pointer to the UART's protocol control block, which can
+            be used to control the RX FIFO buffer and check whether UART
+            has already been initialised or not.
+
+    @section Example
+
+    @code
+    // Make sure that UART is initialised
+    uart_pcb_t *pcb = uartGetPCB();
+    if (!pcb->initialised)
+    {
+      uartInit(CFG_UART_BAUDRATE);
+    }
+    @endcode
+
+*/
+/**************************************************************************/
+uart_pcb_t *uartGetPCB()
+{
+    return &uart_pcb;
+}
+
+/**************************************************************************/
+/*!
+    @brief Initialises UART at the specified baud rate.
+
+    @param[in]  baudRate
+                The baud rate to use when configuring the UART.
+*/
+/**************************************************************************/
+void uartInit(uint32_t baudrate)
+{
+  uint32_t fDiv;
+  uint32_t regVal=regVal;
+
+  #if defined CFG_MCU_FAMILY_LPC11UXX
+    NVIC_DisableIRQ(UART_IRQn);
+  #elif defined CFG_MCU_FAMILY_LPC13UXX
+    NVIC_DisableIRQ(USART_IRQn);
+  #endif
+
+  /* Clear protocol control blocks */
+  memset(&uart_pcb, 0, sizeof(uart_pcb_t));
+  uart_pcb.pending_tx_data = 0;
+  uartRxBufferInit();
+
+  /* Set 0.18 UART RXD */
+  //LPC_IOCON->PIO0_18 &= ~0x07;
+  //LPC_IOCON->PIO0_18 |= 0x01;
+
+  /* Set 0.19 UART TXD */
+  //LPC_IOCON->PIO0_19 &= ~0x07;
+  //LPC_IOCON->PIO0_19 |= 0x01;
+
+  // UART connected to i.MX8M ttymxc2 REFORM
+#if 0
+  /* Set 0.14 UART RXD */
+  LPC_IOCON->PIO1_14 &= ~0x07;
+  LPC_IOCON->PIO1_14 |= 0x03;
+
+  /* Set 0.13 UART TXD */
+  LPC_IOCON->PIO1_13 &= ~0x07;
+  LPC_IOCON->PIO1_13 |= 0x3;
+#endif
+
+  // UART connected to expansion header / keyboard REFORM
+#if 1
+  /* Set 1.26 UART RXD */
+  LPC_IOCON->PIO1_26 &= ~0x07;
+  LPC_IOCON->PIO1_26 |= 0x2;
+
+  /* Set 1.27 UART TXD */
+  LPC_IOCON->PIO1_27 &= ~0x07;
+  LPC_IOCON->PIO1_27 |= 0x2;
+#endif
+  
+#if defined UART_RTS_CTS_FLOWCONTROL
+  /* start RTS/CTS flow control setup - davidson 130531 */
+  LPC_IOCON->PIO0_7 &= ~0x07;   /* Flow control CTS UART I/O Config  Type Input */
+  LPC_IOCON->PIO0_7 |= 0x01; 
+
+  LPC_IOCON->PIO1_17 &= ~0x07;  /* Flow control RTS UART I/O Config  Type Output */
+  LPC_IOCON->PIO1_17 |= 0x01;  
+  /* end of RTS/CTS flow control setup */
+#endif  
+  
+  /* Enable UART clock */
+  LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 12);
+  LPC_SYSCON->UARTCLKDIV = 1;
+
+  /* 8 bits, no Parity, 1 Stop bit */
+  LPC_USART->LCR = (USART_LCR_Word_Length_Select_8Chars |
+                USART_LCR_Stop_Bit_Select_1Bits |
+                USART_LCR_Parity_Disabled |
+                USART_LCR_Parity_Select_OddParity |
+                USART_LCR_Break_Control_Disabled |
+                USART_LCR_Divisor_Latch_Access_Enabled);
+
+  /* Baud rate */
+  regVal = LPC_SYSCON->UARTCLKDIV;
+  fDiv = ((SystemCoreClock/LPC_SYSCON->UARTCLKDIV)/16)/baudrate;
+
+  LPC_USART->DLM = fDiv / 256;
+  LPC_USART->DLL = fDiv % 256;
+
+  /* Set DLAB back to 0 */
+  LPC_USART->LCR = (USART_LCR_Word_Length_Select_8Chars |
+                USART_LCR_Stop_Bit_Select_1Bits |
+                USART_LCR_Parity_Disabled |
+                USART_LCR_Parity_Select_OddParity |
+                USART_LCR_Break_Control_Disabled |
+                USART_LCR_Divisor_Latch_Access_Disabled);
+
+  /* Enable and reset TX and RX FIFO. */
+  LPC_USART->FCR = (USART_FCR_FIFO_Enabled |
+                USART_FCR_Rx_FIFO_Reset |
+                USART_FCR_Tx_FIFO_Reset);
+
+#if defined UART_RTS_CTS_FLOWCONTROL
+  /* Enable Auto RTS and Auto CTS  - davidson 130531 */
+  LPC_UART->MCR = 0xC0;
+#endif
+                
+  /* Read to clear the line status. */
+  regVal = LPC_USART->LSR;
+
+  /* Ensure a clean start, no data in either TX or RX FIFO. */
+  while (( LPC_USART->LSR & (USART_LSR_THRE|USART_LSR_TEMT)) != (USART_LSR_THRE|USART_LSR_TEMT) );
+  while ( LPC_USART->LSR & USART_LSR_RDR_DATA )
+  {
+    /* Dump data from RX FIFO */
+    regVal = LPC_USART->RBR;
+  }
+
+  /* Set the initialised flag in the protocol control block */
+  uart_pcb.initialised = 1;
+  uart_pcb.baudrate = baudrate;
+
+  /* Enable the UART Interrupt */
+  #if defined CFG_MCU_FAMILY_LPC11UXX
+    NVIC_EnableIRQ(UART_IRQn);
+  #elif defined CFG_MCU_FAMILY_LPC13UXX
+    NVIC_EnableIRQ(USART_IRQn);
+  #endif
+  LPC_USART->IER = USART_IER_RBR_Interrupt_Enabled | USART_IER_RLS_Interrupt_Enabled;
+
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Sends the contents of supplied text buffer over UART.
+
+    @param[in]  bufferPtr
+                Pointer to the text buffer
+    @param[in]  bufferPtr
+                The size of the text buffer
+
+    @section Example
+
+    @code
+    // Set 5-character text buffer
+    uint8_t uartBuffer[5] = { 'T', 'e', 's', 't', '\n' };
+    // Send contents of uartBuffer
+    uartSend((uint8_t *)uartBuffer, 5);
+    @endcode
+
+*/
+/**************************************************************************/
+void uartSend (uint8_t *bufferPtr, uint32_t length)
+{
+  while (length != 0)
+  {
+    /* THRE status, contain valid data */
+    while ( !(LPC_USART->LSR & USART_LSR_THRE) );
+    LPC_USART->THR = *bufferPtr;
+
+    bufferPtr++;
+    length--;
+  }
+
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Sends a single byte over UART.
+
+    @param[in]  byte
+                Byte value to send
+
+    @section Example
+
+    @code
+    // Send 0xFF over UART
+    uartSendByte(0xFF);
+    // Send 'B' over UART (note single quotes)
+    uartSendByte('B');
+    @endcode
+
+*/
+/**************************************************************************/
+void uartSendByte (uint8_t byte)
+{
+  /* THRE status, contain valid data */
+  while ( !(LPC_USART->LSR & USART_LSR_THRE) );
+  LPC_USART->THR = byte;
+
+  return;
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/core/uart/uart.h b/reform2-lpc-fw/src/core/uart/uart.h
new file mode 100644
index 0000000000000000000000000000000000000000..7d5cef9e76fe5f3f4156562f20c2c40853e1f036
--- /dev/null
+++ b/reform2-lpc-fw/src/core/uart/uart.h
@@ -0,0 +1,250 @@
+/**************************************************************************/
+/*! 
+    @file     uart.h
+    @author   K. Townsend (microBuilder.eu)
+    @date     22 March 2010
+    @version  0.10
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __USART_H__ 
+#define __USART_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+/* Uncomment this line to enable HW flow control */
+// #define UART_RTS_CTS_FLOWCONTROL
+
+#define USART_RBR_MASK                           ((unsigned int) 0x000000FF)
+
+#define USART_IER_RBR_Interrupt_MASK             ((unsigned int) 0x00000001) // Enables the received data available interrupt
+#define USART_IER_RBR_Interrupt_Enabled          ((unsigned int) 0x00000001)
+#define USART_IER_RBR_Interrupt_Disabled         ((unsigned int) 0x00000000)
+#define USART_IER_THRE_Interrupt_MASK            ((unsigned int) 0x00000002) // Enables the THRE interrupt
+#define USART_IER_THRE_Interrupt_Enabled         ((unsigned int) 0x00000002)
+#define USART_IER_THRE_Interrupt_Disabled        ((unsigned int) 0x00000000)
+#define USART_IER_RLS_Interrupt_MASK             ((unsigned int) 0x00000004) // Enables the Rx line status interrupt
+#define USART_IER_RLS_Interrupt_Enabled          ((unsigned int) 0x00000004)
+#define USART_IER_RLS_Interrupt_Disabled         ((unsigned int) 0x00000000)
+#define USART_IER_ABEOIntEn_MASK                 ((unsigned int) 0x00000100) // End of auto-baud interrupt
+#define USART_IER_ABEOIntEn_Enabled              ((unsigned int) 0x00000100)
+#define USART_IER_ABEOIntEn_Disabled             ((unsigned int) 0x00000000)
+#define USART_IER_ABTOIntEn_MASK                 ((unsigned int) 0x00000200) // Auto-baud timeout interrupt
+#define USART_IER_ABTOIntEn_Enabled              ((unsigned int) 0x00000200)
+#define USART_IER_ABTOIntEn_Disabled             ((unsigned int) 0x00000000)
+
+#define USART_IIR_IntStatus_MASK                 ((unsigned int) 0x00000001) // Interrupt status
+#define USART_IIR_IntStatus_InterruptPending     ((unsigned int) 0x00000001)
+#define USART_IIR_IntStatus_NoInterruptPending   ((unsigned int) 0x00000000)
+#define USART_IIR_IntId_MASK                     ((unsigned int) 0x0000000E) // Interrupt identification
+#define USART_IIR_IntId_RLS                      ((unsigned int) 0x00000006) // Receive line status
+#define USART_IIR_IntId_RDA                      ((unsigned int) 0x00000004) // Receive data available
+#define USART_IIR_IntId_CTI                      ((unsigned int) 0x0000000C) // Character time-out indicator
+#define USART_IIR_IntId_THRE                     ((unsigned int) 0x00000002) // THRE interrupt
+#define USART_IIR_IntId_MODEM                    ((unsigned int) 0x00000000) // Modem interrupt
+#define USART_IIR_FIFO_Enable_MASK               ((unsigned int) 0x000000C0)
+#define USART_IIR_ABEOInt_MASK                   ((unsigned int) 0x00000100) // End of auto-baud interrupt
+#define USART_IIR_ABEOInt                        ((unsigned int) 0x00000100)
+#define USART_IIR_ABTOInt_MASK                   ((unsigned int) 0x00000200) // Auto-baud time-out interrupt
+#define USART_IIR_ABTOInt                        ((unsigned int) 0x00000200)
+
+#define USART_FCR_FIFO_Enable_MASK               ((unsigned int) 0x00000001) // UART FIFOs enabled/disabled
+#define USART_FCR_FIFO_Enabled                   ((unsigned int) 0x00000001)
+#define USART_FCR_FIFO_Disabled                  ((unsigned int) 0x00000000)
+#define USART_FCR_Rx_FIFO_Reset_MASK             ((unsigned int) 0x00000002)
+#define USART_FCR_Rx_FIFO_Reset                  ((unsigned int) 0x00000002) // Clear Rx FIFO
+#define USART_FCR_Tx_FIFO_Reset_MASK             ((unsigned int) 0x00000004)
+#define USART_FCR_Tx_FIFO_Reset                  ((unsigned int) 0x00000004) // Clear Tx FIFO
+#define USART_FCR_Rx_Trigger_Level_Select_MASK   ((unsigned int) 0x000000C0) // Chars written before before interrupt
+#define USART_FCR_Rx_Trigger_Level_Select_1Char  ((unsigned int) 0x00000000) 
+#define USART_FCR_Rx_Trigger_Level_Select_4Char  ((unsigned int) 0x00000040) 
+#define USART_FCR_Rx_Trigger_Level_Select_8Char  ((unsigned int) 0x00000080) 
+#define USART_FCR_Rx_Trigger_Level_Select_12Char ((unsigned int) 0x000000C0) 
+
+#define USART_MCR_DTR_Control_MASK               ((unsigned int) 0x00000001) // Source for modem output pin DTR
+#define USART_MCR_DTR_Control                    ((unsigned int) 0x00000001)
+#define USART_MCR_RTS_Control_MASK               ((unsigned int) 0x00000002) // Source for modem output pin RTS
+#define USART_MCR_RTS_Control                    ((unsigned int) 0x00000002)
+#define USART_MCR_Loopback_Mode_Select_MASK      ((unsigned int) 0x00000010) // Diagnostic loopback mode
+#define USART_MCR_Loopback_Mode_Select_Enabled   ((unsigned int) 0x00000010)
+#define USART_MCR_Loopback_Mode_Select_Disabled  ((unsigned int) 0x00000000)
+#define USART_MCR_RTSen_MASK                     ((unsigned int) 0x00000040) // Disable auto-rts flow control
+#define USART_MCR_RTSen_Enabled                  ((unsigned int) 0x00000040)
+#define USART_MCR_RTSen_Disabled                 ((unsigned int) 0x00000000)
+#define USART_MCR_CTSen_MASK                     ((unsigned int) 0x00000080) // Disable auto-cts flow control
+#define USART_MCR_CTSen_Enabled                  ((unsigned int) 0x00000080)
+#define USART_MCR_CTSen_Disabled                 ((unsigned int) 0x00000000)
+
+#define USART_LCR_Word_Length_Select_MASK        ((unsigned int) 0x00000003) // Word Length Selector
+#define USART_LCR_Word_Length_Select_5Chars      ((unsigned int) 0x00000000)
+#define USART_LCR_Word_Length_Select_6Chars      ((unsigned int) 0x00000001)
+#define USART_LCR_Word_Length_Select_7Chars      ((unsigned int) 0x00000002)
+#define USART_LCR_Word_Length_Select_8Chars      ((unsigned int) 0x00000003)
+#define USART_LCR_Stop_Bit_Select_MASK           ((unsigned int) 0x00000004) // Stop bit select
+#define USART_LCR_Stop_Bit_Select_1Bits          ((unsigned int) 0x00000000)
+#define USART_LCR_Stop_Bit_Select_2Bits          ((unsigned int) 0x00000004)
+#define USART_LCR_Parity_Enable_MASK             ((unsigned int) 0x00000008) // Parity enable
+#define USART_LCR_Parity_Enabled                 ((unsigned int) 0x00000008)
+#define USART_LCR_Parity_Disabled                ((unsigned int) 0x00000000)
+#define USART_LCR_Parity_Select_MASK             ((unsigned int) 0x00000030) // Parity select
+#define USART_LCR_Parity_Select_OddParity        ((unsigned int) 0x00000000)
+#define USART_LCR_Parity_Select_EvenParity       ((unsigned int) 0x00000010)
+#define USART_LCR_Parity_Select_Forced1          ((unsigned int) 0x00000020)
+#define USART_LCR_Parity_Select_Forced0          ((unsigned int) 0x00000030)
+#define USART_LCR_Break_Control_MASK             ((unsigned int) 0x00000040) // Break transmission control
+#define USART_LCR_Break_Control_Enabled          ((unsigned int) 0x00000040)
+#define USART_LCR_Break_Control_Disabled         ((unsigned int) 0x00000000)
+#define USART_LCR_Divisor_Latch_Access_MASK      ((unsigned int) 0x00000080) // Divisor latch access
+#define USART_LCR_Divisor_Latch_Access_Enabled   ((unsigned int) 0x00000080)
+#define USART_LCR_Divisor_Latch_Access_Disabled  ((unsigned int) 0x00000000)
+
+#define USART_LSR_RDR_MASK                       ((unsigned int) 0x00000001) // Receiver data ready
+#define USART_LSR_RDR_EMPTY                      ((unsigned int) 0x00000000) // U0RBR is empty
+#define USART_LSR_RDR_DATA                       ((unsigned int) 0x00000001) // U0RBR contains valid data
+#define USART_LSR_OE_MASK                        ((unsigned int) 0x00000002) // Overrun error
+#define USART_LSR_OE                             ((unsigned int) 0x00000002)
+#define USART_LSR_PE_MASK                        ((unsigned int) 0x00000004) // Parity error
+#define USART_LSR_PE                             ((unsigned int) 0x00000004)
+#define USART_LSR_FE_MASK                        ((unsigned int) 0x00000008) // Framing error
+#define USART_LSR_FE                             ((unsigned int) 0x00000008)
+#define USART_LSR_BI_MASK                        ((unsigned int) 0x00000010) // Break interrupt
+#define USART_LSR_BI                             ((unsigned int) 0x00000010)
+#define USART_LSR_THRE_MASK                      ((unsigned int) 0x00000020) // Transmitter holding register empty
+#define USART_LSR_THRE                           ((unsigned int) 0x00000020)
+#define USART_LSR_TEMT_MASK                      ((unsigned int) 0x00000040) // Transmitter empty
+#define USART_LSR_TEMT                           ((unsigned int) 0x00000040)
+#define USART_LSR_RXFE_MASK                      ((unsigned int) 0x00000080) // Error in Rx FIFO
+#define USART_LSR_RXFE                           ((unsigned int) 0x00000080)
+
+#define USART_MSR_Delta_CTS_MASK                 ((unsigned int) 0x00000001) // State change of input CTS
+#define USART_MSR_Delta_CTS                      ((unsigned int) 0x00000001)
+#define USART_MSR_Delta_DSR_MASK                 ((unsigned int) 0x00000002) // State change of input DSR
+#define USART_MSR_Delta_DSR                      ((unsigned int) 0x00000002)
+#define USART_MSR_Trailing_Edge_RI_MASK          ((unsigned int) 0x00000004) // Low to high transition of input RI
+#define USART_MSR_Trailing_Edge_RI               ((unsigned int) 0x00000004)
+#define USART_MSR_Delta_DCD_MASK                 ((unsigned int) 0x00000008) // State change of input DCD
+#define USART_MSR_Delta_DCD                      ((unsigned int) 0x00000008)
+#define USART_MSR_CTS_MASK                       ((unsigned int) 0x00000010) // Clear to send state
+#define USART_MSR_CTS                            ((unsigned int) 0x00000010)
+#define USART_MSR_DSR_MASK                       ((unsigned int) 0x00000020) // Data set ready state
+#define USART_MSR_DSR                            ((unsigned int) 0x00000020)
+#define USART_MSR_RI_MASK                        ((unsigned int) 0x00000040) // Ring indicator state
+#define USART_MSR_RI                             ((unsigned int) 0x00000040)
+#define USART_MSR_DCD_MASK                       ((unsigned int) 0x00000080) // Data carrier detect state
+#define USART_MSR_DCD                            ((unsigned int) 0x00000080)
+
+#define USART_ACR_Start_MASK                     ((unsigned int) 0x00000001) // Auto-baud start/stop
+#define USART_ACR_Start                          ((unsigned int) 0x00000001)
+#define USART_ACR_Stop                           ((unsigned int) 0x00000000)
+#define USART_ACR_Mode_MASK                      ((unsigned int) 0x00000002) // Auto-baud mode select
+#define USART_ACR_Mode_Mode1                     ((unsigned int) 0x00000000)
+#define USART_ACR_Mode_Mode2                     ((unsigned int) 0x00000002)
+#define USART_ACR_AutoRestart_MASK               ((unsigned int) 0x00000004)
+#define USART_ACR_AutoRestart_NoRestart          ((unsigned int) 0x00000000)
+#define USART_ACR_AutoRestart_Restart            ((unsigned int) 0x00000004) // Restart in case of time-out
+#define USART_ACR_ABEOIntClr_MASK                ((unsigned int) 0x00000100) // End of auto-baud interrupt clear bit
+#define USART_ACR_ABEOIntClr                     ((unsigned int) 0x00000100) 
+#define USART_ACR_ABTOIntClr_MASK                ((unsigned int) 0x00000200) // Auto-baud timeout interrupt clear bit
+#define USART_ACR_ABTOIntClr                     ((unsigned int) 0x00000200)
+
+#define USART_FDR_DIVADDVAL_MASK                 ((unsigned int) 0x0000000F) // Fractional divider: prescaler register
+#define USART_FDR_MULVAL_MASK                    ((unsigned int) 0x000000F0) // Fractional divider: prescaler multiplier
+
+#define USART_TER_TXEN_MASK                      ((unsigned int) 0x00000080) // UART transmit enable
+#define USART_TER_TXEN_Enabled                   ((unsigned int) 0x00000080)
+#define USART_TER_TXEN_Disabled                  ((unsigned int) 0x00000000)
+
+#define USART_RS485CTRL_NMMEN_MASK               ((unsigned int) 0x00000001) // Normal multi-drop mode
+#define USART_RS485CTRL_NMMEN                    ((unsigned int) 0x00000001)
+#define USART_RS485CTRL_RXDIS_MASK               ((unsigned int) 0x00000002) // Receiver
+#define USART_RS485CTRL_RXDIS                    ((unsigned int) 0x00000002)
+#define USART_RS485CTRL_AADEN_MASK               ((unsigned int) 0x00000004) // Auto-address detect
+#define USART_RS485CTRL_AADEN                    ((unsigned int) 0x00000004)
+#define USART_RS485CTRL_SEL_MASK                 ((unsigned int) 0x00000008) 
+#define USART_RS485CTRL_SEL_RTS                  ((unsigned int) 0x00000000) // Use RTS for direction control
+#define USART_RS485CTRL_SEL_DTS                  ((unsigned int) 0x00000008) // Use DTS for direction control
+#define USART_RS485CTRL_DCTRL_MASK               ((unsigned int) 0x00000010) // Enable/Disable auto-direction control
+#define USART_RS485CTRL_DCTRL_Disabled           ((unsigned int) 0x00000000)
+#define USART_RS485CTRL_DCTRL_Enabled            ((unsigned int) 0x00000010)
+#define USART_RS485CTRL_OINV_MASK                ((unsigned int) 0x00000020) // Reverse polarity of direction control signal on RTS/DTR pin
+#define USART_RS485CTRL_OINV_Normal              ((unsigned int) 0x00000000)
+#define USART_RS485CTRL_OINV_Inverted            ((unsigned int) 0x00000020)
+
+#define USART_FIFOLVL_RXFIFOLVL_MASK             ((unsigned int) 0x0000000F)
+#define USART_FIFOLVL_RXFIFOLVL_Empty            ((unsigned int) 0x00000000)
+#define USART_FIFOLVL_RXFIFOLVL_Full             ((unsigned int) 0x0000000F)
+#define USART_FIFOLVL_TXFIFOLVL_MASK             ((unsigned int) 0x00000F00)
+#define USART_FIFOLVL_TXFIFOLVL_Empty            ((unsigned int) 0x00000000)
+#define USART_FIFOLVL_TXFIFOLVL_Full             ((unsigned int) 0x00000F00)
+
+// Buffer used for circular fifo
+typedef struct _uart_buffer_t
+{
+  uint8_t ep_dir;
+  volatile uint8_t len;
+  volatile uint8_t wr_ptr;
+  volatile uint8_t rd_ptr;
+  uint8_t buf[CFG_UART_BUFSIZE];
+} uart_buffer_t;
+
+// UART Protocol control block
+typedef struct _uart_pcb_t
+{
+  bool initialised;
+  uint32_t baudrate;
+  uint32_t status;
+  uint32_t pending_tx_data;
+  uart_buffer_t rxfifo;
+} uart_pcb_t;
+
+void USART_IRQHandler(void);
+uart_pcb_t *uartGetPCB(void);
+void uartInit(uint32_t Baudrate);
+void uartSend(uint8_t *BufferPtr, uint32_t Length);
+void uartSendByte (uint8_t byte);
+
+// Rx Buffer access control
+void uartRxBufferInit(void);
+uint8_t uartRxBufferRead(void);
+void uartRxBufferWrite(uint8_t data);
+void uartRxBufferClearFIFO(void);
+uint8_t uartRxBufferDataPending(void);
+bool uartRxBufferReadArray(byte_t* rx, size_t* len);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/core/uart/uart_buf.c b/reform2-lpc-fw/src/core/uart/uart_buf.c
new file mode 100644
index 0000000000000000000000000000000000000000..f51733e6c23f36b6b4fab89ff0e93ab801d93fd8
--- /dev/null
+++ b/reform2-lpc-fw/src/core/uart/uart_buf.c
@@ -0,0 +1,149 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+*******************************************************************/
+
+/**************************************************************************/
+/*! 
+    @file     uart_buf.c
+    @author   Christopher Wang (Freaklabs)
+              Modified by: K. Townsend (microBuilder.eu)
+    @date     19 May 2010
+
+    Original code taken from the FreakUSB Open Source USB Device Stack
+    http://freaklabs.org/index.php/FreakUSB-Open-Source-USB-Device-Stack.html
+
+    If it works well, you can thank Akiba at Freaklabs.  If it fails
+    miserably, you can blame me (since parts of it it were rather
+    ungraciously modified). :-)
+
+*/
+/**************************************************************************/
+
+#include "uart.h"
+
+/**************************************************************************/
+/*!
+  Initialises the RX FIFO buffer
+*/
+/**************************************************************************/
+void uartRxBufferInit()
+{
+  uart_pcb_t *pcb = uartGetPCB();
+  pcb->rxfifo.len = 0;
+}
+
+/**************************************************************************/
+/*!
+  Read one byte out of the RX buffer. This function will return the byte
+  located at the array index of the read pointer, and then increment the
+  read pointer index.  If the read pointer exceeds the maximum buffer
+  size, it will roll over to zero.
+*/
+/**************************************************************************/
+uint8_t uartRxBufferRead()
+{
+  uart_pcb_t *pcb = uartGetPCB();
+  uint8_t data;
+
+  data = pcb->rxfifo.buf[pcb->rxfifo.rd_ptr];
+  pcb->rxfifo.rd_ptr = (pcb->rxfifo.rd_ptr + 1) % CFG_UART_BUFSIZE;
+  pcb->rxfifo.len--;
+  return data;
+}
+
+/**************************************************************************/
+/*!
+  Read byte array from uart
+ */
+/**************************************************************************/
+bool uartRxBufferReadArray(byte_t* rx, size_t* len)
+{
+  uart_pcb_t *pcb = uartGetPCB();
+  *len = 0;
+  
+  while(pcb->rxfifo.len != 0)
+  {
+    (*rx) = uartRxBufferRead();
+    (*len)++;
+    rx++;
+  }
+  
+  return (*len != 0);
+}
+
+/**************************************************************************/
+/*!
+  Write one byte into the RX buffer. This function will write one
+  byte into the array index specified by the write pointer and increment
+  the write index. If the write index exceeds the max buffer size, then it
+  will roll over to zero.
+*/
+/**************************************************************************/
+void uartRxBufferWrite(uint8_t data)
+{
+  uart_pcb_t *pcb = uartGetPCB();
+
+  pcb->rxfifo.buf[pcb->rxfifo.wr_ptr] = data;
+  pcb->rxfifo.wr_ptr = (pcb->rxfifo.wr_ptr + 1) % CFG_UART_BUFSIZE;
+  pcb->rxfifo.len++;
+}
+
+/**************************************************************************/
+/*!
+    Clear the fifo read and write pointers and set the length to zero.
+*/
+/**************************************************************************/
+void uartRxBufferClearFIFO()
+{
+  uart_pcb_t *pcb = uartGetPCB();
+
+  pcb->rxfifo.rd_ptr = 0;
+  pcb->rxfifo.wr_ptr = 0;
+  pcb->rxfifo.len = 0;
+}
+
+/**************************************************************************/
+/*!
+    Check whether there is any data pending on the RX buffer.
+*/
+/**************************************************************************/
+uint8_t uartRxBufferDataPending()
+{
+  uart_pcb_t *pcb = uartGetPCB();
+
+  if (pcb->rxfifo.len != 0)
+  {
+    return 1;
+  }
+
+  return 0;
+}
diff --git a/reform2-lpc-fw/src/core/usb/README.md b/reform2-lpc-fw/src/core/usb/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..378d669f1f8dab34ed215c731b02b18ecdb084df
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/README.md
@@ -0,0 +1,26 @@
+# USB Support #
+
+This code base include a relatively easy to use USB layer that allows you to enumerate one or more of the following USB device classes:
+
+- **USB CDC** - allows you to redirect printf and CLI input and output to a virtual serial port on any host device
+- **USB Mass Storage** - points to an on-board SD card and enumerates the card as an external storage device, allowing you to read and write files from any operating system
+- **USB HID** - Out of the box support for the following HID options:
+ - **HID Mouse** - emulates a 5-button, 2-scroll wheel USB mouse with an easy wrapper function to update the button/wheel state
+ - **HID Keyboard** - emulates a USB keyboard with a wrapper function to send key data to the host device
+ - **HID Generic** - Can be used to send and receive HID Reports of a pre-determined size, and multiple reports can optionally be implemented this way with a bit of extra code.
+
+## Auto USB Composite Device Enumeration ##
+
+One of the key advantages of the way USB support is implemented in the code base is that -- within the limits of the avaiable endpoints -- the system will automatically enumerate as a USB Composite device if more than one USB class is selected in the board config file.
+
+For example, if both CFG_USB_CDC and CFG_USB_HID_GENERIC are defined in your board config file, the system will automatically enumerate both devices during initialisation, without any need to update the descriptors yourself.
+
+The USB Product ID will be updated depending on the combination of classes selected in your board config file, and the supplied Windows .inf file to enable CDC support on Windows should take into account any of these combinations.
+
+## Serial Number Based on the Unique Chip ID ##
+
+During USB enumeration, the device descriptor provides a USB Serial Number based on the unique serial number stored on the LPC11U24/LPC11U37/LPC1347, which can be accessed via IAP calls.  This means that every device that you program will have a unique USB serial number, and you can have several identical devices connected on the same host.
+
+## No Major License Restrictions ##
+
+Because all of the USB code is based on the ROM-based drivers, you no longer have any licensing issues with the Keil USB stacks that were used in many previous LPC1K examples from NXP.  All of the custom USB code provided in this API (everything in this directory) is licensed under a BSD-style license, and the public ROM-driver files provided by NXP (everything in the 'romdriver' folder) is provided with license terms that are far more flexible than the previous Keil stacks.
\ No newline at end of file
diff --git a/reform2-lpc-fw/src/core/usb/WinCDCdriver.inf b/reform2-lpc-fw/src/core/usb/WinCDCdriver.inf
new file mode 100644
index 0000000000000000000000000000000000000000..1ff517b2f567f57f4e5fa640c8e750f92c5335f7
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/WinCDCdriver.inf
@@ -0,0 +1,106 @@
+;************************************************************
+; Windows USB CDC ACM Setup File
+; Copyright (c) 2000 Microsoft Corporation
+
+
+[Version]
+Signature="$Windows NT$"
+Class=Ports
+ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
+Provider=%MFGNAME%
+LayoutFile=layout.inf
+CatalogFile=%MFGFILENAME%.cat
+DriverVer=11/15/2007,5.1.2600.0
+
+[Manufacturer]
+%MFGNAME%=DeviceList, NTamd64
+
+[DestinationDirs]
+DefaultDestDir=12
+
+
+;------------------------------------------------------------------------------
+;  Windows 2000/XP/Vista-32bit Sections
+;------------------------------------------------------------------------------
+
+[DriverInstall.nt]
+include=mdmcpq.inf
+CopyFiles=DriverCopyFiles.nt
+AddReg=DriverInstall.nt.AddReg
+
+[DriverCopyFiles.nt]
+usbser.sys,,,0x20
+
+[DriverInstall.nt.AddReg]
+HKR,,DevLoader,,*ntkern
+HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
+HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
+
+[DriverInstall.nt.Services]
+AddService=usbser, 0x00000002, DriverService.nt
+
+[DriverService.nt]
+DisplayName=%SERVICE%
+ServiceType=1
+StartType=3
+ErrorControl=1
+ServiceBinary=%12%\%DRIVERFILENAME%.sys
+
+;------------------------------------------------------------------------------
+;  Vista-64bit Sections
+;------------------------------------------------------------------------------
+
+[DriverInstall.NTamd64]
+include=mdmcpq.inf
+CopyFiles=DriverCopyFiles.NTamd64
+AddReg=DriverInstall.NTamd64.AddReg
+
+[DriverCopyFiles.NTamd64]
+%DRIVERFILENAME%.sys,,,0x20
+
+[DriverInstall.NTamd64.AddReg]
+HKR,,DevLoader,,*ntkern
+HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
+HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
+
+[DriverInstall.NTamd64.Services]
+AddService=usbser, 0x00000002, DriverService.NTamd64
+
+[DriverService.NTamd64]
+DisplayName=%SERVICE%
+ServiceType=1
+StartType=3
+ErrorControl=1
+ServiceBinary=%12%\%DRIVERFILENAME%.sys
+
+
+;------------------------------------------------------------------------------
+;  Vendor and Product ID Definitions
+;------------------------------------------------------------------------------
+; When developing your USB device, the VID and PID used in the PC side
+; application program and the firmware on the microcontroller must match.
+; Modify the below line to use your VID and PID.  Use the format as shown below.
+; Note: One INF file can be used for multiple devices with different VID and PIDs.
+; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line.
+;------------------------------------------------------------------------------
+[SourceDisksFiles]
+[SourceDisksNames]
+[DeviceList]
+%DESCRIPTION%=DriverInstall, USB\VID_1FC9&PID_2001, USB\VID_1FC9&PID_2003&MI_00, USB\VID_1FC9&PID_2005&MI_00, USB\VID_1FC9&PID_2007&MI_00, USB\VID_1FC9&PID_2009&MI_00, USB\VID_1FC9&PID_200b&MI_00, USB\VID_1FC9&PID_200d&MI_00, USB\VID_1FC9&PID_200f&MI_00, USB\VID_1FC9&PID_2011&MI_00, USB\VID_1FC9&PID_2013&MI_00, USB\VID_1FC9&PID_2015&MI_00, USB\VID_1FC9&PID_2017&MI_00, USB\VID_1FC9&PID_2019&MI_00, USB\VID_1FC9&PID_201b&MI_00, USB\VID_1FC9&PID_201d&MI_00, USB\VID_1FC9&PID_201f&MI_00, USB\VID_1FC9&PID_2021&MI_00, USB\VID_1FC9&PID_2023&MI_00, USB\VID_1FC9&PID_2025&MI_00, USB\VID_1FC9&PID_2027&MI_00, USB\VID_1FC9&PID_2029&MI_00, USB\VID_1FC9&PID_202b&MI_00, USB\VID_1FC9&PID_202d&MI_00, USB\VID_1FC9&PID_202f&MI_00, USB\VID_1FC9&PID_2031&MI_00, USB\VID_1FC9&PID_2033&MI_00, USB\VID_1FC9&PID_2035&MI_00, USB\VID_1FC9&PID_2037&MI_00, USB\VID_1FC9&PID_2039&MI_00, USB\VID_1FC9&PID_203b&MI_00, USB\VID_1FC9&PID_203d&MI_00, USB\VID_1FC9&PID_203f&MI_00
+
+
+[DeviceList.NTamd64]
+%DESCRIPTION%=DriverInstall, USB\VID_1FC9&PID_2001, USB\VID_1FC9&PID_2003&MI_00, USB\VID_1FC9&PID_2005&MI_00, USB\VID_1FC9&PID_2007&MI_00, USB\VID_1FC9&PID_2009&MI_00, USB\VID_1FC9&PID_200b&MI_00, USB\VID_1FC9&PID_200d&MI_00, USB\VID_1FC9&PID_200f&MI_00, USB\VID_1FC9&PID_2011&MI_00, USB\VID_1FC9&PID_2013&MI_00, USB\VID_1FC9&PID_2015&MI_00, USB\VID_1FC9&PID_2017&MI_00, USB\VID_1FC9&PID_2019&MI_00, USB\VID_1FC9&PID_201b&MI_00, USB\VID_1FC9&PID_201d&MI_00, USB\VID_1FC9&PID_201f&MI_00, USB\VID_1FC9&PID_2021&MI_00, USB\VID_1FC9&PID_2023&MI_00, USB\VID_1FC9&PID_2025&MI_00, USB\VID_1FC9&PID_2027&MI_00, USB\VID_1FC9&PID_2029&MI_00, USB\VID_1FC9&PID_202b&MI_00, USB\VID_1FC9&PID_202d&MI_00, USB\VID_1FC9&PID_202f&MI_00, USB\VID_1FC9&PID_2031&MI_00, USB\VID_1FC9&PID_2033&MI_00, USB\VID_1FC9&PID_2035&MI_00, USB\VID_1FC9&PID_2037&MI_00, USB\VID_1FC9&PID_2039&MI_00, USB\VID_1FC9&PID_203b&MI_00, USB\VID_1FC9&PID_203d&MI_00, USB\VID_1FC9&PID_203f&MI_00
+
+;------------------------------------------------------------------------------
+;  String Definitions
+;------------------------------------------------------------------------------
+;Modify these strings to customize your device
+;------------------------------------------------------------------------------
+[Strings]
+MFGFILENAME="CDC_vista"
+DRIVERFILENAME ="usbser"
+MFGNAME="microBuilder.eu"
+INSTDISK="microBuilder CDC driver"
+DESCRIPTION="Communications Port"
+SERVICE="USB RS-232 Emulation Driver"
\ No newline at end of file
diff --git a/reform2-lpc-fw/src/core/usb/app_usbd_cfg.h b/reform2-lpc-fw/src/core/usb/app_usbd_cfg.h
new file mode 100644
index 0000000000000000000000000000000000000000..c757066609802361d2d1d9e98febe96fc0834998
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/app_usbd_cfg.h
@@ -0,0 +1,145 @@
+/**************************************************************************/
+/*!
+    @file     app_usbd_cfg.h
+    @author   Thach Ha (tinyusb.net)
+
+    @section DESCRIPTION
+
+    Common USB daemon config settings
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __APP_USBD_CFG_H__
+#define __APP_USBD_CFG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "romdriver/mw_usbd.h"
+
+#define USB_MAX_IF_NUM                      (8)
+#define USB_MAX_EP_NUM                      (5)
+
+#define USB_FS_MAX_BULK_PACKET              (64)
+#define USB_HS_MAX_BULK_PACKET              (USB_FS_MAX_BULK_PACKET) /* Full speed device only */
+
+// Control Endpoint
+#define USB_MAX_PACKET0                     (64)
+
+#ifdef CFG_USB_CDC
+  #define INTERFACES_OF_CDC                 (2)
+#else
+  #define INTERFACES_OF_CDC                 (0)
+#endif
+
+#ifdef CFG_USB_HID_KEYBOARD
+  #define INTERFACES_OF_HID_KEYBOARD        (1)
+#else
+  #define INTERFACES_OF_HID_KEYBOARD        (0)
+#endif
+
+#ifdef CFG_USB_HID_MOUSE
+  #define INTERFACES_OF_HID_MOUSE           (1)
+#else
+  #define INTERFACES_OF_HID_MOUSE           (0)
+#endif
+
+
+#ifdef CFG_USB_HID_GENERIC
+  #define INTERFACES_OF_HID_GENERIC         (1)
+#else
+  #define INTERFACES_OF_HID_GENERIC         (0)
+#endif
+
+#ifdef CFG_USB_MSC
+  #define INTERFACES_OF_MSC                 (1)
+#else
+  #define INTERFACES_OF_MSC                 (0)
+#endif
+
+#ifdef CFG_USB_CUSTOM_CLASS
+  #define INTERFACES_OF_CUSTOM              (1)
+#else
+  #define INTERFACES_OF_CUSTOM              (0)
+#endif
+
+#define INTERFACE_INDEX_CDC                 (0)
+#define INTERFACE_INDEX_HID_KEYBOARD        (INTERFACE_INDEX_CDC          + INTERFACES_OF_CDC          )
+#define INTERFACE_INDEX_HID_MOUSE           (INTERFACE_INDEX_HID_KEYBOARD + INTERFACES_OF_HID_KEYBOARD )
+#define INTERFACE_INDEX_HID_GENERIC         (INTERFACE_INDEX_HID_MOUSE    + INTERFACES_OF_HID_MOUSE    )
+#define INTERFACE_INDEX_MSC                 (INTERFACE_INDEX_HID_GENERIC  + INTERFACES_OF_HID_GENERIC  )
+#define INTERFACE_INDEX_CUSTOM              (INTERFACE_INDEX_MSC          + INTERFACES_OF_MSC          )
+
+#define TOTAL_INTEFACES                     (INTERFACES_OF_CDC + INTERFACES_OF_HID_KEYBOARD + INTERFACES_OF_HID_MOUSE +\
+    INTERFACES_OF_HID_GENERIC + INTERFACES_OF_MSC + INTERFACES_OF_CUSTOM)
+
+// Number of Endpoint IN used by CDC, HID is equal to the number of its interface, here we used INTERFACES_OF_CLASS as EP_IN_USED_BY_CLASS
+#define  CDC_NUMBER_OF_EP_IN                (INTERFACES_OF_CDC)
+#define  HID_KEYBOARD_NUMBER_OF_EP_IN       (INTERFACES_OF_HID_KEYBOARD)
+#define  HID_MOUSE_NUMBER_OF_EP_IN          (INTERFACES_OF_HID_MOUSE)
+#define  HID_GENERIC_NUMBER_OF_EP_IN        (INTERFACES_OF_HID_GENERIC)
+#define  MSC_NUMBER_OF_EP_IN                (INTERFACES_OF_MSC)
+#define  CUSTOM_NUMBER_OF_EP_IN             (INTERFACES_OF_CUSTOM)
+
+#define  EP_IN_TOTAL                        (CDC_NUMBER_OF_EP_IN + HID_KEYBOARD_NUMBER_OF_EP_IN + HID_MOUSE_NUMBER_OF_EP_IN+\
+    HID_GENERIC_NUMBER_OF_EP_IN + MSC_NUMBER_OF_EP_IN + CUSTOM_NUMBER_OF_EP_IN)
+
+/* CDC Endpoint Address */
+#define  CDC_NOTIFICATION_EP                (USB_ENDPOINT_IN(1))
+#define  CDC_DATA_EP_IN                     (USB_ENDPOINT_IN(2))
+#define  CDC_DATA_EP_OUT                    (USB_ENDPOINT_OUT(1))
+#define  CDC_NOTIFICATION_EP_MAXPACKETSIZE  (8)
+#define  CDC_DATA_EP_MAXPACKET_SIZE         (16)
+
+/*       HID                                In/Out                Endpoint  Address  */
+#define  HID_KEYBOARD_EP_IN                 (CDC_NOTIFICATION_EP  + CDC_NUMBER_OF_EP_IN)
+#define  HID_MOUSE_EP_IN                    (HID_KEYBOARD_EP_IN   + HID_KEYBOARD_NUMBER_OF_EP_IN)
+#define  HID_GENERIC_EP_IN                  (HID_MOUSE_EP_IN      + HID_MOUSE_NUMBER_OF_EP_IN)
+#define  HID_GENERIC_EP_OUT                 (USB_ENDPOINT_OUT(2))
+
+//       MSC                                Enpoint               Address
+#define  MSC_EP_IN                          (HID_GENERIC_EP_IN    + HID_GENERIC_NUMBER_OF_EP_IN)
+#define  MSC_EP_OUT                         (USB_ENDPOINT_OUT(3))
+
+// CUSTOM CLASS
+#define  CUSTOM_EP_IN                       (MSC_EP_IN + MSC_NUMBER_OF_EP_IN)
+#define  CUSTOM_EP_OUT                      (USB_ENDPOINT_OUT(4))
+
+#if (EP_IN_TOTAL > 4)
+  #error lpc11uxx and lpc13uxx only has up to 4 IN endpoints
+#endif
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif  /* __USBCFG_H__ */
diff --git a/reform2-lpc-fw/src/core/usb/descriptors.c b/reform2-lpc-fw/src/core/usb/descriptors.c
new file mode 100644
index 0000000000000000000000000000000000000000..626748b1bfbe645f1de17a2efd76118e2886a10b
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/descriptors.c
@@ -0,0 +1,534 @@
+/**************************************************************************/
+/*!
+    @file     descriptors.c
+    @author   Thach Ha (tinyusb.net)
+
+    @section DESCRIPTION
+
+    Descriptors for USB initialisation and identification
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "descriptors.h"
+
+#ifdef CFG_USB
+
+#ifdef CFG_USB_HID_KEYBOARD
+ALIGNED(4) const uint8_t HID_KeyboardReportDescriptor[] = {
+  HID_UsagePage  ( HID_USAGE_PAGE_GENERIC     ),
+  HID_Usage      ( HID_USAGE_GENERIC_KEYBOARD ),
+  HID_Collection ( HID_Application            ),
+    HID_UsagePage (HID_USAGE_PAGE_KEYBOARD),
+      HID_UsageMin    (224                                     ),
+      HID_UsageMax    (231                                     ),
+      HID_LogicalMin  ( 0                                      ),
+      HID_LogicalMax  ( 1                                      ),
+
+      HID_ReportCount ( 8                                      ), /* 8 bits */
+      HID_ReportSize  ( 1                                      ),
+      HID_Input       ( HID_Data | HID_Variable | HID_Absolute ), /* maskable modifier key */
+
+      HID_ReportCount ( 1                                      ),
+      HID_ReportSize  ( 8                                      ),
+      HID_Input       (HID_Constant                            ), /* reserved */
+
+    HID_UsagePage  ( HID_USAGE_PAGE_LED                   ),
+      HID_UsageMin    (1                                       ),
+      HID_UsageMax    (5                                       ),
+      HID_ReportCount (5                                       ),
+      HID_ReportSize  (1                                       ),
+      HID_Output      ( HID_Data | HID_Variable | HID_Absolute ), /* 5-bit Led report */
+
+      HID_ReportCount ( 1                                      ),
+      HID_ReportSize  (3                                       ), /* led padding */
+      HID_Output      (HID_Constant                            ),
+
+    HID_UsagePage (HID_USAGE_PAGE_KEYBOARD),
+      HID_UsageMin    (0                                   ),
+      HID_UsageMax    (101                                 ),
+      HID_LogicalMin  (0                                       ),
+      HID_LogicalMax  (101                                     ),
+
+      HID_ReportCount (6                                   ),
+      HID_ReportSize  (8                                   ),
+      HID_Input       (HID_Data | HID_Array | HID_Absolute ), /* keycodes array 6 items */
+  HID_EndCollection,
+};
+#endif
+
+#ifdef CFG_USB_HID_MOUSE
+ALIGNED(4) const uint8_t HID_MouseReportDescriptor[] = {
+  HID_UsagePage  ( HID_USAGE_PAGE_GENERIC     ),
+  HID_Usage      ( HID_USAGE_GENERIC_MOUSE ),
+  HID_Collection ( HID_Application            ),
+    HID_Usage (HID_USAGE_GENERIC_POINTER),
+
+    HID_Collection ( HID_Physical ),
+      HID_UsagePage  ( HID_USAGE_PAGE_BUTTON     ),
+        HID_UsageMin    ( 1                                      ), /* FW | BW | MD | RM | LM */
+        HID_UsageMax    ( 5                                      ),
+        HID_LogicalMin  ( 0                                      ),
+        HID_LogicalMax  ( 1                                      ),
+
+        HID_ReportCount ( 5                                      ),
+        HID_ReportSize  ( 1                                      ),
+        HID_Input       ( HID_Data | HID_Variable | HID_Absolute ),
+
+        HID_ReportCount ( 1                                      ),
+        HID_ReportSize  ( 3                                      ),
+        HID_Input       (HID_Constant                            ), /* reserved */
+
+      HID_UsagePage  ( HID_USAGE_PAGE_GENERIC ),
+        HID_Usage       ( HID_USAGE_GENERIC_X                    ), /* X, Y position */
+        HID_Usage       ( HID_USAGE_GENERIC_Y                    ),
+        HID_LogicalMin  ( 0x81                                   ), /* -127 */
+        HID_LogicalMax  ( 0x7f                                   ), /* 127  */
+
+        HID_ReportCount ( 2                                      ),
+        HID_ReportSize  ( 8                                      ), /* X, Y is 8-bit */
+        HID_Input       ( HID_Data | HID_Variable | HID_Relative ), /* relative values */
+
+        HID_Usage       ( HID_USAGE_GENERIC_WHEEL                ), /* mouse scroll */
+        HID_LogicalMin  ( 0x81                                   ), /* -127 */
+        HID_LogicalMax  ( 0x7f                                   ), /* 127  */
+        HID_ReportCount ( 1                                      ),
+        HID_ReportSize  ( 8                                      ), /* 8-bit value */
+        HID_Input       ( HID_Data | HID_Variable | HID_Relative ), /* relative values */
+
+      HID_UsagePage     ( HID_USAGE_PAGE_CONSUMER         ),
+        HID_Usage_2Bytes( HID_USAGE_CONSUMER_ACPAN               ), /* mouse scroll */
+        HID_LogicalMin  ( 0x81                                   ), /* -127 */
+        HID_LogicalMax  ( 0x7f                                   ), /* 127  */
+        HID_ReportCount ( 1                                      ),
+        HID_ReportSize  ( 8                                      ), /* 8-bit value */
+        HID_Input       ( HID_Data | HID_Variable | HID_Relative ), /* relative values */
+
+    HID_EndCollection,
+
+  HID_EndCollection,
+};
+#endif
+
+#ifdef CFG_USB_HID_GENERIC
+
+#define  HID_GENERIC_USAGEPAGE_VENDOR  0x00
+#define  HID_GENERIC_USAGE_COLLECTION  0x01
+#define  HID_GENERIC_USAGE_IN          0x02
+#define  HID_GENERIC_USAGE_OUT         0x03
+
+ALIGNED(4) const uint8_t HID_GenericReportDescriptor[] = {
+    HID_UsagePageVendor (HID_GENERIC_USAGEPAGE_VENDOR ),
+    HID_Usage           (HID_GENERIC_USAGE_COLLECTION ),
+    HID_Collection      (HID_Application              ),
+      HID_Usage       (HID_GENERIC_USAGE_IN                   ),
+      HID_LogicalMin  (0x00                                   ),
+      HID_LogicalMax  (0xff                                   ),
+      HID_ReportSize  (8                                      ),
+      HID_ReportCount (CFG_USB_HID_GENERIC_REPORT_SIZE        ),
+      HID_Input       (HID_Data | HID_Variable | HID_Absolute ),
+
+      HID_Usage       (HID_GENERIC_USAGE_OUT                   ),
+      HID_LogicalMin  (0x00                                    ),
+      HID_LogicalMax  (0xff                                    ),
+      HID_ReportSize  (8                                       ),
+      HID_ReportCount (CFG_USB_HID_GENERIC_REPORT_SIZE         ),
+      HID_Output      ( HID_Data | HID_Variable | HID_Absolute ),
+
+    HID_EndCollection,
+};
+#endif
+
+/* USB Standard Device Descriptor */
+ALIGNED(4) const USB_DEVICE_DESCRIPTOR USB_DeviceDescriptor =
+{
+  .bLength            = sizeof(USB_DEVICE_DESCRIPTOR),
+  .bDescriptorType    = USB_DEVICE_DESCRIPTOR_TYPE,
+  .bcdUSB             = 0x0200,
+
+  #if IAD_DESC_REQUIRED
+  /* Multiple Interfaces Using Interface Association Descriptor (IAD) */
+  .bDeviceClass       = USB_DEVICE_CLASS_IAD,
+  .bDeviceSubClass    = USB_DEVICE_SUBCLASS_IAD,
+  .bDeviceProtocol    = USB_DEVICE_PROTOCOL_IAD,
+  #elif defined CFG_USB_CDC
+  .bDeviceClass       = CDC_COMMUNICATION_INTERFACE_CLASS,
+  .bDeviceSubClass    = 0x00,
+  .bDeviceProtocol    = 0x00,
+  #else
+  .bDeviceClass       = 0x00,
+  .bDeviceSubClass    = 0x00,
+  .bDeviceProtocol    = 0x00,
+  #endif
+
+  .bMaxPacketSize0    = USB_MAX_PACKET0,
+
+  .idVendor           = CFG_USB_VENDORID,
+  .idProduct          = USB_PRODUCT_ID,
+  .bcdDevice          = 0x0100,
+
+  .iManufacturer      = 0x01,
+  .iProduct           = 0x02,
+  .iSerialNumber      = 0x03,
+
+  .bNumConfigurations = 0x01
+};
+
+ALIGNED(4) const USB_FS_CONFIGURATION_DESCRIPTOR USB_FsConfigDescriptor =
+{
+    .Config =
+    {
+        .bLength             = sizeof(USB_CONFIGURATION_DESCRIPTOR),
+        .bDescriptorType     = USB_CONFIGURATION_DESCRIPTOR_TYPE,
+
+        .wTotalLength        = sizeof(USB_FS_CONFIGURATION_DESCRIPTOR) - 1, // exclude termination
+        .bNumInterfaces      = TOTAL_INTEFACES,
+
+        .bConfigurationValue = 1,
+        .iConfiguration      = 0x00,
+        .bmAttributes        = USB_CONFIG_BUS_POWERED,
+        .bMaxPower           = USB_CONFIG_POWER_MA(500)
+    },
+
+    #if IAD_DESC_REQUIRED
+    // IAD points to CDC Interfaces
+    .CDC_IAD =
+    {
+        .bLength           = sizeof(USB_INTERFACE_ASSOCIATION_DESCRIPTOR),
+        .bDescriptorType   = USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE,
+
+        .bFirstInterface   = 0,
+        .bInterfaceCount   = 2,
+
+        .bFunctionClass    = CDC_COMMUNICATION_INTERFACE_CLASS,
+        .bFunctionSubClass = CDC_ABSTRACT_CONTROL_MODEL,
+        .bFunctionProtocol = CDC_PROTOCOL_COMMON_AT_COMMANDS,
+
+        .iFunction         = 0
+    },
+    #endif
+
+    #ifdef CFG_USB_CDC
+    // USB CDC Serial Interface
+    // CDC Control Interface
+    .CDC_CCI_Interface =
+    {
+        .bLength            = sizeof(USB_INTERFACE_DESCRIPTOR),
+        .bDescriptorType    = USB_INTERFACE_DESCRIPTOR_TYPE,
+        .bInterfaceNumber   = INTERFACE_INDEX_CDC,
+        .bAlternateSetting  = 0,
+        .bNumEndpoints      = 1,
+        .bInterfaceClass    = CDC_COMMUNICATION_INTERFACE_CLASS,
+        .bInterfaceSubClass = CDC_ABSTRACT_CONTROL_MODEL,
+        .bInterfaceProtocol = CDC_PROTOCOL_COMMON_AT_COMMANDS,
+        .iInterface         = 0x00
+    },
+
+    .CDC_Header =
+    {
+        .bFunctionLength    = sizeof(CDC_HEADER_DESCRIPTOR),
+        .bDescriptorType    = CDC_CS_INTERFACE,
+        .bDescriptorSubtype = CDC_HEADER,
+        .bcdCDC             = 0x0120
+    },
+
+    .CDC_ACM =
+    {
+        .bFunctionLength    = sizeof(CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR),
+        .bDescriptorType    = CDC_CS_INTERFACE,
+        .bDescriptorSubtype = CDC_ABSTRACT_CONTROL_MANAGEMENT,
+        .bmCapabilities     = 0x06 // Support Send_Break and Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State
+    },
+
+    .CDC_Union =
+    {
+        .sUnion =
+        {
+            .bFunctionLength    = sizeof(CDC_UNION_1SLAVE_DESCRIPTOR),
+            .bDescriptorType    = CDC_CS_INTERFACE,
+            .bDescriptorSubtype = CDC_UNION,
+            .bMasterInterface   = 0
+        },
+        .bSlaveInterfaces[0] = 1
+    },
+
+    .CDC_NotificationEndpoint =
+    {
+        .bLength          = sizeof(USB_ENDPOINT_DESCRIPTOR),
+        .bDescriptorType  = USB_ENDPOINT_DESCRIPTOR_TYPE,
+        .bEndpointAddress = CDC_NOTIFICATION_EP,
+        .bmAttributes     = USB_ENDPOINT_TYPE_INTERRUPT,
+        .wMaxPacketSize   = CDC_NOTIFICATION_EP_MAXPACKETSIZE,
+        .bInterval        = 0xff // lowest polling rate
+    },
+
+    // CDC Data Interface
+    .CDC_DCI_Interface =
+    {
+        .bLength            = sizeof(USB_INTERFACE_DESCRIPTOR),
+        .bDescriptorType    = USB_INTERFACE_DESCRIPTOR_TYPE,
+        .bInterfaceNumber   = INTERFACE_INDEX_CDC+1,
+        .bAlternateSetting  = 0x00,
+        .bNumEndpoints      = 2,
+        .bInterfaceClass    = CDC_DATA_INTERFACE_CLASS,
+        .bInterfaceSubClass = 0,
+        .bInterfaceProtocol = 0,
+        .iInterface         = 0x00
+    },
+
+    .CDC_DataOutEndpoint =
+    {
+        .bLength          = sizeof(USB_ENDPOINT_DESCRIPTOR),
+        .bDescriptorType  = USB_ENDPOINT_DESCRIPTOR_TYPE,
+        .bEndpointAddress = CDC_DATA_EP_OUT,
+        .bmAttributes     = USB_ENDPOINT_TYPE_BULK,
+        .wMaxPacketSize   = CDC_DATA_EP_MAXPACKET_SIZE,
+        .bInterval        = 0
+    },
+
+    .CDC_DataInEndpoint =
+    {
+        .bLength          = sizeof(USB_ENDPOINT_DESCRIPTOR),
+        .bDescriptorType  = USB_ENDPOINT_DESCRIPTOR_TYPE,
+        .bEndpointAddress = CDC_DATA_EP_IN,
+        .bmAttributes     = USB_ENDPOINT_TYPE_BULK,
+        .wMaxPacketSize   = CDC_DATA_EP_MAXPACKET_SIZE,
+        .bInterval        = 0
+    },
+    #endif
+
+    #ifdef CFG_USB_HID_KEYBOARD
+    ///// USB HID Keyboard interface
+    .HID_KeyboardInterface =
+    {
+        .bLength            = sizeof(USB_INTERFACE_DESCRIPTOR),
+        .bDescriptorType    = USB_INTERFACE_DESCRIPTOR_TYPE,
+        .bInterfaceNumber   = INTERFACE_INDEX_HID_KEYBOARD,
+        .bAlternateSetting  = 0x00,
+        .bNumEndpoints      = 1,
+        .bInterfaceClass    = USB_DEVICE_CLASS_HUMAN_INTERFACE,
+        .bInterfaceSubClass = HID_SUBCLASS_BOOT,
+        .bInterfaceProtocol = HID_PROTOCOL_KEYBOARD,
+        .iInterface         = 0x00
+    },
+
+    .HID_KeyboardHID =
+    {
+        .bLength           = sizeof(HID_DESCRIPTOR),
+        .bDescriptorType   = HID_HID_DESCRIPTOR_TYPE,
+        .bcdHID            = 0x0111,
+        .bCountryCode      = HID_Local_NotSupported,
+        .bNumDescriptors   = 1,
+        .DescriptorList[0] =
+        {
+            .bDescriptorType   = HID_REPORT_DESCRIPTOR_TYPE,
+            .wDescriptorLength = sizeof(HID_KeyboardReportDescriptor)
+        },
+    },
+
+    .HID_KeyboardEndpoint =
+    {
+        .bLength          = sizeof(USB_ENDPOINT_DESCRIPTOR),
+        .bDescriptorType  = USB_ENDPOINT_DESCRIPTOR_TYPE,
+        .bEndpointAddress = HID_KEYBOARD_EP_IN,
+        .bmAttributes     = USB_ENDPOINT_TYPE_INTERRUPT,
+        .wMaxPacketSize   = 0x08,
+        .bInterval        = 0x0A
+    },
+    #endif
+
+    #ifdef CFG_USB_HID_MOUSE
+    .HID_MouseInterface =
+    {
+        .bLength            = sizeof(USB_INTERFACE_DESCRIPTOR),
+        .bDescriptorType    = USB_INTERFACE_DESCRIPTOR_TYPE,
+        .bInterfaceNumber   = INTERFACE_INDEX_HID_MOUSE,
+        .bAlternateSetting  = 0x00,
+        .bNumEndpoints      = 1,
+        .bInterfaceClass    = USB_DEVICE_CLASS_HUMAN_INTERFACE,
+        .bInterfaceSubClass = HID_SUBCLASS_BOOT,
+        .bInterfaceProtocol = HID_PROTOCOL_MOUSE,
+        .iInterface         = 0x00
+    },
+
+    .HID_MouseHID =
+    {
+        .bLength           = sizeof(HID_DESCRIPTOR),
+        .bDescriptorType   = HID_HID_DESCRIPTOR_TYPE,
+        .bcdHID            = 0x0111,
+        .bCountryCode      = HID_Local_NotSupported,
+        .bNumDescriptors   = 1,
+        .DescriptorList[0] =
+        {
+            .bDescriptorType   = HID_REPORT_DESCRIPTOR_TYPE,
+            .wDescriptorLength = sizeof(HID_MouseReportDescriptor)
+        },
+    },
+
+    .HID_MouseEndpoint =
+    {
+        .bLength          = sizeof(USB_ENDPOINT_DESCRIPTOR),
+        .bDescriptorType  = USB_ENDPOINT_DESCRIPTOR_TYPE,
+        .bEndpointAddress = HID_MOUSE_EP_IN,
+        .bmAttributes     = USB_ENDPOINT_TYPE_INTERRUPT,
+        .wMaxPacketSize   = 0x08,
+        .bInterval        = 0x0A
+    },
+
+    #endif
+
+    #ifdef CFG_USB_HID_GENERIC
+    .HID_GenericInterface =
+    {
+        .bLength            = sizeof(USB_INTERFACE_DESCRIPTOR),
+        .bDescriptorType    = USB_INTERFACE_DESCRIPTOR_TYPE,
+        .bInterfaceNumber   = INTERFACE_INDEX_HID_GENERIC,
+        .bAlternateSetting  = 0x00,
+        .bNumEndpoints      = 2,
+        .bInterfaceClass    = USB_DEVICE_CLASS_HUMAN_INTERFACE,
+        .bInterfaceSubClass = HID_SUBCLASS_NONE,
+        .bInterfaceProtocol = HID_PROTOCOL_NONE,
+        .iInterface         = 0x00
+    },
+
+    .HID_GenericHID =
+    {
+        .bLength           = sizeof(HID_DESCRIPTOR),
+        .bDescriptorType   = HID_HID_DESCRIPTOR_TYPE,
+        .bcdHID            = 0x0111,
+        .bCountryCode      = HID_Local_NotSupported,
+        .bNumDescriptors   = 1,
+        .DescriptorList[0] =
+        {
+            .bDescriptorType   = HID_REPORT_DESCRIPTOR_TYPE,
+            .wDescriptorLength = sizeof(HID_GenericReportDescriptor)
+        },
+    },
+
+    .HID_GenericINEndpoint =
+    {
+        .bLength          = sizeof(USB_ENDPOINT_DESCRIPTOR),
+        .bDescriptorType  = USB_ENDPOINT_DESCRIPTOR_TYPE,
+        .bEndpointAddress = HID_GENERIC_EP_IN,
+        .bmAttributes     = USB_ENDPOINT_TYPE_INTERRUPT,
+        .wMaxPacketSize   = 64,
+        .bInterval        = 0x01
+    },
+
+    .HID_GenericOUTEndpoint =
+    {
+        .bLength          = sizeof(USB_ENDPOINT_DESCRIPTOR),
+        .bDescriptorType  = USB_ENDPOINT_DESCRIPTOR_TYPE,
+        .bEndpointAddress = HID_GENERIC_EP_OUT,
+        .bmAttributes     = USB_ENDPOINT_TYPE_INTERRUPT,
+        .wMaxPacketSize   = 64,
+        .bInterval        = 0x01
+    },
+    #endif
+
+    #ifdef CFG_USB_MSC
+    .MSC_Interface =
+    {
+        .bLength            = sizeof(USB_INTERFACE_DESCRIPTOR),
+        .bDescriptorType    = USB_INTERFACE_DESCRIPTOR_TYPE,
+        .bInterfaceNumber   = INTERFACE_INDEX_MSC,
+        .bAlternateSetting  = 0x00,
+        .bNumEndpoints      = 2,
+        .bInterfaceClass    = USB_DEVICE_CLASS_STORAGE,
+        .bInterfaceSubClass = MSC_SUBCLASS_SCSI,
+        .bInterfaceProtocol = MSC_PROTOCOL_BULK_ONLY,
+        .iInterface         = 0x00
+    },
+
+    .MSC_BulkIN =
+    {
+        .bLength          = sizeof(USB_ENDPOINT_DESCRIPTOR),
+        .bDescriptorType  = USB_ENDPOINT_DESCRIPTOR_TYPE,
+        .bEndpointAddress = MSC_EP_IN,
+        .bmAttributes     = USB_ENDPOINT_TYPE_BULK,
+        .wMaxPacketSize   = 64,
+    },
+
+    .MSC_BulkOUT =
+    {
+        .bLength          = sizeof(USB_ENDPOINT_DESCRIPTOR),
+        .bDescriptorType  = USB_ENDPOINT_DESCRIPTOR_TYPE,
+        .bEndpointAddress = MSC_EP_OUT,
+        .bmAttributes     = USB_ENDPOINT_TYPE_BULK,
+        .wMaxPacketSize   = 64,
+    },
+    #endif
+
+    #ifdef CFG_USB_CUSTOM_CLASS
+    .Custom_Interface =
+    {
+        .bLength            = sizeof(USB_INTERFACE_DESCRIPTOR),
+        .bDescriptorType    = USB_INTERFACE_DESCRIPTOR_TYPE,
+        .bInterfaceNumber   = INTERFACE_INDEX_CUSTOM,
+        .bAlternateSetting  = 0x00,
+        .bNumEndpoints      = 2,
+        .bInterfaceClass    = USB_DEVICE_CLASS_VENDOR_SPECIFIC,
+        .bInterfaceSubClass = 0xff,
+        .bInterfaceProtocol = 0xff,
+        .iInterface         = 0x00
+    },
+
+    .Custom_BulkIN =
+    {
+        .bLength          = sizeof(USB_ENDPOINT_DESCRIPTOR),
+        .bDescriptorType  = USB_ENDPOINT_DESCRIPTOR_TYPE,
+        .bEndpointAddress = CUSTOM_EP_IN,
+        .bmAttributes     = USB_ENDPOINT_TYPE_BULK,
+        .wMaxPacketSize   = 64,
+    },
+
+    .Custom_BulkOUT =
+    {
+        .bLength          = sizeof(USB_ENDPOINT_DESCRIPTOR),
+        .bDescriptorType  = USB_ENDPOINT_DESCRIPTOR_TYPE,
+        .bEndpointAddress = CUSTOM_EP_OUT,
+        .bmAttributes     = USB_ENDPOINT_TYPE_BULK,
+        .wMaxPacketSize   = 64,
+    },
+    #endif
+
+    .ConfigDescTermination = 0,
+};
+
+ALIGNED(4) USB_STR_DESCRIPTOR USB_StringDescriptor =
+{
+    .LangID = { .bLength = 0x04, .bDescriptorType = USB_STRING_DESCRIPTOR_TYPE },
+    .strLangID= {0x0409}, // US English
+    .Manufacturer = { .bLength = USB_STRING_LEN(sizeof(CFG_USB_STRING_MANUFACTURER)-1), .bDescriptorType = USB_STRING_DESCRIPTOR_TYPE },
+    .Product = { .bLength = USB_STRING_LEN(sizeof(CFG_USB_STRING_PRODUCT)-1), .bDescriptorType = USB_STRING_DESCRIPTOR_TYPE },
+    .Serial = { .bLength = USB_STRING_LEN(USB_STRING_SERIAL_LEN), .bDescriptorType = USB_STRING_DESCRIPTOR_TYPE },
+};
+
+#endif /* CFG_USB */
diff --git a/reform2-lpc-fw/src/core/usb/descriptors.h b/reform2-lpc-fw/src/core/usb/descriptors.h
new file mode 100644
index 0000000000000000000000000000000000000000..5d0b76c4af1f78403789574b678becfe5c72a4ae
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/descriptors.h
@@ -0,0 +1,179 @@
+/**************************************************************************/
+/*!
+    @file     descriptors.h
+    @author   Thach Ha (tinyusb.net)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _DESCRIPTORS_H_
+#define _DESCRIPTORS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "app_usbd_cfg.h"
+#include "romdriver/mw_usbd_rom_api.h"
+#include "usbd.h"
+
+#ifdef CFG_USB
+
+/* USB Serial uses the MCUs unique 128-bit chip ID via an IAP call = 32 hex chars */
+#define USB_STRING_SERIAL_LEN     32
+
+#define USB_STRING_LEN(n) (2 + ((n)<<1))
+
+typedef PRE_PACK struct POST_PACK _USB_STR_DESCRIPTOR
+{
+  USB_COMMON_DESCRIPTOR LangID;
+  uint16_t strLangID[1];
+
+  USB_COMMON_DESCRIPTOR Manufacturer;
+  uint16_t strManufacturer[sizeof(CFG_USB_STRING_MANUFACTURER)-1]; // exclude null-character
+
+  USB_COMMON_DESCRIPTOR Product;
+  uint16_t strProduct[sizeof(CFG_USB_STRING_PRODUCT)-1]; // exclude null-character
+
+  USB_COMMON_DESCRIPTOR Serial;
+  uint16_t strSerial[USB_STRING_SERIAL_LEN];
+} USB_STR_DESCRIPTOR;
+
+// USB Interface Assosication Descriptor
+#define  USB_DEVICE_CLASS_IAD        USB_DEVICE_CLASS_MISCELLANEOUS
+#define  USB_DEVICE_SUBCLASS_IAD     0x02
+#define  USB_DEVICE_PROTOCOL_IAD     0x01
+
+// USB Interface Association Descriptor
+typedef PRE_PACK struct POST_PACK _USB_INTERFACE_ASSOCIATION_DESCRIPTOR
+{
+  uint8_t bLength;           /**< Size of descriptor*/
+  uint8_t bDescriptorType;   /**< Other_speed_Configuration Type*/
+
+  uint8_t bFirstInterface;   /**< Index of the first associated interface. */
+  uint8_t bInterfaceCount;   /**< Total number of associated interfaces. */
+
+  uint8_t bFunctionClass;    /**< Interface class ID. */
+  uint8_t bFunctionSubClass; /**< Interface subclass ID. */
+  uint8_t bFunctionProtocol; /**< Interface protocol ID. */
+
+  uint8_t iFunction;         /**< Index of the string descriptor describing the interface association. */
+} USB_INTERFACE_ASSOCIATION_DESCRIPTOR;
+
+///////////////////////////////////////////////////////////////////////
+// Interface Assosication Descriptor if device is CDC + other class
+#define IAD_DESC_REQUIRED ( defined(CFG_USB_CDC) && ( defined(CFG_USB_HID) || defined(CFG_USB_MSC) || defined(CFG_USB_CUSTOM_CLASS)) )
+
+#ifndef USB_PRODUCT_ID
+// Bitmap: MassStorage | Generic | Mouse | Key | CDC
+#define PRODUCTID_BITMAP(interface, n)  ( (INTERFACES_OF_##interface ? 1 : 0) << (n) )
+#define USB_PRODUCT_ID                  (0x2000 | ( PRODUCTID_BITMAP(CDC, 0) | PRODUCTID_BITMAP(HID_KEYBOARD, 1) |\
+                                         PRODUCTID_BITMAP(HID_MOUSE, 2) | PRODUCTID_BITMAP(HID_GENERIC, 3) |\
+                                         PRODUCTID_BITMAP(MSC, 4) | PRODUCTID_BITMAP(CUSTOM, 5) ) )
+#endif
+
+///////////////////////////////////////////////////////////////////////
+typedef struct
+{
+  USB_CONFIGURATION_DESCRIPTOR                Config;
+
+#if IAD_DESC_REQUIRED
+  USB_INTERFACE_ASSOCIATION_DESCRIPTOR        CDC_IAD;
+#endif
+
+#ifdef CFG_USB_CDC
+  //CDC - Serial
+  //CDC Control Interface
+  USB_INTERFACE_DESCRIPTOR                    CDC_CCI_Interface;
+  CDC_HEADER_DESCRIPTOR                       CDC_Header;
+  CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR  CDC_ACM;
+  CDC_UNION_1SLAVE_DESCRIPTOR                 CDC_Union;
+  USB_ENDPOINT_DESCRIPTOR                     CDC_NotificationEndpoint;
+
+  //CDC Data Interface
+  USB_INTERFACE_DESCRIPTOR                    CDC_DCI_Interface;
+  USB_ENDPOINT_DESCRIPTOR                     CDC_DataOutEndpoint;
+  USB_ENDPOINT_DESCRIPTOR                     CDC_DataInEndpoint;
+#endif
+
+#ifdef CFG_USB_HID_KEYBOARD
+  //Keyboard HID Interface
+  USB_INTERFACE_DESCRIPTOR                    HID_KeyboardInterface;
+  HID_DESCRIPTOR                              HID_KeyboardHID;
+  USB_ENDPOINT_DESCRIPTOR                     HID_KeyboardEndpoint;
+#endif
+
+#ifdef CFG_USB_HID_MOUSE
+  //Mouse HID Interface
+  USB_INTERFACE_DESCRIPTOR                    HID_MouseInterface;
+  HID_DESCRIPTOR                              HID_MouseHID;
+  USB_ENDPOINT_DESCRIPTOR                     HID_MouseEndpoint;
+#endif
+
+#ifdef CFG_USB_HID_GENERIC
+  //Generic HID Interface
+  USB_INTERFACE_DESCRIPTOR                    HID_GenericInterface;
+  HID_DESCRIPTOR                              HID_GenericHID;
+  USB_ENDPOINT_DESCRIPTOR                     HID_GenericINEndpoint;
+  USB_ENDPOINT_DESCRIPTOR                     HID_GenericOUTEndpoint;
+
+#endif
+
+#ifdef CFG_USB_MSC
+  USB_INTERFACE_DESCRIPTOR                    MSC_Interface;
+  USB_ENDPOINT_DESCRIPTOR                     MSC_BulkIN;
+  USB_ENDPOINT_DESCRIPTOR                     MSC_BulkOUT;
+#endif
+
+#ifdef CFG_USB_CUSTOM_CLASS
+  USB_INTERFACE_DESCRIPTOR                    Custom_Interface;
+  USB_ENDPOINT_DESCRIPTOR                     Custom_BulkIN;
+  USB_ENDPOINT_DESCRIPTOR                     Custom_BulkOUT;
+#endif
+
+  unsigned char                               ConfigDescTermination;
+} USB_FS_CONFIGURATION_DESCRIPTOR;
+
+extern const USB_DEVICE_DESCRIPTOR USB_DeviceDescriptor;
+extern const USB_FS_CONFIGURATION_DESCRIPTOR USB_FsConfigDescriptor;
+extern USB_STR_DESCRIPTOR USB_StringDescriptor;
+
+extern const uint8_t HID_KeyboardReportDescriptor[];
+extern const uint8_t HID_MouseReportDescriptor[];
+extern const uint8_t HID_GenericReportDescriptor[];
+
+#endif /* CFG_USB */
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/core/usb/romdriver/error.h b/reform2-lpc-fw/src/core/usb/romdriver/error.h
new file mode 100644
index 0000000000000000000000000000000000000000..5969da22c9b24019abc15037847d3c46a9c77f76
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/romdriver/error.h
@@ -0,0 +1,148 @@
+/***********************************************************************
+* $Id:: error.h 228 2011-07-15 18:58:20Z usb06052               $
+*
+* Project: LPC chip software
+*
+* Description:
+*     This file contains unified error codes to be used across driver,
+* middleware, applications, hal and demo software. 
+*
+* Notes:
+*
+***********************************************************************
+* Software that is described herein is for illustrative purposes only
+* which provides customers with programming information regarding the
+* products. This software is supplied "AS IS" without any warranties.
+* NXP Semiconductors assumes no responsibility or liability for the
+* use of the software, conveys no license or title under any patent,
+* copyright, or mask work right to the product. NXP Semiconductors
+* reserves the right to make changes in the software without
+* notification. NXP Semiconductors also make no representation or
+* warranty that such application will be suitable for the specified
+* use without further testing or modification.
+**********************************************************************/
+#ifndef __LPC_ERROR_H__
+#define __LPC_ERROR_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \file
+ *  \brief Error code returned by Boot ROM drivers/library functions.
+ *  \ingroup Common
+ *
+ *  This file contains unified error codes to be used across driver,
+ *  middleware, applications, hal and demo software.
+ *
+ */
+
+/** Error code returned by Boot ROM drivers/library functions 
+* 
+*  Error codes are a 32-bit value with :
+*      - The 16 MSB contains the peripheral code number
+*      - The 16 LSB contains an error code number associated to that peripheral
+*   
+*/
+
+typedef enum
+{
+  /**\b 0x00000000*/ LPC_OK=0, /**< enum value returned on Success */
+  /**\b 0xFFFFFFFF*/ ERR_FAILED = -1, /**< enum value returned on general failure */
+  
+  /* ISP related errors */
+  ERR_ISP_BASE = 0x00000000,
+  /*0x00000001*/ ERR_ISP_INVALID_COMMAND = ERR_ISP_BASE + 1,
+  /*0x00000002*/ ERR_ISP_SRC_ADDR_ERROR, /* Source address not on word boundary */
+  /*0x00000003*/ ERR_ISP_DST_ADDR_ERROR, /* Destination address not on word or 256 byte boundary */
+  /*0x00000004*/ ERR_ISP_SRC_ADDR_NOT_MAPPED,
+  /*0x00000005*/ ERR_ISP_DST_ADDR_NOT_MAPPED,
+  /*0x00000006*/ ERR_ISP_COUNT_ERROR, /* Byte count is not multiple of 4 or is not a permitted value */
+  /*0x00000007*/ ERR_ISP_INVALID_SECTOR,
+  /*0x00000008*/ ERR_ISP_SECTOR_NOT_BLANK,
+  /*0x00000009*/ ERR_ISP_SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION,
+  /*0x0000000A*/ ERR_ISP_COMPARE_ERROR,
+  /*0x0000000B*/ ERR_ISP_BUSY, /* Flash programming hardware interface is busy */
+  /*0x0000000C*/ ERR_ISP_PARAM_ERROR, /* Insufficient number of parameters */
+  /*0x0000000D*/ ERR_ISP_ADDR_ERROR, /* Address not on word boundary */
+  /*0x0000000E*/ ERR_ISP_ADDR_NOT_MAPPED,
+  /*0x0000000F*/ ERR_ISP_CMD_LOCKED, /* Command is locked */
+  /*0x00000010*/ ERR_ISP_INVALID_CODE, /* Unlock code is invalid */
+  /*0x00000011*/ ERR_ISP_INVALID_BAUD_RATE,
+  /*0x00000012*/ ERR_ISP_INVALID_STOP_BIT,
+  /*0x00000013*/ ERR_ISP_CODE_READ_PROTECTION_ENABLED,
+
+  /* ROM API related errors */
+  ERR_API_BASE = 0x00010000,
+  /**\b 0x00010001*/ ERR_API_INVALID_PARAMS = ERR_API_BASE + 1, /**< Invalid parameters*/
+  /**\b 0x00010002*/ ERR_API_INVALID_PARAM1, /**< PARAM1 is invalid */
+  /**\b 0x00010003*/ ERR_API_INVALID_PARAM2, /**< PARAM2 is invalid */
+  /**\b 0x00010004*/ ERR_API_INVALID_PARAM3, /**< PARAM3 is invalid */
+  /**\b 0x00010005*/ ERR_API_MOD_INIT, /**< API is called before module init */
+
+  /* SPIFI API related errors */
+  ERR_SPIFI_BASE = 0x00020000,
+  /*0x00020001*/ ERR_SPIFI_DEVICE_ERROR =ERR_SPIFI_BASE+1,  
+  /*0x00020002*/ ERR_SPIFI_INTERNAL_ERROR,		    
+  /*0x00020003*/ ERR_SPIFI_TIMEOUT,			    
+  /*0x00020004*/ ERR_SPIFI_OPERAND_ERROR,		    
+  /*0x00020005*/ ERR_SPIFI_STATUS_PROBLEM,		    
+  /*0x00020006*/ ERR_SPIFI_UNKNOWN_EXT, 		    
+  /*0x00020007*/ ERR_SPIFI_UNKNOWN_ID,  		    
+  /*0x00020008*/ ERR_SPIFI_UNKNOWN_TYPE,		    
+  /*0x00020009*/ ERR_SPIFI_UNKNOWN_MFG, 		    
+
+  /* Security API related errors */
+  ERR_SEC_BASE = 0x00030000,
+  /*0x00030001*/	ERR_SEC_AES_WRONG_CMD=ERR_SEC_BASE+1,
+  /*0x00030002*/	ERR_SEC_AES_NOT_SUPPORTED,
+  /*0x00030003*/	ERR_SEC_AES_KEY_ALREADY_PROGRAMMED,
+  
+
+  /* USB device stack related errors */
+  ERR_USBD_BASE = 0x00040000,
+  /**\b 0x00040001*/ ERR_USBD_INVALID_REQ = ERR_USBD_BASE + 1, /**< invalid request */
+  /**\b 0x00040002*/ ERR_USBD_UNHANDLED, /**< Callback did not process the event */
+  /**\b 0x00040003*/ ERR_USBD_STALL,     /**< Stall the endpoint on which the call back is called */
+  /**\b 0x00040004*/ ERR_USBD_SEND_ZLP,  /**< Send ZLP packet on the endpoint on which the call back is called */
+  /**\b 0x00040005*/ ERR_USBD_SEND_DATA, /**< Send data packet on the endpoint on which the call back is called */
+  /**\b 0x00040006*/ ERR_USBD_BAD_DESC,  /**< Bad descriptor*/
+  /**\b 0x00040007*/ ERR_USBD_BAD_CFG_DESC,/**< Bad config descriptor*/
+  /**\b 0x00040009*/ ERR_USBD_BAD_INTF_DESC,/**< Bad interface descriptor*/
+  /**\b 0x0004000a*/ ERR_USBD_BAD_EP_DESC,/**< Bad endpoint descriptor*/
+  /**\b 0x0004000b*/ ERR_USBD_BAD_MEM_BUF, /**< Bad alignment of buffer passed. */
+  /**\b 0x0004000c*/ ERR_USBD_TOO_MANY_CLASS_HDLR, /**< Too many class handlers. */
+
+  /* CGU  related errors */
+  ERR_CGU_BASE = 0x00050000,
+  /*0x00050001*/ ERR_CGU_NOT_IMPL=ERR_CGU_BASE+1,
+  /*0x00050002*/ ERR_CGU_INVALID_PARAM,
+  /*0x00050003*/ ERR_CGU_INVALID_SLICE,
+  /*0x00050004*/ ERR_CGU_OUTPUT_GEN,
+  /*0x00050005*/ ERR_CGU_DIV_SRC,
+  /*0x00050006*/ ERR_CGU_DIV_VAL,
+  /*0x00050007*/ ERR_CGU_SRC, 
+
+  /*  I2C related errors   */
+  ERR_I2C_BASE = 0x00060000,
+/*0x00060001*/	 ERR_I2C_NAK=ERR_I2C_BASE+1,
+/*0x00060002*/	 ERR_I2C_BUFFER_OVERFLOW,    
+/*0x00060003*/	 ERR_I2C_BYTE_COUNT_ERR,     
+/*0x00060004*/	 ERR_I2C_LOSS_OF_ARBRITRATION,    
+/*0x00060005*/	 ERR_I2C_SLAVE_NOT_ADDRESSED,     
+/*0x00060006*/	 ERR_I2C_LOSS_OF_ARBRITRATION_NAK_BIT,   
+/*0x00060007*/	 ERR_I2C_GENERAL_FAILURE,         
+/*0x00060008*/	 ERR_I2C_REGS_SET_TO_DEFAULT
+
+} ErrorCode_t;
+
+
+// KT: This conflicts with offsetof in stddef.h with newlib!
+// #define offsetof(s,m)   (int)&(((s *)0)->m)
+#define COMPILE_TIME_ASSERT(pred)    switch(0){case 0:case pred:;}
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif /* __LPC_ERROR_H__ */
diff --git a/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd.h b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd.h
new file mode 100644
index 0000000000000000000000000000000000000000..ad97fa0ae627ce396f994b4c3c2ab218b25aeabb
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd.h
@@ -0,0 +1,659 @@
+/***********************************************************************
+* $Id:: mw_usbd.h 197 2011-06-12 20:22:41Z usb06052                           $
+*
+* Project: USB device ROM Stack
+*
+* Description:
+*     USB Definitions.
+*
+***********************************************************************
+*   Copyright(C) 2011, NXP Semiconductor
+*   All rights reserved.
+*
+* Software that is described herein is for illustrative purposes only
+* which provides customers with programming information regarding the
+* products. This software is supplied "AS IS" without any warranties.
+* NXP Semiconductors assumes no responsibility or liability for the
+* use of the software, conveys no license or title under any patent,
+* copyright, or mask work right to the product. NXP Semiconductors
+* reserves the right to make changes in the software without
+* notification. NXP Semiconductors also make no representation or
+* warranty that such application will be suitable for the specified
+* use without further testing or modification.
+**********************************************************************/
+#ifndef __USB_H__
+#define __USB_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \file
+ *  \brief Common definitions and declarations for the USB stack.
+ *
+ *  Common definitions and declarations for the USB stack.
+ *  \addtogroup USBD_Core 
+ *  @{
+ */
+
+#include <stdint.h>
+
+#if defined(__GNUC__)
+/* As per http://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html#Attribute-Syntax,
+6.29 Attributes Syntax
+"An attribute specifier list may appear as part of a struct, union or
+enum specifier. It may go either immediately after the struct, union
+or enum keyword, or after the closing brace. The former syntax is
+preferred. Where attribute specifiers follow the closing brace, they
+are considered to relate to the structure, union or enumerated type
+defined, not to any enclosing declaration the type specifier appears
+in, and the type defined is not complete until after the attribute
+specifiers."
+So use POST_PACK immediately after struct keyword
+*/
+#define PRE_PACK
+#define POST_PACK	__attribute__((__packed__))
+#define ALIGNED(n)  __attribute__((aligned (n)))
+#elif defined(__arm)
+#define PRE_PACK	__packed
+#define POST_PACK
+#define ALIGNED(n)  __align(n)
+#endif
+
+/** Structure to pack lower and upper byte to form 16 bit word. */
+PRE_PACK struct POST_PACK _WB_T
+{
+  uint8_t L; /**< lower byte */
+  uint8_t H; /**< upper byte */
+};
+/** Structure to pack lower and upper byte to form 16 bit word.*/
+typedef struct _WB_T WB_T;
+
+/** Union of \ref _WB_T struct and 16 bit word.*/
+PRE_PACK union POST_PACK __WORD_BYTE
+{
+  uint16_t W; /**< data member to do 16 bit access */
+  WB_T WB; /**< data member to do 8 bit access */
+} ;
+/** Union of \ref _WB_T struct and 16 bit word.*/
+typedef union __WORD_BYTE WORD_BYTE;
+
+/** bmRequestType.Dir defines 
+ * @{ 
+ */
+/** Request from host to device */
+#define REQUEST_HOST_TO_DEVICE     0
+/** Request from device to host */
+#define REQUEST_DEVICE_TO_HOST     1
+/** @} */
+
+/** bmRequestType.Type defines  
+ * @{ 
+ */
+/** Standard Request */
+#define REQUEST_STANDARD           0
+/** Class Request */
+#define REQUEST_CLASS              1
+/** Vendor Request */
+#define REQUEST_VENDOR             2
+/** Reserved Request */
+#define REQUEST_RESERVED           3
+/** @} */
+
+/** bmRequestType.Recipient defines  
+ * @{ 
+ */
+/** Request to device */
+#define REQUEST_TO_DEVICE          0
+/** Request to interface */
+#define REQUEST_TO_INTERFACE       1
+/** Request to endpoint */
+#define REQUEST_TO_ENDPOINT        2
+/** Request to other */
+#define REQUEST_TO_OTHER           3
+/** @} */
+
+/** Structure to define 8 bit USB request.*/
+PRE_PACK struct POST_PACK _BM_T
+{
+  uint8_t Recipient :  5; /**< Recipeint type. */
+  uint8_t Type      :  2; /**< Request type.  */
+  uint8_t Dir       :  1; /**< Directtion type. */
+};
+/** Structure to define 8 bit USB request.*/
+typedef struct _BM_T BM_T;
+
+/** Union of \ref _BM_T struct and 8 bit byte.*/
+PRE_PACK union POST_PACK _REQUEST_TYPE
+{
+  uint8_t B; /**< byte wide access memeber */
+  BM_T BM;   /**< bitfield structure access memeber */
+} ;
+/** Union of \ref _BM_T struct and 8 bit byte.*/
+typedef union _REQUEST_TYPE REQUEST_TYPE;
+
+/** USB Standard Request Codes 
+ * @{ 
+ */
+/** GET_STATUS request */
+#define USB_REQUEST_GET_STATUS                 0
+/** CLEAR_FEATURE request */
+#define USB_REQUEST_CLEAR_FEATURE              1
+/** SET_FEATURE request */
+#define USB_REQUEST_SET_FEATURE                3
+/** SET_ADDRESS request */
+#define USB_REQUEST_SET_ADDRESS                5
+/** GET_DESCRIPTOR request */
+#define USB_REQUEST_GET_DESCRIPTOR             6
+/** SET_DESCRIPTOR request */
+#define USB_REQUEST_SET_DESCRIPTOR             7
+/** GET_CONFIGURATION request */
+#define USB_REQUEST_GET_CONFIGURATION          8
+/** SET_CONFIGURATION request */
+#define USB_REQUEST_SET_CONFIGURATION          9
+/** GET_INTERFACE request */
+#define USB_REQUEST_GET_INTERFACE              10
+/** SET_INTERFACE request */
+#define USB_REQUEST_SET_INTERFACE              11
+/** SYNC_FRAME request */
+#define USB_REQUEST_SYNC_FRAME                 12
+/** @} */
+
+/** USB GET_STATUS Bit Values 
+ * @{ 
+ */
+/** SELF_POWERED status*/
+#define USB_GETSTATUS_SELF_POWERED             0x01
+/** REMOTE_WAKEUP capable status*/
+#define USB_GETSTATUS_REMOTE_WAKEUP            0x02
+/** ENDPOINT_STALL status*/
+#define USB_GETSTATUS_ENDPOINT_STALL           0x01
+/** @} */
+
+/** USB Standard Feature selectors 
+ * @{ 
+ */
+/** ENDPOINT_STALL feature*/
+#define USB_FEATURE_ENDPOINT_STALL             0
+/** REMOTE_WAKEUP feature*/
+#define USB_FEATURE_REMOTE_WAKEUP              1
+/** TEST_MODE feature*/
+#define USB_FEATURE_TEST_MODE                  2
+/** @} */
+
+/** USB Default Control Pipe Setup Packet*/
+PRE_PACK struct POST_PACK _USB_SETUP_PACKET
+{
+  REQUEST_TYPE bmRequestType; /**< This bitmapped field identifies the characteristics
+                              of the specific request. \sa _BM_T.
+                              */
+  uint8_t      bRequest; /**< This field specifies the particular request. The 
+                         Type bits in the bmRequestType field modify the meaning 
+                         of this field. \sa USBD_REQUEST.
+                         */
+  WORD_BYTE    wValue; /**< Used to pass a parameter to the device, specific
+                        to the request.
+                        */
+  WORD_BYTE    wIndex; /**< Used to pass a parameter to the device, specific
+                        to the request. The wIndex field is often used in 
+                        requests to specify an endpoint or an interface.
+                        */
+  uint16_t     wLength; /**< This field specifies the length of the data 
+                        transferred during the second phase of the control 
+                        transfer.
+                        */
+} ;
+/** USB Default Control Pipe Setup Packet*/
+typedef struct _USB_SETUP_PACKET USB_SETUP_PACKET;
+
+
+/** USB Descriptor Types 
+ * @{ 
+ */
+/** Device descriptor type  */
+#define USB_DEVICE_DESCRIPTOR_TYPE             1
+/** Configuration descriptor type  */
+#define USB_CONFIGURATION_DESCRIPTOR_TYPE      2
+/** String descriptor type  */
+#define USB_STRING_DESCRIPTOR_TYPE             3
+/** Interface descriptor type  */
+#define USB_INTERFACE_DESCRIPTOR_TYPE          4
+/** Endpoint descriptor type  */
+#define USB_ENDPOINT_DESCRIPTOR_TYPE           5
+/** Device qualifier descriptor type  */
+#define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE   6
+/** Other speed configuration descriptor type  */
+#define USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE 7
+/** Interface power descriptor type  */
+#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE    8
+/** OTG descriptor type  */
+#define USB_OTG_DESCRIPTOR_TYPE                     9
+/** Debug descriptor type  */
+#define USB_DEBUG_DESCRIPTOR_TYPE                  10
+/** Interface association descriptor type  */
+#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE  11
+/** @} */
+
+/** USB Device Classes 
+ * @{ 
+ */
+/** Reserved device class  */
+#define USB_DEVICE_CLASS_RESERVED              0x00
+/** Audio device class  */
+#define USB_DEVICE_CLASS_AUDIO                 0x01
+/** Communications device class  */
+#define USB_DEVICE_CLASS_COMMUNICATIONS        0x02
+/** Human interface device class  */
+#define USB_DEVICE_CLASS_HUMAN_INTERFACE       0x03
+/** monitor device class  */
+#define USB_DEVICE_CLASS_MONITOR               0x04
+/** physical interface device class  */
+#define USB_DEVICE_CLASS_PHYSICAL_INTERFACE    0x05
+/** power device class  */
+#define USB_DEVICE_CLASS_POWER                 0x06
+/** Printer device class  */
+#define USB_DEVICE_CLASS_PRINTER               0x07
+/** Storage device class  */
+#define USB_DEVICE_CLASS_STORAGE               0x08
+/** Hub device class  */
+#define USB_DEVICE_CLASS_HUB                   0x09
+/** miscellaneous device class  */
+#define USB_DEVICE_CLASS_MISCELLANEOUS         0xEF
+/** Application device class  */
+#define USB_DEVICE_CLASS_APP                   0xFE
+/** Vendor specific device class  */
+#define USB_DEVICE_CLASS_VENDOR_SPECIFIC       0xFF
+/** @} */
+
+/** bmAttributes in Configuration Descriptor 
+ * @{ 
+ */
+/** Power field mask */
+#define USB_CONFIG_POWERED_MASK                0x40
+/** Bus powered */
+#define USB_CONFIG_BUS_POWERED                 0x80
+/** Self powered */
+#define USB_CONFIG_SELF_POWERED                0xC0
+/** remote wakeup */
+#define USB_CONFIG_REMOTE_WAKEUP               0x20
+/** @} */
+
+/** bMaxPower in Configuration Descriptor */
+#define USB_CONFIG_POWER_MA(mA)                ((mA)/2)
+
+/** bEndpointAddress in Endpoint Descriptor 
+ * @{ 
+ */
+/** Endopint address mask */
+#define USB_ENDPOINT_DIRECTION_MASK            0x80
+/** Macro to convert OUT endopint number to endpoint address value. */
+#define USB_ENDPOINT_OUT(addr)                 ((addr) | 0x00)
+/** Macro to convert IN endopint number to endpoint address value. */
+#define USB_ENDPOINT_IN(addr)                  ((addr) | 0x80)
+/** @} */
+
+/** bmAttributes in Endpoint Descriptor 
+ * @{ 
+ */
+/** Endopint type mask */
+#define USB_ENDPOINT_TYPE_MASK                 0x03
+/** Control Endopint type */
+#define USB_ENDPOINT_TYPE_CONTROL              0x00
+/** isochronous Endopint type */
+#define USB_ENDPOINT_TYPE_ISOCHRONOUS          0x01
+/** bulk Endopint type */
+#define USB_ENDPOINT_TYPE_BULK                 0x02
+/** interrupt Endopint type */
+#define USB_ENDPOINT_TYPE_INTERRUPT            0x03
+/** Endopint sync type mask */
+#define USB_ENDPOINT_SYNC_MASK                 0x0C
+/** no synchronization Endopint */
+#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION   0x00
+/** Asynchronous sync Endopint */
+#define USB_ENDPOINT_SYNC_ASYNCHRONOUS         0x04
+/** Adaptive sync Endopint */
+#define USB_ENDPOINT_SYNC_ADAPTIVE             0x08
+/** Synchronous sync Endopint */
+#define USB_ENDPOINT_SYNC_SYNCHRONOUS          0x0C
+/** Endopint usage type mask */
+#define USB_ENDPOINT_USAGE_MASK                0x30
+/** Endopint data usage type  */
+#define USB_ENDPOINT_USAGE_DATA                0x00
+/** Endopint feedback usage type  */
+#define USB_ENDPOINT_USAGE_FEEDBACK            0x10
+/** Endopint implicit feedback usage type  */
+#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK   0x20
+/** Endopint reserved usage type  */
+#define USB_ENDPOINT_USAGE_RESERVED            0x30
+/** @} */
+
+/** Control endopint EP0's maximum packet size in high-speed mode.*/
+#define USB_ENDPOINT_0_HS_MAXP                 64
+/** Control endopint EP0's maximum packet size in low-speed mode.*/
+#define USB_ENDPOINT_0_LS_MAXP                 8
+/** Bulk endopint's maximum packet size in high-speed mode.*/
+#define USB_ENDPOINT_BULK_HS_MAXP              512
+
+/** USB Standard Device Descriptor */
+PRE_PACK struct POST_PACK _USB_DEVICE_DESCRIPTOR
+{
+  uint8_t  bLength;     /**< Size of this descriptor in bytes. */
+  uint8_t  bDescriptorType; /**< DEVICE Descriptor Type. */
+  uint16_t bcdUSB; /**< BUSB Specification Release Number in
+                    Binary-Coded Decimal (i.e., 2.10 is 210H).
+                    This field identifies the release of the USB
+                    Specification with which the device and its
+                    descriptors are compliant.
+                   */
+  uint8_t  bDeviceClass; /**< Class code (assigned by the USB-IF).
+                          If this field is reset to zero, each interface
+                          within a configuration specifies its own
+                          class information and the various
+                          interfaces operate independently.\n
+                          If this field is set to a value between 1 and
+                          FEH, the device supports different class
+                          specifications on different interfaces and
+                          the interfaces may not operate
+                          independently. This value identifies the
+                          class definition used for the aggregate
+                          interfaces. \n
+                          If this field is set to FFH, the device class
+                          is vendor-specific.
+                          */
+  uint8_t  bDeviceSubClass; /**< Subclass code (assigned by the USB-IF).
+                            These codes are qualified by the value of
+                            the bDeviceClass field. \n
+                            If the bDeviceClass field is reset to zero,
+                            this field must also be reset to zero. \n
+                            If the bDeviceClass field is not set to FFH,
+                            all values are reserved for assignment by
+                            the USB-IF. 
+                            */
+  uint8_t  bDeviceProtocol; /**< Protocol code (assigned by the USB-IF).
+                            These codes are qualified by the value of
+                            the bDeviceClass and the
+                            bDeviceSubClass fields. If a device
+                            supports class-specific protocols on a
+                            device basis as opposed to an interface
+                            basis, this code identifies the protocols
+                            that the device uses as defined by the
+                            specification of the device class. \n
+                            If this field is reset to zero, the device
+                            does not use class-specific protocols on a
+                            device basis. However, it may use classspecific
+                            protocols on an interface basis. \n
+                            If this field is set to FFH, the device uses a
+                            vendor-specific protocol on a device basis. 
+                            */
+  uint8_t  bMaxPacketSize0; /**< Maximum packet size for endpoint zero
+                            (only 8, 16, 32, or 64 are valid). For HS devices
+                            is fixed to 64.
+                            */
+
+  uint16_t idVendor; /**< Vendor ID (assigned by the USB-IF). */
+  uint16_t idProduct; /**< Product ID (assigned by the manufacturer). */
+  uint16_t bcdDevice; /**< Device release number in binary-coded decimal. */
+  uint8_t  iManufacturer; /**< Index of string descriptor describing manufacturer. */
+  uint8_t  iProduct; /**< Index of string descriptor describing product. */
+  uint8_t  iSerialNumber; /**< Index of string descriptor describing the device�s 
+                          serial number.
+                          */
+  uint8_t  bNumConfigurations; /**< Number of possible configurations. */
+} ;
+/** USB Standard Device Descriptor */
+typedef struct _USB_DEVICE_DESCRIPTOR USB_DEVICE_DESCRIPTOR;
+
+/** USB 2.0 Device Qualifier Descriptor */
+PRE_PACK struct POST_PACK _USB_DEVICE_QUALIFIER_DESCRIPTOR
+{
+  uint8_t  bLength; /**< Size of descriptor */
+  uint8_t  bDescriptorType; /**< Device Qualifier Type */
+  uint16_t bcdUSB; /**< USB specification version number (e.g., 0200H for V2.00) */
+  uint8_t  bDeviceClass; /**< Class Code */
+  uint8_t  bDeviceSubClass; /**< SubClass Code */
+  uint8_t  bDeviceProtocol; /**< Protocol Code */
+  uint8_t  bMaxPacketSize0; /**< Maximum packet size for other speed */
+  uint8_t  bNumConfigurations; /**< Number of Other-speed Configurations */
+  uint8_t  bReserved; /**< Reserved for future use, must be zero */
+} ;
+/** USB 2.0 Device Qualifier Descriptor */
+typedef struct _USB_DEVICE_QUALIFIER_DESCRIPTOR USB_DEVICE_QUALIFIER_DESCRIPTOR;
+
+/** USB Standard Configuration Descriptor */
+PRE_PACK struct POST_PACK _USB_CONFIGURATION_DESCRIPTOR
+{
+  uint8_t  bLength; /**< Size of this descriptor in bytes */
+  uint8_t  bDescriptorType; /**< CONFIGURATION Descriptor Type*/
+  uint16_t wTotalLength; /**< Total length of data returned for this
+                          configuration. Includes the combined length
+                          of all descriptors (configuration, interface,
+                          endpoint, and class- or vendor-specific)
+                          returned for this configuration.*/
+  uint8_t  bNumInterfaces; /**< Number of interfaces supported by this configuration*/
+  uint8_t  bConfigurationValue; /**< Value to use as an argument to the
+                                SetConfiguration() request to select this 
+                                configuration. */
+  uint8_t  iConfiguration; /**< Index of string descriptor describing this
+                            configuration*/
+  uint8_t  bmAttributes; /**< Configuration characteristics \n
+                          D7: Reserved (set to one)\n
+                          D6: Self-powered \n
+                          D5: Remote Wakeup \n
+                          D4...0: Reserved (reset to zero) \n
+                          D7 is reserved and must be set to one for
+                          historical reasons. \n
+                          A device configuration that uses power from
+                          the bus and a local source reports a non-zero
+                          value in bMaxPower to indicate the amount of
+                          bus power required and sets D6. The actual
+                          power source at runtime may be determined
+                          using the GetStatus(DEVICE) request (see
+                          USB 2.0 spec Section 9.4.5). \n
+                          If a device configuration supports remote
+                          wakeup, D5 is set to one.*/
+  uint8_t  bMaxPower; /**< Maximum power consumption of the USB
+                      device from the bus in this specific
+                      configuration when the device is fully
+                      operational. Expressed in 2 mA units
+                      (i.e., 50 = 100 mA). \n
+                      Note: A device configuration reports whether
+                      the configuration is bus-powered or selfpowered.
+                      Device status reports whether the
+                      device is currently self-powered. If a device is
+                      disconnected from its external power source, it
+                      updates device status to indicate that it is no
+                      longer self-powered. \n
+                      A device may not increase its power draw
+                      from the bus, when it loses its external power
+                      source, beyond the amount reported by its
+                      configuration. \n
+                      If a device can continue to operate when
+                      disconnected from its external power source, it
+                      continues to do so. If the device cannot
+                      continue to operate, it fails operations it can
+                      no longer support. The USB System Software
+                      may determine the cause of the failure by
+                      checking the status and noting the loss of the
+                      device�s power source.*/
+} ;
+/** USB Standard Configuration Descriptor */
+typedef struct _USB_CONFIGURATION_DESCRIPTOR USB_CONFIGURATION_DESCRIPTOR;
+
+/** USB Standard Interface Descriptor */
+PRE_PACK struct POST_PACK _USB_INTERFACE_DESCRIPTOR
+{
+  uint8_t  bLength; /**< Size of this descriptor in bytes*/
+  uint8_t  bDescriptorType; /**< INTERFACE Descriptor Type*/
+  uint8_t  bInterfaceNumber; /**< Number of this interface. Zero-based
+                              value identifying the index in the array of
+                              concurrent interfaces supported by this
+                              configuration.*/
+  uint8_t  bAlternateSetting; /**< Value used to select this alternate setting
+                              for the interface identified in the prior field*/
+  uint8_t  bNumEndpoints; /**< Number of endpoints used by this
+                          interface (excluding endpoint zero). If this
+                          value is zero, this interface only uses the
+                          Default Control Pipe.*/
+  uint8_t  bInterfaceClass; /**< Class code (assigned by the USB-IF). \n
+                            A value of zero is reserved for future
+                            standardization. \n
+                            If this field is set to FFH, the interface
+                            class is vendor-specific. \n
+                            All other values are reserved for
+                            assignment by the USB-IF.*/
+  uint8_t  bInterfaceSubClass; /**< Subclass code (assigned by the USB-IF). \n
+                              These codes are qualified by the value of
+                              the bInterfaceClass field. \n
+                              If the bInterfaceClass field is reset to zero,
+                              this field must also be reset to zero. \n
+                              If the bInterfaceClass field is not set to
+                              FFH, all values are reserved for
+                              assignment by the USB-IF.*/
+  uint8_t  bInterfaceProtocol; /**< Protocol code (assigned by the USB). \n
+                                These codes are qualified by the value of
+                                the bInterfaceClass and the
+                                bInterfaceSubClass fields. If an interface
+                                supports class-specific requests, this code
+                                identifies the protocols that the device
+                                uses as defined by the specification of the
+                                device class. \n
+                                If this field is reset to zero, the device
+                                does not use a class-specific protocol on
+                                this interface. \n
+                                If this field is set to FFH, the device uses
+                                a vendor-specific protocol for this
+                                interface.*/
+  uint8_t  iInterface; /**< Index of string descriptor describing this interface*/
+} ;
+/** USB Standard Interface Descriptor */
+typedef struct _USB_INTERFACE_DESCRIPTOR USB_INTERFACE_DESCRIPTOR;
+
+/** USB Standard Endpoint Descriptor */
+PRE_PACK struct POST_PACK _USB_ENDPOINT_DESCRIPTOR
+{
+  uint8_t  bLength; /**< Size of this descriptor in bytes*/
+  uint8_t  bDescriptorType; /**< ENDPOINT Descriptor Type*/
+  uint8_t  bEndpointAddress; /**< The address of the endpoint on the USB device
+                            described by this descriptor. The address is
+                            encoded as follows: \n
+                            Bit 3...0: The endpoint number \n
+                            Bit 6...4: Reserved, reset to zero \n
+                            Bit 7: Direction, ignored for control endpoints
+                            0 = OUT endpoint
+                            1 = IN endpoint.  \n \sa USBD_ENDPOINT_ADR_Type*/
+  uint8_t  bmAttributes; /**< This field describes the endpoint�s attributes when it is
+                          configured using the bConfigurationValue. \n
+                          Bits 1..0: Transfer Type
+                          \li 00 = Control
+                          \li 01 = Isochronous
+                          \li 10 = Bulk
+                          \li 11 = Interrupt  \n
+                          If not an isochronous endpoint, bits 5..2 are reserved
+                          and must be set to zero. If isochronous, they are
+                          defined as follows: \n
+                          Bits 3..2: Synchronization Type
+                          \li 00 = No Synchronization
+                          \li 01 = Asynchronous
+                          \li 10 = Adaptive
+                          \li 11 = Synchronous \n
+                          Bits 5..4: Usage Type
+                          \li 00 = Data endpoint
+                          \li 01 = Feedback endpoint
+                          \li 10 = Implicit feedback Data endpoint
+                          \li 11 = Reserved \n
+                          Refer to Chapter 5 of USB 2.0 specification for more information. \n
+                          All other bits are reserved and must be reset to zero.
+                          Reserved bits must be ignored by the host.
+                         \n \sa USBD_EP_ATTR_Type*/
+  uint16_t wMaxPacketSize; /**< Maximum packet size this endpoint is capable of
+                          sending or receiving when this configuration is
+                          selected. \n
+                          For isochronous endpoints, this value is used to
+                          reserve the bus time in the schedule, required for the
+                          per-(micro)frame data payloads. The pipe may, on an
+                          ongoing basis, actually use less bandwidth than that
+                          reserved. The device reports, if necessary, the actual
+                          bandwidth used via its normal, non-USB defined
+                          mechanisms. \n
+                          For all endpoints, bits 10..0 specify the maximum
+                          packet size (in bytes). \n
+                          For high-speed isochronous and interrupt endpoints: \n
+                          Bits 12..11 specify the number of additional transaction
+                          opportunities per microframe: \n
+                          \li 00 = None (1 transaction per microframe)
+                          \li 01 = 1 additional (2 per microframe)
+                          \li 10 = 2 additional (3 per microframe)
+                          \li 11 = Reserved \n
+                          Bits 15..13 are reserved and must be set to zero.*/
+  uint8_t  bInterval; /**< Interval for polling endpoint for data transfers.
+                      Expressed in frames or microframes depending on the
+                      device operating speed (i.e., either 1 millisecond or
+                      125 �s units). 
+                      \li For full-/high-speed isochronous endpoints, this value
+                      must be in the range from 1 to 16. The bInterval value
+                      is used as the exponent for a \f$ 2^(bInterval-1) \f$ value; e.g., a
+                      bInterval of 4 means a period of 8 (\f$ 2^(4-1) \f$). 
+                      \li For full-/low-speed interrupt endpoints, the value of
+                      this field may be from 1 to 255.
+                      \li For high-speed interrupt endpoints, the bInterval value
+                      is used as the exponent for a \f$ 2^(bInterval-1) \f$ value; e.g., a
+                      bInterval of 4 means a period of 8 (\f$ 2^(4-1) \f$) . This value
+                      must be from 1 to 16.
+                      \li For high-speed bulk/control OUT endpoints, the
+                      bInterval must specify the maximum NAK rate of the
+                      endpoint. A value of 0 indicates the endpoint never
+                      NAKs. Other values indicate at most 1 NAK each
+                      bInterval number of microframes. This value must be
+                      in the range from 0 to 255. \n
+                      Refer to Chapter 5 of USB 2.0 specification for more information.
+                      */
+} ;
+/** USB Standard Endpoint Descriptor */
+typedef struct _USB_ENDPOINT_DESCRIPTOR USB_ENDPOINT_DESCRIPTOR;
+
+/** USB String Descriptor */
+PRE_PACK struct POST_PACK _USB_STRING_DESCRIPTOR
+{
+  uint8_t  bLength; /**< Size of this descriptor in bytes*/
+  uint8_t  bDescriptorType; /**< STRING Descriptor Type*/
+  uint16_t bString/*[]*/; /**< UNICODE encoded string */
+}  ;
+/** USB String Descriptor */
+typedef struct _USB_STRING_DESCRIPTOR USB_STRING_DESCRIPTOR;
+
+/** USB Common Descriptor */
+PRE_PACK struct POST_PACK _USB_COMMON_DESCRIPTOR
+{
+  uint8_t  bLength; /**< Size of this descriptor in bytes*/
+  uint8_t  bDescriptorType; /**< Descriptor Type*/
+} ;
+/** USB Common Descriptor */
+typedef struct _USB_COMMON_DESCRIPTOR USB_COMMON_DESCRIPTOR;
+
+/** USB Other Speed Configuration */
+PRE_PACK struct POST_PACK _USB_OTHER_SPEED_CONFIGURATION
+{
+  uint8_t  bLength; /**< Size of descriptor*/
+  uint8_t  bDescriptorType; /**< Other_speed_Configuration Type*/
+  uint16_t wTotalLength; /**< Total length of data returned*/
+  uint8_t  bNumInterfaces; /**< Number of interfaces supported by this speed configuration*/
+  uint8_t  bConfigurationValue; /**< Value to use to select configuration*/
+  uint8_t  IConfiguration; /**< Index of string descriptor*/
+  uint8_t  bmAttributes; /**< Same as Configuration descriptor*/
+  uint8_t  bMaxPower; /**< Same as Configuration descriptor*/
+} ;
+/** USB Other Speed Configuration */
+typedef struct _USB_OTHER_SPEED_CONFIGURATION USB_OTHER_SPEED_CONFIGURATION;
+
+/** \ingroup USBD_Core 
+ * USB device stack/module handle. 
+ */
+typedef void* USBD_HANDLE_T;
+
+/** @}*/
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif  /* __USB_H__ */
diff --git a/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_adcuser.h b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_adcuser.h
new file mode 100644
index 0000000000000000000000000000000000000000..b7a81ca97d141fc9cef37aa8f364efe43c9579d7
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_adcuser.h
@@ -0,0 +1,38 @@
+/***********************************************************************
+* $Id:: mw_usbd_adcuser.h 165 2011-04-14 17:41:11Z usb10131                   $
+*
+* Project: USB device ROM Stack
+*
+* Description:
+*     USB Audio Device Class Definitions.
+*
+***********************************************************************
+*   Copyright(C) 2011, NXP Semiconductor
+*   All rights reserved.
+*
+* Software that is described herein is for illustrative purposes only
+* which provides customers with programming information regarding the
+* products. This software is supplied "AS IS" without any warranties.
+* NXP Semiconductors assumes no responsibility or liability for the
+* use of the software, conveys no license or title under any patent,
+* copyright, or mask work right to the product. NXP Semiconductors
+* reserves the right to make changes in the software without
+* notification. NXP Semiconductors also make no representation or
+* warranty that such application will be suitable for the specified
+* use without further testing or modification.
+**********************************************************************/
+
+#ifndef __ADCUSER_H__
+#define __ADCUSER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Audio Device Class Requests Callback Functions */
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif  /* __ADCUSER_H__ */
diff --git a/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_audio.h b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_audio.h
new file mode 100644
index 0000000000000000000000000000000000000000..dbd4c37fa6f2e7c8934bcc6ec1000ce2db4139b6
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_audio.h
@@ -0,0 +1,384 @@
+/***********************************************************************
+* $Id:: mw_usbd_audio.h 165 2011-04-14 17:41:11Z usb10131                     $
+*
+* Project: USB device ROM Stack
+*
+* Description:
+*     USB Audio Device Class Definitions.
+*
+***********************************************************************
+*   Copyright(C) 2011, NXP Semiconductor
+*   All rights reserved.
+*
+* Software that is described herein is for illustrative purposes only
+* which provides customers with programming information regarding the
+* products. This software is supplied "AS IS" without any warranties.
+* NXP Semiconductors assumes no responsibility or liability for the
+* use of the software, conveys no license or title under any patent,
+* copyright, or mask work right to the product. NXP Semiconductors
+* reserves the right to make changes in the software without
+* notification. NXP Semiconductors also make no representation or
+* warranty that such application will be suitable for the specified
+* use without further testing or modification.
+**********************************************************************/
+#ifndef __AUDIO_H__
+#define __AUDIO_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Audio Interface Subclass Codes */
+#define AUDIO_SUBCLASS_UNDEFINED                0x00
+#define AUDIO_SUBCLASS_AUDIOCONTROL             0x01
+#define AUDIO_SUBCLASS_AUDIOSTREAMING           0x02
+#define AUDIO_SUBCLASS_MIDISTREAMING            0x03
+
+/* Audio Interface Protocol Codes */
+#define AUDIO_PROTOCOL_UNDEFINED                0x00
+
+
+/* Audio Descriptor Types */
+#define AUDIO_UNDEFINED_DESCRIPTOR_TYPE         0x20
+#define AUDIO_DEVICE_DESCRIPTOR_TYPE            0x21
+#define AUDIO_CONFIGURATION_DESCRIPTOR_TYPE     0x22
+#define AUDIO_STRING_DESCRIPTOR_TYPE            0x23
+#define AUDIO_INTERFACE_DESCRIPTOR_TYPE         0x24
+#define AUDIO_ENDPOINT_DESCRIPTOR_TYPE          0x25
+
+
+/* Audio Control Interface Descriptor Subtypes */
+#define AUDIO_CONTROL_UNDEFINED                 0x00
+#define AUDIO_CONTROL_HEADER                    0x01
+#define AUDIO_CONTROL_INPUT_TERMINAL            0x02
+#define AUDIO_CONTROL_OUTPUT_TERMINAL           0x03
+#define AUDIO_CONTROL_MIXER_UNIT                0x04
+#define AUDIO_CONTROL_SELECTOR_UNIT             0x05
+#define AUDIO_CONTROL_FEATURE_UNIT              0x06
+#define AUDIO_CONTROL_PROCESSING_UNIT           0x07
+#define AUDIO_CONTROL_EXTENSION_UNIT            0x08
+
+/* Audio Streaming Interface Descriptor Subtypes */
+#define AUDIO_STREAMING_UNDEFINED               0x00
+#define AUDIO_STREAMING_GENERAL                 0x01
+#define AUDIO_STREAMING_FORMAT_TYPE             0x02
+#define AUDIO_STREAMING_FORMAT_SPECIFIC         0x03
+
+/* Audio Endpoint Descriptor Subtypes */
+#define AUDIO_ENDPOINT_UNDEFINED                0x00
+#define AUDIO_ENDPOINT_GENERAL                  0x01
+
+
+/* Audio Descriptor Sizes */
+#define AUDIO_CONTROL_INTERFACE_DESC_SZ(n)      0x08+n
+#define AUDIO_STREAMING_INTERFACE_DESC_SIZE     0x07
+#define AUDIO_INPUT_TERMINAL_DESC_SIZE          0x0C
+#define AUDIO_OUTPUT_TERMINAL_DESC_SIZE         0x09
+#define AUDIO_MIXER_UNIT_DESC_SZ(p,n)           0x0A+p+n
+#define AUDIO_SELECTOR_UNIT_DESC_SZ(p)          0x06+p
+#define AUDIO_FEATURE_UNIT_DESC_SZ(ch,n)        0x07+(ch+1)*n
+#define AUDIO_PROCESSING_UNIT_DESC_SZ(p,n,x)    0x0D+p+n+x
+#define AUDIO_EXTENSION_UNIT_DESC_SZ(p,n)       0x0D+p+n
+#define AUDIO_STANDARD_ENDPOINT_DESC_SIZE       0x09
+#define AUDIO_STREAMING_ENDPOINT_DESC_SIZE      0x07
+
+
+/* Audio Processing Unit Process Types */
+#define AUDIO_UNDEFINED_PROCESS                 0x00
+#define AUDIO_UP_DOWN_MIX_PROCESS               0x01
+#define AUDIO_DOLBY_PROLOGIC_PROCESS            0x02
+#define AUDIO_3D_STEREO_PROCESS                 0x03
+#define AUDIO_REVERBERATION_PROCESS             0x04
+#define AUDIO_CHORUS_PROCESS                    0x05
+#define AUDIO_DYN_RANGE_COMP_PROCESS            0x06
+
+
+/* Audio Request Codes */
+#define AUDIO_REQUEST_UNDEFINED                 0x00
+#define AUDIO_REQUEST_SET_CUR                   0x01
+#define AUDIO_REQUEST_GET_CUR                   0x81
+#define AUDIO_REQUEST_SET_MIN                   0x02
+#define AUDIO_REQUEST_GET_MIN                   0x82
+#define AUDIO_REQUEST_SET_MAX                   0x03
+#define AUDIO_REQUEST_GET_MAX                   0x83
+#define AUDIO_REQUEST_SET_RES                   0x04
+#define AUDIO_REQUEST_GET_RES                   0x84
+#define AUDIO_REQUEST_SET_MEM                   0x05
+#define AUDIO_REQUEST_GET_MEM                   0x85
+#define AUDIO_REQUEST_GET_STAT                  0xFF
+
+
+/* Audio Control Selector Codes */
+#define AUDIO_CONTROL_UNDEFINED                 0x00    /* Common Selector */
+
+/*  Terminal Control Selectors */
+#define AUDIO_COPY_PROTECT_CONTROL              0x01
+
+/*  Feature Unit Control Selectors */
+#define AUDIO_MUTE_CONTROL                      0x01
+#define AUDIO_VOLUME_CONTROL                    0x02
+#define AUDIO_BASS_CONTROL                      0x03
+#define AUDIO_MID_CONTROL                       0x04
+#define AUDIO_TREBLE_CONTROL                    0x05
+#define AUDIO_GRAPHIC_EQUALIZER_CONTROL         0x06
+#define AUDIO_AUTOMATIC_GAIN_CONTROL            0x07
+#define AUDIO_DELAY_CONTROL                     0x08
+#define AUDIO_BASS_BOOST_CONTROL                0x09
+#define AUDIO_LOUDNESS_CONTROL                  0x0A
+
+/*  Processing Unit Control Selectors: */
+#define AUDIO_ENABLE_CONTROL                    0x01    /* Common Selector */
+#define AUDIO_MODE_SELECT_CONTROL               0x02    /* Common Selector */
+
+/*  - Up/Down-mix Control Selectors */
+/*      AUDIO_ENABLE_CONTROL                    0x01       Common Selector */
+/*      AUDIO_MODE_SELECT_CONTROL               0x02       Common Selector */
+
+/*  - Dolby Prologic Control Selectors */
+/*      AUDIO_ENABLE_CONTROL                    0x01       Common Selector */
+/*      AUDIO_MODE_SELECT_CONTROL               0x02       Common Selector */
+
+/*  - 3D Stereo Extender Control Selectors */
+/*      AUDIO_ENABLE_CONTROL                    0x01       Common Selector */
+#define AUDIO_SPACIOUSNESS_CONTROL              0x02
+
+/*  - Reverberation Control Selectors */
+/*      AUDIO_ENABLE_CONTROL                    0x01       Common Selector */
+#define AUDIO_REVERB_LEVEL_CONTROL              0x02
+#define AUDIO_REVERB_TIME_CONTROL               0x03
+#define AUDIO_REVERB_FEEDBACK_CONTROL           0x04
+
+/*  - Chorus Control Selectors */
+/*      AUDIO_ENABLE_CONTROL                    0x01       Common Selector */
+#define AUDIO_CHORUS_LEVEL_CONTROL              0x02
+#define AUDIO_SHORUS_RATE_CONTROL               0x03
+#define AUDIO_CHORUS_DEPTH_CONTROL              0x04
+
+/*  - Dynamic Range Compressor Control Selectors */
+/*      AUDIO_ENABLE_CONTROL                    0x01       Common Selector */
+#define AUDIO_COMPRESSION_RATE_CONTROL          0x02
+#define AUDIO_MAX_AMPL_CONTROL                  0x03
+#define AUDIO_THRESHOLD_CONTROL                 0x04
+#define AUDIO_ATTACK_TIME_CONTROL               0x05
+#define AUDIO_RELEASE_TIME_CONTROL              0x06
+
+/*  Extension Unit Control Selectors */
+/*      AUDIO_ENABLE_CONTROL                    0x01       Common Selector */
+
+/*  Endpoint Control Selectors */
+#define AUDIO_SAMPLING_FREQ_CONTROL             0x01
+#define AUDIO_PITCH_CONTROL                     0x02
+
+
+/* Audio Format Specific Control Selectors */
+
+/*  MPEG Control Selectors */
+#define AUDIO_MPEG_CONTROL_UNDEFINED            0x00
+#define AUDIO_MPEG_DUAL_CHANNEL_CONTROL         0x01
+#define AUDIO_MPEG_SECOND_STEREO_CONTROL        0x02
+#define AUDIO_MPEG_MULTILINGUAL_CONTROL         0x03
+#define AUDIO_MPEG_DYN_RANGE_CONTROL            0x04
+#define AUDIO_MPEG_SCALING_CONTROL              0x05
+#define AUDIO_MPEG_HILO_SCALING_CONTROL         0x06
+
+/*  AC-3 Control Selectors */
+#define AUDIO_AC3_CONTROL_UNDEFINED             0x00
+#define AUDIO_AC3_MODE_CONTROL                  0x01
+#define AUDIO_AC3_DYN_RANGE_CONTROL             0x02
+#define AUDIO_AC3_SCALING_CONTROL               0x03
+#define AUDIO_AC3_HILO_SCALING_CONTROL          0x04
+
+
+/* Audio Format Types */
+#define AUDIO_FORMAT_TYPE_UNDEFINED             0x00
+#define AUDIO_FORMAT_TYPE_I                     0x01
+#define AUDIO_FORMAT_TYPE_II                    0x02
+#define AUDIO_FORMAT_TYPE_III                   0x03
+
+
+/* Audio Format Type Descriptor Sizes */
+#define AUDIO_FORMAT_TYPE_I_DESC_SZ(n)          0x08+(n*3)
+#define AUDIO_FORMAT_TYPE_II_DESC_SZ(n)         0x09+(n*3)
+#define AUDIO_FORMAT_TYPE_III_DESC_SZ(n)        0x08+(n*3)
+#define AUDIO_FORMAT_MPEG_DESC_SIZE             0x09
+#define AUDIO_FORMAT_AC3_DESC_SIZE              0x0A
+
+
+/* Audio Data Format Codes */
+
+/*  Audio Data Format Type I Codes */
+#define AUDIO_FORMAT_TYPE_I_UNDEFINED           0x0000
+#define AUDIO_FORMAT_PCM                        0x0001
+#define AUDIO_FORMAT_PCM8                       0x0002
+#define AUDIO_FORMAT_IEEE_FLOAT                 0x0003
+#define AUDIO_FORMAT_ALAW                       0x0004
+#define AUDIO_FORMAT_MULAW                      0x0005
+
+/*  Audio Data Format Type II Codes */
+#define AUDIO_FORMAT_TYPE_II_UNDEFINED          0x1000
+#define AUDIO_FORMAT_MPEG                       0x1001
+#define AUDIO_FORMAT_AC3                        0x1002
+
+/*  Audio Data Format Type III Codes */
+#define AUDIO_FORMAT_TYPE_III_UNDEFINED         0x2000
+#define AUDIO_FORMAT_IEC1937_AC3                0x2001
+#define AUDIO_FORMAT_IEC1937_MPEG1_L1           0x2002
+#define AUDIO_FORMAT_IEC1937_MPEG1_L2_3         0x2003
+#define AUDIO_FORMAT_IEC1937_MPEG2_NOEXT        0x2003
+#define AUDIO_FORMAT_IEC1937_MPEG2_EXT          0x2004
+#define AUDIO_FORMAT_IEC1937_MPEG2_L1_LS        0x2005
+#define AUDIO_FORMAT_IEC1937_MPEG2_L2_3         0x2006
+
+
+/* Predefined Audio Channel Configuration Bits */
+#define AUDIO_CHANNEL_M                         0x0000  /* Mono */
+#define AUDIO_CHANNEL_L                         0x0001  /* Left Front */
+#define AUDIO_CHANNEL_R                         0x0002  /* Right Front */
+#define AUDIO_CHANNEL_C                         0x0004  /* Center Front */
+#define AUDIO_CHANNEL_LFE                       0x0008  /* Low Freq. Enhance. */
+#define AUDIO_CHANNEL_LS                        0x0010  /* Left Surround */
+#define AUDIO_CHANNEL_RS                        0x0020  /* Right Surround */
+#define AUDIO_CHANNEL_LC                        0x0040  /* Left of Center */
+#define AUDIO_CHANNEL_RC                        0x0080  /* Right of Center */
+#define AUDIO_CHANNEL_S                         0x0100  /* Surround */
+#define AUDIO_CHANNEL_SL                        0x0200  /* Side Left */
+#define AUDIO_CHANNEL_SR                        0x0400  /* Side Right */
+#define AUDIO_CHANNEL_T                         0x0800  /* Top */
+
+
+/* Feature Unit Control Bits */
+#define AUDIO_CONTROL_MUTE                      0x0001
+#define AUDIO_CONTROL_VOLUME                    0x0002
+#define AUDIO_CONTROL_BASS                      0x0004
+#define AUDIO_CONTROL_MID                       0x0008
+#define AUDIO_CONTROL_TREBLE                    0x0010
+#define AUDIO_CONTROL_GRAPHIC_EQUALIZER         0x0020
+#define AUDIO_CONTROL_AUTOMATIC_GAIN            0x0040
+#define AUDIO_CONTROL_DEALY                     0x0080
+#define AUDIO_CONTROL_BASS_BOOST                0x0100
+#define AUDIO_CONTROL_LOUDNESS                  0x0200
+
+/* Processing Unit Control Bits: */
+#define AUDIO_CONTROL_ENABLE                    0x0001  /* Common Bit */
+#define AUDIO_CONTROL_MODE_SELECT               0x0002  /* Common Bit */
+
+/* - Up/Down-mix Control Bits */
+/*      AUDIO_CONTROL_ENABLE                    0x0001     Common Bit */
+/*      AUDIO_CONTROL_MODE_SELECT               0x0002     Common Bit */
+
+/* - Dolby Prologic Control Bits */
+/*      AUDIO_CONTROL_ENABLE                    0x0001     Common Bit */
+/*      AUDIO_CONTROL_MODE_SELECT               0x0002     Common Bit */
+
+/* - 3D Stereo Extender Control Bits */
+/*      AUDIO_CONTROL_ENABLE                    0x0001     Common Bit */
+#define AUDIO_CONTROL_SPACIOUSNESS              0x0002
+
+/* - Reverberation Control Bits */
+/*      AUDIO_CONTROL_ENABLE                    0x0001     Common Bit */
+#define AUDIO_CONTROL_REVERB_TYPE               0x0002
+#define AUDIO_CONTROL_REVERB_LEVEL              0x0004
+#define AUDIO_CONTROL_REVERB_TIME               0x0008
+#define AUDIO_CONTROL_REVERB_FEEDBACK           0x0010
+
+/* - Chorus Control Bits */
+/*      AUDIO_CONTROL_ENABLE                    0x0001     Common Bit */
+#define AUDIO_CONTROL_CHORUS_LEVEL              0x0002
+#define AUDIO_CONTROL_SHORUS_RATE               0x0004
+#define AUDIO_CONTROL_CHORUS_DEPTH              0x0008
+
+/* - Dynamic Range Compressor Control Bits */
+/*      AUDIO_CONTROL_ENABLE                    0x0001     Common Bit */
+#define AUDIO_CONTROL_COMPRESSION_RATE          0x0002
+#define AUDIO_CONTROL_MAX_AMPL                  0x0004
+#define AUDIO_CONTROL_THRESHOLD                 0x0008
+#define AUDIO_CONTROL_ATTACK_TIME               0x0010
+#define AUDIO_CONTROL_RELEASE_TIME              0x0020
+
+/* Extension Unit Control Bits */
+/*      AUDIO_CONTROL_ENABLE                    0x0001     Common Bit */
+
+/* Endpoint Control Bits */
+#define AUDIO_CONTROL_SAMPLING_FREQ             0x01
+#define AUDIO_CONTROL_PITCH                     0x02
+#define AUDIO_MAX_PACKETS_ONLY                  0x80
+
+
+/* Audio Terminal Types */
+
+/*  USB Terminal Types */
+#define AUDIO_TERMINAL_USB_UNDEFINED            0x0100
+#define AUDIO_TERMINAL_USB_STREAMING            0x0101
+#define AUDIO_TERMINAL_USB_VENDOR_SPECIFIC      0x01FF
+
+/*  Input Terminal Types */
+#define AUDIO_TERMINAL_INPUT_UNDEFINED          0x0200
+#define AUDIO_TERMINAL_MICROPHONE               0x0201
+#define AUDIO_TERMINAL_DESKTOP_MICROPHONE       0x0202
+#define AUDIO_TERMINAL_PERSONAL_MICROPHONE      0x0203
+#define AUDIO_TERMINAL_OMNI_DIR_MICROPHONE      0x0204
+#define AUDIO_TERMINAL_MICROPHONE_ARRAY         0x0205
+#define AUDIO_TERMINAL_PROCESSING_MIC_ARRAY     0x0206
+
+/*  Output Terminal Types */
+#define AUDIO_TERMINAL_OUTPUT_UNDEFINED         0x0300
+#define AUDIO_TERMINAL_SPEAKER                  0x0301
+#define AUDIO_TERMINAL_HEADPHONES               0x0302
+#define AUDIO_TERMINAL_HEAD_MOUNTED_AUDIO       0x0303
+#define AUDIO_TERMINAL_DESKTOP_SPEAKER          0x0304
+#define AUDIO_TERMINAL_ROOM_SPEAKER             0x0305
+#define AUDIO_TERMINAL_COMMUNICATION_SPEAKER    0x0306
+#define AUDIO_TERMINAL_LOW_FREQ_SPEAKER         0x0307
+
+/*  Bi-directional Terminal Types */
+#define AUDIO_TERMINAL_BIDIRECTIONAL_UNDEFINED  0x0400
+#define AUDIO_TERMINAL_HANDSET                  0x0401
+#define AUDIO_TERMINAL_HEAD_MOUNTED_HANDSET     0x0402
+#define AUDIO_TERMINAL_SPEAKERPHONE             0x0403
+#define AUDIO_TERMINAL_SPEAKERPHONE_ECHOSUPRESS 0x0404
+#define AUDIO_TERMINAL_SPEAKERPHONE_ECHOCANCEL  0x0405
+
+/*  Telephony Terminal Types */
+#define AUDIO_TERMINAL_TELEPHONY_UNDEFINED      0x0500
+#define AUDIO_TERMINAL_PHONE_LINE               0x0501
+#define AUDIO_TERMINAL_TELEPHONE                0x0502
+#define AUDIO_TERMINAL_DOWN_LINE_PHONE          0x0503
+
+/*  External Terminal Types */
+#define AUDIO_TERMINAL_EXTERNAL_UNDEFINED       0x0600
+#define AUDIO_TERMINAL_ANALOG_CONNECTOR         0x0601
+#define AUDIO_TERMINAL_DIGITAL_AUDIO_INTERFACE  0x0602
+#define AUDIO_TERMINAL_LINE_CONNECTOR           0x0603
+#define AUDIO_TERMINAL_LEGACY_AUDIO_CONNECTOR   0x0604
+#define AUDIO_TERMINAL_SPDIF_INTERFACE          0x0605
+#define AUDIO_TERMINAL_1394_DA_STREAM           0x0606
+#define AUDIO_TERMINAL_1394_DA_STREAM_TRACK     0x0607
+
+/*  Embedded Function Terminal Types */
+#define AUDIO_TERMINAL_EMBEDDED_UNDEFINED       0x0700
+#define AUDIO_TERMINAL_CALIBRATION_NOISE        0x0701
+#define AUDIO_TERMINAL_EQUALIZATION_NOISE       0x0702
+#define AUDIO_TERMINAL_CD_PLAYER                0x0703
+#define AUDIO_TERMINAL_DAT                      0x0704
+#define AUDIO_TERMINAL_DCC                      0x0705
+#define AUDIO_TERMINAL_MINI_DISK                0x0706
+#define AUDIO_TERMINAL_ANALOG_TAPE              0x0707
+#define AUDIO_TERMINAL_PHONOGRAPH               0x0708
+#define AUDIO_TERMINAL_VCR_AUDIO                0x0709
+#define AUDIO_TERMINAL_VIDEO_DISC_AUDIO         0x070A
+#define AUDIO_TERMINAL_DVD_AUDIO                0x070B
+#define AUDIO_TERMINAL_TV_TUNER_AUDIO           0x070C
+#define AUDIO_TERMINAL_SATELLITE_RECEIVER_AUDIO 0x070D
+#define AUDIO_TERMINAL_CABLE_TUNER_AUDIO        0x070E
+#define AUDIO_TERMINAL_DSS_AUDIO                0x070F
+#define AUDIO_TERMINAL_RADIO_RECEIVER           0x0710
+#define AUDIO_TERMINAL_RADIO_TRANSMITTER        0x0711
+#define AUDIO_TERMINAL_MULTI_TRACK_RECORDER     0x0712
+#define AUDIO_TERMINAL_SYNTHESIZER              0x0713
+
+#ifdef __cplusplus
+}
+#endif 
+
+
+#endif  /* __AUDIO_H__ */
diff --git a/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_cdc.h b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_cdc.h
new file mode 100644
index 0000000000000000000000000000000000000000..8960c8ab9036935c99874c9ed810390a5b452470
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_cdc.h
@@ -0,0 +1,257 @@
+/***********************************************************************
+* $Id:: mw_usbd_cdc.h 197 2011-06-12 20:22:41Z usb06052                       $
+*
+* Project: USB device ROM Stack
+*
+* Description:
+*     USB Communication Device Class User module Definitions.
+*
+***********************************************************************
+*   Copyright(C) 2011, NXP Semiconductor
+*   All rights reserved.
+*
+* Software that is described herein is for illustrative purposes only
+* which provides customers with programming information regarding the
+* products. This software is supplied "AS IS" without any warranties.
+* NXP Semiconductors assumes no responsibility or liability for the
+* use of the software, conveys no license or title under any patent,
+* copyright, or mask work right to the product. NXP Semiconductors
+* reserves the right to make changes in the software without
+* notification. NXP Semiconductors also make no representation or
+* warranty that such application will be suitable for the specified
+* use without further testing or modification.
+**********************************************************************/
+#ifndef __CDC_H
+#define __CDC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "mw_usbd.h"
+
+/*----------------------------------------------------------------------------
+ *      Definitions  based on usbcdc11.pdf (www.usb.org)
+ *---------------------------------------------------------------------------*/
+/* Communication device class specification version 1.10 */
+#define CDC_V1_10                               0x0110
+
+/* Communication interface class code */
+/* (usbcdc11.pdf, 4.2, Table 15) */
+#define CDC_COMMUNICATION_INTERFACE_CLASS       0x02
+
+/* Communication interface class subclass codes */
+/* (usbcdc11.pdf, 4.3, Table 16) */
+#define CDC_DIRECT_LINE_CONTROL_MODEL           0x01
+#define CDC_ABSTRACT_CONTROL_MODEL              0x02
+#define CDC_TELEPHONE_CONTROL_MODEL             0x03
+#define CDC_MULTI_CHANNEL_CONTROL_MODEL         0x04
+#define CDC_CAPI_CONTROL_MODEL                  0x05
+#define CDC_ETHERNET_NETWORKING_CONTROL_MODEL   0x06
+#define CDC_ATM_NETWORKING_CONTROL_MODEL        0x07
+
+/* Communication interface class control protocol codes */
+/* (usbcdc11.pdf, 4.4, Table 17) */
+#define CDC_PROTOCOL_COMMON_AT_COMMANDS         0x01
+
+/* Data interface class code */
+/* (usbcdc11.pdf, 4.5, Table 18) */
+#define CDC_DATA_INTERFACE_CLASS                0x0A
+
+/* Data interface class protocol codes */
+/* (usbcdc11.pdf, 4.7, Table 19) */
+#define CDC_PROTOCOL_ISDN_BRI                   0x30
+#define CDC_PROTOCOL_HDLC                       0x31
+#define CDC_PROTOCOL_TRANSPARENT                0x32
+#define CDC_PROTOCOL_Q921_MANAGEMENT            0x50
+#define CDC_PROTOCOL_Q921_DATA_LINK             0x51
+#define CDC_PROTOCOL_Q921_MULTIPLEXOR           0x52
+#define CDC_PROTOCOL_V42                        0x90
+#define CDC_PROTOCOL_EURO_ISDN                  0x91
+#define CDC_PROTOCOL_V24_RATE_ADAPTATION        0x92
+#define CDC_PROTOCOL_CAPI                       0x93
+#define CDC_PROTOCOL_HOST_BASED_DRIVER          0xFD
+#define CDC_PROTOCOL_DESCRIBED_IN_PUFD          0xFE
+
+/* Type values for bDescriptorType field of functional descriptors */
+/* (usbcdc11.pdf, 5.2.3, Table 24) */
+#define CDC_CS_INTERFACE                        0x24
+#define CDC_CS_ENDPOINT                         0x25
+
+/* Type values for bDescriptorSubtype field of functional descriptors */
+/* (usbcdc11.pdf, 5.2.3, Table 25) */
+#define CDC_HEADER                              0x00
+#define CDC_CALL_MANAGEMENT                     0x01
+#define CDC_ABSTRACT_CONTROL_MANAGEMENT         0x02
+#define CDC_DIRECT_LINE_MANAGEMENT              0x03
+#define CDC_TELEPHONE_RINGER                    0x04
+#define CDC_REPORTING_CAPABILITIES              0x05
+#define CDC_UNION                               0x06
+#define CDC_COUNTRY_SELECTION                   0x07
+#define CDC_TELEPHONE_OPERATIONAL_MODES         0x08
+#define CDC_USB_TERMINAL                        0x09
+#define CDC_NETWORK_CHANNEL                     0x0A
+#define CDC_PROTOCOL_UNIT                       0x0B
+#define CDC_EXTENSION_UNIT                      0x0C
+#define CDC_MULTI_CHANNEL_MANAGEMENT            0x0D
+#define CDC_CAPI_CONTROL_MANAGEMENT             0x0E
+#define CDC_ETHERNET_NETWORKING                 0x0F
+#define CDC_ATM_NETWORKING                      0x10
+
+/* CDC class-specific request codes */
+/* (usbcdc11.pdf, 6.2, Table 46) */
+/* see Table 45 for info about the specific requests. */
+#define CDC_SEND_ENCAPSULATED_COMMAND           0x00
+#define CDC_GET_ENCAPSULATED_RESPONSE           0x01
+#define CDC_SET_COMM_FEATURE                    0x02
+#define CDC_GET_COMM_FEATURE                    0x03
+#define CDC_CLEAR_COMM_FEATURE                  0x04
+#define CDC_SET_AUX_LINE_STATE                  0x10
+#define CDC_SET_HOOK_STATE                      0x11
+#define CDC_PULSE_SETUP                         0x12
+#define CDC_SEND_PULSE                          0x13
+#define CDC_SET_PULSE_TIME                      0x14
+#define CDC_RING_AUX_JACK                       0x15
+#define CDC_SET_LINE_CODING                     0x20
+#define CDC_GET_LINE_CODING                     0x21
+#define CDC_SET_CONTROL_LINE_STATE              0x22
+#define CDC_SEND_BREAK                          0x23
+#define CDC_SET_RINGER_PARMS                    0x30
+#define CDC_GET_RINGER_PARMS                    0x31
+#define CDC_SET_OPERATION_PARMS                 0x32
+#define CDC_GET_OPERATION_PARMS                 0x33
+#define CDC_SET_LINE_PARMS                      0x34
+#define CDC_GET_LINE_PARMS                      0x35
+#define CDC_DIAL_DIGITS                         0x36
+#define CDC_SET_UNIT_PARAMETER                  0x37
+#define CDC_GET_UNIT_PARAMETER                  0x38
+#define CDC_CLEAR_UNIT_PARAMETER                0x39
+#define CDC_GET_PROFILE                         0x3A
+#define CDC_SET_ETHERNET_MULTICAST_FILTERS      0x40
+#define CDC_SET_ETHERNET_PMP_FILTER             0x41
+#define CDC_GET_ETHERNET_PMP_FILTER             0x42
+#define CDC_SET_ETHERNET_PACKET_FILTER          0x43
+#define CDC_GET_ETHERNET_STATISTIC              0x44
+#define CDC_SET_ATM_DATA_FORMAT                 0x50
+#define CDC_GET_ATM_DEVICE_STATISTICS           0x51
+#define CDC_SET_ATM_DEFAULT_VC                  0x52
+#define CDC_GET_ATM_VC_STATISTICS               0x53
+
+/* Communication feature selector codes */
+/* (usbcdc11.pdf, 6.2.2..6.2.4, Table 47) */
+#define CDC_ABSTRACT_STATE                      0x01
+#define CDC_COUNTRY_SETTING                     0x02
+
+/* Feature Status returned for ABSTRACT_STATE Selector */
+/* (usbcdc11.pdf, 6.2.3, Table 48) */
+#define CDC_IDLE_SETTING                        (1 << 0)
+#define CDC_DATA_MULTPLEXED_STATE               (1 << 1)
+
+
+/* Control signal bitmap values for the SetControlLineState request */
+/* (usbcdc11.pdf, 6.2.14, Table 51) */
+#define CDC_DTE_PRESENT                         (1 << 0)
+#define CDC_ACTIVATE_CARRIER                    (1 << 1)
+
+/* CDC class-specific notification codes */
+/* (usbcdc11.pdf, 6.3, Table 68) */
+/* see Table 67 for Info about class-specific notifications */
+#define CDC_NOTIFICATION_NETWORK_CONNECTION     0x00
+#define CDC_RESPONSE_AVAILABLE                  0x01
+#define CDC_AUX_JACK_HOOK_STATE                 0x08
+#define CDC_RING_DETECT                         0x09
+#define CDC_NOTIFICATION_SERIAL_STATE           0x20
+#define CDC_CALL_STATE_CHANGE                   0x28
+#define CDC_LINE_STATE_CHANGE                   0x29
+#define CDC_CONNECTION_SPEED_CHANGE             0x2A
+
+/* UART state bitmap values (Serial state notification). */
+/* (usbcdc11.pdf, 6.3.5, Table 69) */
+#define CDC_SERIAL_STATE_OVERRUN                (1 << 6)  /* receive data overrun error has occurred */
+#define CDC_SERIAL_STATE_PARITY                 (1 << 5)  /* parity error has occurred */
+#define CDC_SERIAL_STATE_FRAMING                (1 << 4)  /* framing error has occurred */
+#define CDC_SERIAL_STATE_RING                   (1 << 3)  /* state of ring signal detection */
+#define CDC_SERIAL_STATE_BREAK                  (1 << 2)  /* state of break detection */
+#define CDC_SERIAL_STATE_TX_CARRIER             (1 << 1)  /* state of transmission carrier */
+#define CDC_SERIAL_STATE_RX_CARRIER             (1 << 0)  /* state of receiver carrier */
+
+
+/*----------------------------------------------------------------------------
+ *      Structures  based on usbcdc11.pdf (www.usb.org)
+ *---------------------------------------------------------------------------*/
+
+/* Header functional descriptor */
+/* (usbcdc11.pdf, 5.2.3.1) */
+/* This header must precede any list of class-specific descriptors. */
+PRE_PACK struct POST_PACK _CDC_HEADER_DESCRIPTOR{
+  uint8_t  bFunctionLength;                      /* size of this descriptor in bytes */
+  uint8_t  bDescriptorType;                      /* CS_INTERFACE descriptor type */
+  uint8_t  bDescriptorSubtype;                   /* Header functional descriptor subtype */
+  uint16_t bcdCDC;                               /* USB CDC specification release version */
+};
+typedef struct _CDC_HEADER_DESCRIPTOR CDC_HEADER_DESCRIPTOR;
+
+/* Call management functional descriptor */
+/* (usbcdc11.pdf, 5.2.3.2) */
+/* Describes the processing of calls for the communication class interface. */
+PRE_PACK struct POST_PACK _CDC_CALL_MANAGEMENT_DESCRIPTOR {
+  uint8_t  bFunctionLength;                      /* size of this descriptor in bytes */
+  uint8_t  bDescriptorType;                      /* CS_INTERFACE descriptor type */
+  uint8_t  bDescriptorSubtype;                   /* call management functional descriptor subtype */
+  uint8_t  bmCapabilities;                       /* capabilities that this configuration supports */
+  uint8_t  bDataInterface;                       /* interface number of the data class interface used for call management (optional) */
+};
+typedef struct _CDC_CALL_MANAGEMENT_DESCRIPTOR CDC_CALL_MANAGEMENT_DESCRIPTOR;
+
+/* Abstract control management functional descriptor */
+/* (usbcdc11.pdf, 5.2.3.3) */
+/* Describes the command supported by the communication interface class with the Abstract Control Model subclass code. */
+PRE_PACK struct POST_PACK _CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR {
+  uint8_t  bFunctionLength;                      /* size of this descriptor in bytes */
+  uint8_t  bDescriptorType;                      /* CS_INTERFACE descriptor type */
+  uint8_t  bDescriptorSubtype;                   /* abstract control management functional descriptor subtype */
+  uint8_t  bmCapabilities;                       /* capabilities supported by this configuration */
+};
+typedef struct _CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR;
+
+/* Union functional descriptors */
+/* (usbcdc11.pdf, 5.2.3.8) */
+/* Describes the relationship between a group of interfaces that can be considered to form a functional unit. */
+PRE_PACK struct POST_PACK _CDC_UNION_DESCRIPTOR {
+  uint8_t  bFunctionLength;                      /* size of this descriptor in bytes */
+  uint8_t  bDescriptorType;                      /* CS_INTERFACE descriptor type */
+  uint8_t  bDescriptorSubtype;                   /* union functional descriptor subtype */
+  uint8_t  bMasterInterface;                     /* interface number designated as master */
+};
+typedef struct _CDC_UNION_DESCRIPTOR CDC_UNION_DESCRIPTOR;
+
+/* Union functional descriptors with one slave interface */
+/* (usbcdc11.pdf, 5.2.3.8) */
+PRE_PACK struct POST_PACK _CDC_UNION_1SLAVE_DESCRIPTOR {
+  CDC_UNION_DESCRIPTOR sUnion;              /* Union functional descriptor */
+  uint8_t              bSlaveInterfaces[1]; /* Slave interface 0 */
+};
+typedef struct _CDC_UNION_1SLAVE_DESCRIPTOR CDC_UNION_1SLAVE_DESCRIPTOR;
+
+/* Line coding structure */
+/* Format of the data returned when a GetLineCoding request is received */
+/* (usbcdc11.pdf, 6.2.13) */
+PRE_PACK struct POST_PACK _CDC_LINE_CODING {
+  uint32_t dwDTERate;                            /* Data terminal rate in bits per second */
+  uint8_t  bCharFormat;                          /* Number of stop bits */
+  uint8_t  bParityType;                          /* Parity bit type */
+  uint8_t  bDataBits;                            /* Number of data bits */
+};
+typedef struct _CDC_LINE_CODING CDC_LINE_CODING;
+
+/* Notification header */
+/* Data sent on the notification endpoint must follow this header. */
+/* see  USB_SETUP_PACKET in file usb.h */
+typedef USB_SETUP_PACKET CDC_NOTIFICATION_HEADER;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif /* __CDC_H */
+
diff --git a/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_cdcuser.h b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_cdcuser.h
new file mode 100644
index 0000000000000000000000000000000000000000..33b6c8b1a60da7504accb8d9983a0835f83962d3
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_cdcuser.h
@@ -0,0 +1,348 @@
+/***********************************************************************
+* $Id:: mw_usbd_cdcuser.h 202 2011-06-12 21:50:01Z usb06052                   $
+*
+* Project: USB device ROM Stack
+*
+* Description:
+*     USB Communication Device Class User module Definitions.
+*
+***********************************************************************
+*   Copyright(C) 2011, NXP Semiconductor
+*   All rights reserved.
+*
+* Software that is described herein is for illustrative purposes only
+* which provides customers with programming information regarding the
+* products. This software is supplied "AS IS" without any warranties.
+* NXP Semiconductors assumes no responsibility or liability for the
+* use of the software, conveys no license or title under any patent,
+* copyright, or mask work right to the product. NXP Semiconductors
+* reserves the right to make changes in the software without
+* notification. NXP Semiconductors also make no representation or
+* warranty that such application will be suitable for the specified
+* use without further testing or modification.
+**********************************************************************/
+#ifndef __CDCUSER_H__
+#define __CDCUSER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "error.h"
+#include "mw_usbd.h"
+#include "mw_usbd_cdc.h"
+
+/** \file
+ *  \brief Communication Device Class (CDC) API structures and function prototypes.
+ *
+ *  Definition of functions exported by ROM based CDC function driver.
+ *
+ */
+
+/** \ingroup Group_USBD
+ *  @defgroup USBD_CDC Communication Device Class (CDC) Function Driver
+ *  \section Sec_CDCModDescription Module Description
+ *  CDC Class Function Driver module. This module contains an internal implementation of the USB CDC Class.
+ *  User applications can use this class driver instead of implementing the CDC class manually
+ *  via the low-level USBD_HW and USBD_Core APIs.
+ *
+ *  This module is designed to simplify the user code by exposing only the required interface needed to interface with
+ *  Devices using the USB CDC Class.
+ */
+
+/*----------------------------------------------------------------------------
+  We need a buffer for incomming data on USB port because USB receives
+  much faster than  UART transmits
+ *---------------------------------------------------------------------------*/
+/* Buffer masks */
+#define CDC_BUF_SIZE               (128)               /* Output buffer in bytes (power 2) */
+                                                       /* large enough for file transfer */
+#define CDC_BUF_MASK               (CDC_BUF_SIZE-1ul)
+
+/** \brief Communication Device Class function driver initilization parameter data structure.
+ *  \ingroup USBD_CDC
+ *
+ *  \details  This data structure is used to pass initialization parameters to the 
+ *  Communication Device Class function driver's init function.
+ *
+ */
+typedef struct USBD_CDC_INIT_PARAM
+{
+  /* memory allocation params */
+  uint32_t mem_base;  /**< Base memory location from where the stack can allocate
+                      data and buffers. \note The memory address set in this field
+                      should be accessible by USB DMA controller. Also this value
+                      should be aligned on 4 byte boundary.
+                      */
+  uint32_t mem_size;  /**< The size of memory buffer which stack can use. 
+                      \note The \em mem_size should be greater than the size 
+                      returned by USBD_CDC_API::GetMemSize() routine.*/
+  /** Pointer to the control interface descriptor within the descriptor
+  * array (\em high_speed_desc) passed to Init() through \ref USB_CORE_DESCS_T 
+  * structure. The stack assumes both HS and FS use same BULK endpoints. 
+  */
+  uint8_t* cif_intf_desc;
+  /** Pointer to the data interface descriptor within the descriptor
+  * array (\em high_speed_desc) passed to Init() through \ref USB_CORE_DESCS_T 
+  * structure. The stack assumes both HS and FS use same BULK endpoints. 
+  */
+  uint8_t* dif_intf_desc;
+
+  /* user defined functions */
+
+  /* required functions */
+  /** 
+  *  Communication Interface Class specific get request callback function.
+  *
+  *  This function is provided by the application software. This function gets called 
+  *  when host sends CIC management element get requests. The setup packet data (\em pSetup)
+  *  is passed to the callback so that application can extract the CIC request type
+  *  and other associated data. By default the stack will ssign \em pBuffer pointer
+  *  to \em EP0Buff allocated at init. The application code can directly write data 
+  *  into this buffer as long as data is less than 64 byte. If more data has to be sent 
+  *  then application code should update \em pBuffer pointer and length accordingly.
+  *   
+  *  
+  *  \param[in] hCdc Handle to CDC function driver. 
+  *  \param[in] pSetup Pointer to setup packet recived from host. 
+  *  \param[in, out] pBuffer  Pointer to a pointer of data buffer containing request data. 
+  *                       Pointer-to-pointer is used to implement zero-copy buffers. 
+  *                       See \ref USBD_ZeroCopy for more details on zero-copy concept.
+  *  \param[in, out] length  Amount of data to be sent back to host.
+  *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK On success.
+  *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+  *          \retval ERR_USBD_xxx  For other error conditions. 
+  *                                             
+  */
+  ErrorCode_t (*CIC_GetRequest)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t* length); 
+  
+  /** 
+  *  Communication Interface Class specific set request callback function.
+  *
+  *  This function is provided by the application software. This function gets called 
+  *  when host sends a CIC management element requests. The setup packet data (\em pSetup)
+  *  is passed to the callback so that application can extract the CIC request type
+  *  and other associated data. If a set request has data associated, then this callback
+  *  is called twice. 
+  *  (1) First when setup request is recived, at this time application code could update
+  *  \em pBuffer pointer to point to the intended destination. The length param is set to 0
+  *  so that application code knows this is first time. By default the stack will
+  *  assign \em pBuffer pointer to \em EP0Buff allocated at init. Note, if data length is 
+  *  greater than 64 bytes and application code doesn't update \em pBuffer pointer the 
+  *  stack will send STALL condition to host.
+  *  (2) Second when the data is recived from the host. This time the length param is set
+  *  with number of data bytes recived.
+  *  
+  *  \param[in] hCdc Handle to CDC function driver. 
+  *  \param[in] pSetup Pointer to setup packet recived from host. 
+  *  \param[in, out] pBuffer  Pointer to a pointer of data buffer containing request data. 
+  *                       Pointer-to-pointer is used to implement zero-copy buffers. 
+  *                       See \ref USBD_ZeroCopy for more details on zero-copy concept.
+  *  \param[in] length  Amount of data copied to destination buffer.
+  *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK On success.
+  *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+  *          \retval ERR_USBD_xxx  For other error conditions. 
+  *                                             
+  */
+  ErrorCode_t (*CIC_SetRequest)( USBD_HANDLE_T hCdc, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t length);
+
+  /** 
+  *  Communication Device Class specific BULK IN endpoint handler.
+  *
+  *  The application software should provide the BULK IN endpoint handler.
+  *  Applications should transfer data depending on the communication protocol type set in descriptors. 
+  *  \n
+  *  \note 
+  *  
+  *  \param[in] hUsb Handle to the USB device stack. 
+  *  \param[in] data Pointer to the data which will be passed when callback function is called by the stack. 
+  *  \param[in] event  Type of endpoint event. See \ref USBD_EVENT_T for more details.
+  *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK On success.
+  *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+  *          \retval ERR_USBD_xxx  For other error conditions. 
+  *                                             
+  */
+  ErrorCode_t (*CDC_BulkIN_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event);
+
+  /** 
+  *  Communication Device Class specific BULK OUT endpoint handler.
+  *
+  *  The application software should provide the BULK OUT endpoint handler.
+  *  Applications should transfer data depending on the communication protocol type set in descriptors. 
+  *  \n
+  *  \note 
+  *  
+  *  \param[in] hUsb Handle to the USB device stack. 
+  *  \param[in] data Pointer to the data which will be passed when callback function is called by the stack. 
+  *  \param[in] event  Type of endpoint event. See \ref USBD_EVENT_T for more details.
+  *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK On success.
+  *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+  *          \retval ERR_USBD_xxx  For other error conditions. 
+  *                                             
+  */
+  ErrorCode_t (*CDC_BulkOUT_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event);
+
+  ErrorCode_t (*SendEncpsCmd) (USBD_HANDLE_T hCDC, uint8_t* buffer, uint16_t len);
+  ErrorCode_t (*GetEncpsResp) (USBD_HANDLE_T hCDC, uint8_t** buffer, uint16_t* len);
+  ErrorCode_t (*SetCommFeature) (USBD_HANDLE_T hCDC, uint16_t feature, uint8_t* buffer, uint16_t len);
+  ErrorCode_t (*GetCommFeature) (USBD_HANDLE_T hCDC, uint16_t feature, uint8_t** pBuffer, uint16_t* len);
+  ErrorCode_t (*ClrCommFeature) (USBD_HANDLE_T hCDC, uint16_t feature);
+  ErrorCode_t (*SetCtrlLineState) (USBD_HANDLE_T hCDC, uint16_t state);
+  ErrorCode_t (*SendBreak) (USBD_HANDLE_T hCDC, uint16_t mstime);
+  ErrorCode_t (*SetLineCode) (USBD_HANDLE_T hCDC, CDC_LINE_CODING* line_coding);
+
+  /** 
+  *  Optional Communication Device Class specific INTERRUPT IN endpoint handler.
+  *
+  *  The application software should provide the INT IN endpoint handler.
+  *  Applications should transfer data depending on the communication protocol type set in descriptors. 
+  *  \n
+  *  \note 
+  *  
+  *  \param[in] hUsb Handle to the USB device stack. 
+  *  \param[in] data Pointer to the data which will be passed when callback function is called by the stack. 
+  *  \param[in] event  Type of endpoint event. See \ref USBD_EVENT_T for more details.
+  *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK On success.
+  *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+  *          \retval ERR_USBD_xxx  For other error conditions. 
+  *                                             
+  */
+  ErrorCode_t (*CDC_InterruptEP_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event);
+
+  /** 
+  *  Optional user overridable function to replace the default CDC class handler.
+  *
+  *  The application software could override the default EP0 class handler with their
+  *  own by providing the handler function address as this data member of the parameter
+  *  structure. Application which like the default handler should set this data member
+  *  to zero before calling the USBD_CDC_API::Init().
+  *  \n
+  *  \note 
+  *  
+  *  \param[in] hUsb Handle to the USB device stack. 
+  *  \param[in] data Pointer to the data which will be passed when callback function is called by the stack. 
+  *  \param[in] event  Type of endpoint event. See \ref USBD_EVENT_T for more details.
+  *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK On success.
+  *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+  *          \retval ERR_USBD_xxx  For other error conditions. 
+  *                                             
+  */
+  ErrorCode_t (*CDC_Ep0_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event);
+
+} USBD_CDC_INIT_PARAM_T;
+
+/** \brief CDC class API functions structure.
+ *  \ingroup USBD_CDC
+ *
+ *  This module exposes functions which interact directly with USB device controller hardware.
+ *
+ */
+typedef struct USBD_CDC_API
+{
+  /** \fn uint32_t GetMemSize(USBD_CDC_INIT_PARAM_T* param)
+   *  Function to determine the memory required by the CDC function driver module.
+   * 
+   *  This function is called by application layer before calling pUsbApi->CDC->Init(), to allocate memory used 
+   *  by CDC function driver module. The application should allocate the memory which is accessible by USB
+   *  controller/DMA controller. 
+   *  \note Some memory areas are not accessible by all bus masters.
+   *
+   *  \param[in] param Structure containing CDC function driver module initialization parameters.
+   *  \return Returns the required memory size in bytes.
+   */
+  uint32_t (*GetMemSize)(USBD_CDC_INIT_PARAM_T* param);
+  
+  /** \fn ErrorCode_t init(USBD_HANDLE_T hUsb, USBD_CDC_INIT_PARAM_T* param)
+   *  Function to initialize CDC function driver module.
+   * 
+   *  This fuction is called by application layer to initialize CDC function driver module. 
+   *
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in, out] param Structure containing CDC function driver module initialization parameters.
+   *  \return Returns \ref ErrorCode_t type to indicate success or error condition.
+   *          \retval LPC_OK On success
+   *          \retval ERR_USBD_BAD_MEM_BUF  Memory buffer passed is not 4-byte 
+   *              aligned or smaller than required. 
+   *          \retval ERR_API_INVALID_PARAM2 Either CDC_Write() or CDC_Read() or
+   *              CDC_Verify() callbacks are not defined. 
+   *          \retval ERR_USBD_BAD_INTF_DESC  Wrong interface descriptor is passed. 
+   *          \retval ERR_USBD_BAD_EP_DESC  Wrong endpoint descriptor is passed. 
+   */
+  ErrorCode_t (*init)(USBD_HANDLE_T hUsb, USBD_CDC_INIT_PARAM_T* param, USBD_HANDLE_T* phCDC);
+
+  /** \fn ErrorCode_t SendNotification(USBD_HANDLE_T hCdc, uint8_t bNotification, uint16_t data)
+   *  Function to initialize CDC function driver module.
+   * 
+   *  This fuction is called by application layer to initialize CDC function driver module. 
+   *
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in, out] param Structure containing CDC function driver module initialization parameters.
+   *  \return Returns \ref ErrorCode_t type to indicate success or error condition.
+   *          \retval LPC_OK On success
+   *          \retval ERR_USBD_BAD_MEM_BUF  Memory buffer passed is not 4-byte 
+   *              aligned or smaller than required. 
+   *          \retval ERR_API_INVALID_PARAM2 Either CDC_Write() or CDC_Read() or
+   *              CDC_Verify() callbacks are not defined. 
+   *          \retval ERR_USBD_BAD_INTF_DESC  Wrong interface descriptor is passed. 
+   *          \retval ERR_USBD_BAD_EP_DESC  Wrong endpoint descriptor is passed. 
+   */
+  ErrorCode_t (*SendNotification)(USBD_HANDLE_T hCdc, uint8_t bNotification, uint16_t data);
+
+} USBD_CDC_API_T;
+
+/*-----------------------------------------------------------------------------
+ *  Private functions & structures prototypes
+ *-----------------------------------------------------------------------------*/
+/** @cond  ADVANCED_API */
+
+typedef struct _CDC_CTRL_T
+{
+  USB_CORE_CTRL_T*  pUsbCtrl;
+  /* notification buffer */
+  uint8_t notice_buf[12];
+  CDC_LINE_CODING line_coding;
+  uint8_t pad0;
+
+  uint8_t cif_num;                 /* control interface number */
+  uint8_t dif_num;                 /* data interface number */
+  uint8_t epin_num;                /* BULK IN endpoint number */
+  uint8_t epout_num;               /* BULK OUT endpoint number */
+  uint8_t epint_num;               /* Interrupt IN endpoint number */
+  uint8_t pad[3];
+  /* user defined functions */
+  ErrorCode_t (*SendEncpsCmd) (USBD_HANDLE_T hCDC, uint8_t* buffer, uint16_t len);
+  ErrorCode_t (*GetEncpsResp) (USBD_HANDLE_T hCDC, uint8_t** buffer, uint16_t* len);
+  ErrorCode_t (*SetCommFeature) (USBD_HANDLE_T hCDC, uint16_t feature, uint8_t* buffer, uint16_t len);
+  ErrorCode_t (*GetCommFeature) (USBD_HANDLE_T hCDC, uint16_t feature, uint8_t** pBuffer, uint16_t* len);
+  ErrorCode_t (*ClrCommFeature) (USBD_HANDLE_T hCDC, uint16_t feature);
+  ErrorCode_t (*SetCtrlLineState) (USBD_HANDLE_T hCDC, uint16_t state);
+  ErrorCode_t (*SendBreak) (USBD_HANDLE_T hCDC, uint16_t state);
+  ErrorCode_t (*SetLineCode) (USBD_HANDLE_T hCDC, CDC_LINE_CODING* line_coding);
+
+  /* virtual functions */
+  ErrorCode_t (*CIC_GetRequest)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t* length); 
+  ErrorCode_t (*CIC_SetRequest)( USBD_HANDLE_T hCdc, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t length);
+
+}USB_CDC_CTRL_T;
+
+/** @cond  DIRECT_API */
+extern uint32_t mwCDC_GetMemSize(USBD_CDC_INIT_PARAM_T* param);
+extern ErrorCode_t mwCDC_init(USBD_HANDLE_T hUsb, USBD_CDC_INIT_PARAM_T* param, USBD_HANDLE_T* phCDC);
+extern ErrorCode_t mwCDC_SendNotification (USBD_HANDLE_T hCdc, uint8_t bNotification, uint16_t data); 
+/** @endcond */
+
+/** @endcond */
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#endif  /* __CDCUSER_H__ */ 
diff --git a/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_core.h b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_core.h
new file mode 100644
index 0000000000000000000000000000000000000000..d2e432a8be528fd338e0e233c992c1d7457552c8
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_core.h
@@ -0,0 +1,583 @@
+/***********************************************************************
+* $Id:: mw_usbd_core.h 202 2011-06-12 21:50:01Z usb06052                      $
+*
+* Project: USB device ROM Stack
+*
+* Description:
+*     USB core controller structure defnitions and function prototypes.
+*
+***********************************************************************
+*   Copyright(C) 2011, NXP Semiconductor
+*   All rights reserved.
+*
+* Software that is described herein is for illustrative purposes only
+* which provides customers with programming information regarding the
+* products. This software is supplied "AS IS" without any warranties.
+* NXP Semiconductors assumes no responsibility or liability for the
+* use of the software, conveys no license or title under any patent,
+* copyright, or mask work right to the product. NXP Semiconductors
+* reserves the right to make changes in the software without
+* notification. NXP Semiconductors also make no representation or
+* warranty that such application will be suitable for the specified
+* use without further testing or modification.
+**********************************************************************/
+#ifndef __MW_USBD_CORE_H__
+#define __MW_USBD_CORE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "error.h"
+#include "mw_usbd.h"
+#include "../app_usbd_cfg.h"
+
+/** \file
+ *  \brief ROM API for USB device stack.
+ *
+ *  Definition of functions exported by core layer of ROM based USB device stack.
+ *
+ */
+
+/** \ingroup Group_USBD
+ *  @defgroup USBD_Core USB Core Layer
+ *  \section Sec_CoreModDescription Module Description
+ *  The USB Core Layer implements the device abstraction defined in the <em> Universal Serial Bus Specification, </em>
+ *  for applications to interact with the USB device interface on the device. The software in this layer responds to 
+ *  standard requests and returns standard descriptors. In current stack the Init() routine part of 
+ *  \ref USBD_HW_API_T structure initializes both hardware layer and core layer.
+ */
+
+
+/* function pointer types */
+
+/** \ingroup USBD_Core 
+ *  \typedef USB_CB_T
+ *  \brief USB device stack's event callback function type.
+ *
+ *  The USB device stack exposes several event triggers through callback to application layer. The
+ *  application layer can register methods to be called when such USB event happens.
+ *  
+ *  \param[in] hUsb Handle to the USB device stack. 
+ *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
+ *          \retval LPC_OK On success
+ *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+ *          \retval ERR_USBD_xxx  Other error conditions. 
+ *                                             
+ */
+typedef ErrorCode_t (*USB_CB_T) (USBD_HANDLE_T hUsb);
+
+/** \ingroup USBD_Core 
+ *  \typedef USB_PARAM_CB_T
+ *  \brief USB device stack's event callback function type.
+ *
+ *  The USB device stack exposes several event triggers through callback to application layer. The
+ *  application layer can register methods to be called when such USB event happens.
+ *  
+ *  \param[in] hUsb Handle to the USB device stack. 
+ *  \param[in] param1 Extra information related to the event. 
+ *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
+ *          \retval LPC_OK On success
+ *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+ *          \retval ERR_USBD_xxx  For other error conditions. 
+ *                                             
+ */
+typedef ErrorCode_t (*USB_PARAM_CB_T) (USBD_HANDLE_T hUsb, uint32_t param1);
+
+/** \ingroup USBD_Core
+ *  \typedef USB_EP_HANDLER_T
+ *  \brief USBD setup request and endpoint event handler type.
+ *
+ *  The application layer should define the custom class's EP0 handler with function signature. 
+ *  The stack calls all the registered class handlers on any EP0 event before going through default 
+ *  handling of the event. This gives the class handlers to implement class specific request handlers
+ *  and also to override the default stack handling for a particular event targeted to the interface.
+ *  If an event is not handled by the callback the function should return ERR_USBD_UNHANDLED. For all
+ *  other return codes the stack assumes that callback has taken care of the event and hence will not
+ *  process the event any further and issues a STALL condition on EP0 indicating error to the host.
+ *  \n
+ *  For endpoint interrupt handler the return value is ignored by the stack.
+ *  \n
+ *  \param[in] hUsb Handle to the USB device stack. 
+ *  \param[in] data Pointer to the data which will be passed when callback function is called by the stack. 
+ *  \param[in] event  Type of endpoint event. See \ref USBD_EVENT_T for more details.
+ *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
+ *          \retval LPC_OK On success.
+ *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+ *          \retval ERR_USBD_xxx  For other error conditions. 
+ *                                             
+ */
+typedef ErrorCode_t (*USB_EP_HANDLER_T)(USBD_HANDLE_T hUsb, void* data, uint32_t event);
+
+
+/** \ingroup USBD_Core 
+ *  \brief USB descriptors data structure.
+ *  \ingroup USBD_Core
+ *
+ *  \details  This structure is used as part of USB device stack initialisation 
+ *  parameter structure \ref USBD_API_INIT_PARAM_T. This structure contains
+ *  pointers to various descriptor arrays needed by the stack. These descriptors
+ *  are reported to USB host as part of enumerations process.
+ *
+ *  \note All descriptor pointers assigned in this structure should be on 4 byte
+ *  aligned address boundary.
+ */
+typedef struct _USB_CORE_DESCS_T
+{
+  uint8_t *device_desc; /**< Pointer to USB device descriptor */
+  uint8_t *string_desc; /**< Pointer to array of USB string descriptors */
+  uint8_t *full_speed_desc; /**< Pointer to USB device configuration descriptor
+                            * when device is operating in full speed mode.
+                            */
+  uint8_t *high_speed_desc; /**< Pointer to USB device configuration descriptor
+                            * when device is operating in high speed mode. For
+                            * full-speed only implementation this pointer should
+                            * be same as full_speed_desc.
+                            */
+  uint8_t *device_qualifier; /**< Pointer to USB device qualifier descriptor. For
+                             * full-speed only implementation this pointer should
+                             * be set to null (0).
+                             */
+} USB_CORE_DESCS_T;
+
+/** \brief USB device stack initilization parameter data structure.
+ *  \ingroup USBD_Core
+ *
+ *  \details  This data structure is used to pass initialization parameters to the 
+ *  USB device stack's init function.
+ *
+ */
+typedef struct USBD_API_INIT_PARAM
+{
+  uint32_t usb_reg_base; /**< USB device controller's base register address. */ 
+  uint32_t mem_base;  /**< Base memory location from where the stack can allocate
+                      data and buffers. \note The memory address set in this field
+                      should be accessible by USB DMA controller. Also this value
+                      should be aligned on 2048 byte boundary.
+                      */
+  uint32_t mem_size;  /**< The size of memory buffer which stack can use. 
+                      \note The \em mem_size should be greater than the size 
+                      returned by USBD_HW_API::GetMemSize() routine.*/
+  uint8_t max_num_ep; /**< max number of endpoints supported by the USB device 
+                      controller instance (specified by \em usb_reg_base field)
+                      to which this instance of stack is attached. 
+                      */
+  uint8_t pad0[3];
+  /* USB Device Events Callback Functions */
+	/** Event for USB interface reset. This event fires when the USB host requests that the device 
+	 *  reset its interface. This event fires after the control endpoint has been automatically
+	 *  configured by the library.
+	 *  \n
+	 *  \note This event is called from USB_ISR context and hence is time-critical. Having delays in this
+	 *  callback will prevent the device from enumerating correctly or operate properly.
+	 *
+	 */
+  USB_CB_T USB_Reset_Event;
+
+	/** Event for USB suspend. This event fires when the USB host suspends the device by halting its
+	 *  transmission of Start Of Frame pulses to the device. This is generally hooked in order to move
+	 *  the device over to a low power state until the host wakes up the device. 
+	 *  \n
+	 *  \note This event is called from USB_ISR context and hence is time-critical. Having delays in this
+	 *  callback will cause other system issues.
+	 */
+  USB_CB_T USB_Suspend_Event;
+
+	/** Event for USB wake up or resume. This event fires when a the USB device interface is suspended 
+	 *  and the host wakes up the device by supplying Start Of Frame pulses. This is generally
+	 *  hooked to pull the user application out of a low power state and back into normal operating
+	 *  mode. 
+	 *  \n
+	 *  \note This event is called from USB_ISR context and hence is time-critical. Having delays in this
+	 *  callback will cause other system issues.
+	 *
+	 */
+  USB_CB_T USB_Resume_Event;
+
+  /** Reserved parameter should be set to zero. */
+  USB_CB_T reserved_sbz;
+
+  /** Event for USB Start Of Frame detection, when enabled. This event fires at the start of each USB
+	 *  frame, once per millisecond in full-speed mode or once per 125 microseconds in high-speed mode,
+   *  and is synchronized to the USB bus. 
+	 *
+	 *  This event is time-critical; it is run once per millisecond (full-speed mode) and thus long handlers 
+	 *  will significantly degrade device performance. This event should only be enabled when needed to 
+   *  reduce device wake-ups.
+	 *
+	 *  \note This event is not normally active - it must be manually enabled and disabled via the USB interrupt
+	 *        register.
+	 *        \n\n
+	 */  
+  USB_CB_T USB_SOF_Event;
+
+  /** Event for remote wakeup configururation, when enabled. This event fires when the USB host
+	 *  request the device to configure itself for remote wake-up capability. The USB host sends
+   *  this request to device which report remote wakeup capable in their device descriptors,
+   *  before going to low-power state. The application layer should implement this callback if
+   *  they have any special on board circuit to trigerr remote wake up event. Also application
+   *  can use this callback to differntiate the following SUSPEND event is caused by cable plug-out
+   *  or host SUSPEND request. The device can wakeup host only after reciving this callback and
+   *  remote wakeup feature is enabled by host. To signal remote wakeup the device has to generate
+   *  resume signaling on bus by calling usapi.hw->WakeUp() routine.
+	 *
+	 *  \n\n
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] param1 When 0 - Clear the wakeup configuration, 1 - Enable the wake-up configuration. 
+   *  \return The call back should return \ref ErrorCode_t type to indicate success or error condition.
+	 */  
+  USB_PARAM_CB_T USB_WakeUpCfg;
+
+  /** Reserved parameter should be set to zero. */
+  USB_PARAM_CB_T USB_Power_Event;
+
+  /** Event for error condition. This event fires when USB device controller detect 
+	 *  an error condition in the system.  
+	 *
+	 *  \n\n
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] param1 USB device interrupt status register. 
+   *  \return The call back should return \ref ErrorCode_t type to indicate success or error condition.
+   */  
+  USB_PARAM_CB_T USB_Error_Event;
+
+  /* USB Core Events Callback Functions */
+  /** Event for USB configuration number changed. This event fires when a the USB host changes the
+   *  selected configuration number. On receiving configuration change request from host, the stack
+   *  enables/configures the endpoints needed by the new configuration before calling this callback
+   *  function.
+	 *  \n
+	 *  \note This event is called from USB_ISR context and hence is time-critical. Having delays in this
+	 *  callback will prevent the device from enumerating correctly or operate properly.
+   *
+   */
+  USB_CB_T USB_Configure_Event;
+
+  /** Event for USB interface setting changed. This event fires when a the USB host changes the
+   *  interface setting to one of alternate interface settings. On receiving interface change 
+   *  request from host, the stack enables/configures the endpoints needed by the new alternate 
+   *  interface setting before calling this callback function.
+	 *  \n
+	 *  \note This event is called from USB_ISR context and hence is time-critical. Having delays in this
+	 *  callback will prevent the device from enumerating correctly or operate properly.
+   *
+   */
+  USB_CB_T USB_Interface_Event;
+
+  /** Event for USB feature changed. This event fires when a the USB host send set/clear feature
+   *  request. The stack handles this request for USB_FEATURE_REMOTE_WAKEUP, USB_FEATURE_TEST_MODE
+   *  and USB_FEATURE_ENDPOINT_STALL features only. On receiving feature request from host, the  
+   *  stack handle the request appropriately and then calls this callback function.
+	 *  \n
+	 *  \note This event is called from USB_ISR context and hence is time-critical. Having delays in this
+	 *  callback will prevent the device from enumerating correctly or operate properly.
+   *
+   */
+ USB_CB_T USB_Feature_Event;
+
+  /* cache and mmu translation functions */
+  /** Reserved parameter for future use. should be set to zero. */
+  uint32_t (* virt_to_phys)(void* vaddr);
+  /** Reserved parameter for future use. should be set to zero. */
+  void (* cache_flush)(uint32_t* start_adr, uint32_t* end_adr);
+
+} USBD_API_INIT_PARAM_T;
+
+
+/** \brief USBD stack Core API functions structure.
+ *  \ingroup USBD_Core
+ *
+ *  \details  This module exposes functions which interact directly with USB device stack's core layer.
+ *  The application layer uses this component when it has to implement custom class function driver or 
+ *  standard class function driver which is not part of the current USB device stack.
+ *  The functions exposed by this interface are to register class specific EP0 handlers and corresponding
+ *  utility functions to manipulate EP0 state machine of the stack. This interface also exposes
+ *  function to register custom endpoint interrupt handler.
+ *
+ */
+typedef struct USBD_CORE_API 
+{
+ /** \fn ErrorCode_t RegisterClassHandler(USBD_HANDLE_T hUsb, USB_EP_HANDLER_T pfn, void* data)
+  *  Function to register class specific EP0 event handler with USB device stack.
+  *
+  *  The application layer uses this function when it has to register the custom class's EP0 handler. 
+  *  The stack calls all the registered class handlers on any EP0 event before going through default 
+  *  handling of the event. This gives the class handlers to implement class specific request handlers
+  *  and also to override the default stack handling for a particular event targeted to the interface.
+  *  Check USB_EP_HANDLER_T for more details on how the callback function should be implemented. Also
+  *  application layer could use this function to register EP0 handler which responds to vendor specific 
+  *  requests.
+  *  
+  *  \param[in] hUsb Handle to the USB device stack. 
+  *  \param[in] pfn  Class specific EP0 handler function.
+  *  \param[in] data Pointer to the data which will be passed when callback function is called by the stack. 
+  *  \return Returns \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK On success
+  *          \retval ERR_USBD_TOO_MANY_CLASS_HDLR(0x0004000c)  The number of class handlers registered is 
+                        greater than the number of handlers allowed by the stack.
+  *                                             
+  */
+  ErrorCode_t (*RegisterClassHandler)(USBD_HANDLE_T hUsb, USB_EP_HANDLER_T pfn, void* data);
+
+ /** \fn ErrorCode_t RegisterEpHandler(USBD_HANDLE_T hUsb, uint32_t ep_index, USB_EP_HANDLER_T pfn, void* data)
+  *  Function to register interrupt/event handler for the requested endpoint with USB device stack.
+  *
+  *  The application layer uses this function to register the custom class's EP0 handler. 
+  *  The stack calls all the registered class handlers on any EP0 event before going through default 
+  *  handling of the event. This gives the class handlers to implement class specific request handlers
+  *  and also to override the default stack handling for a particular event targeted to the interface.
+  *  Check USB_EP_HANDLER_T for more details on how the callback function should be implemented.
+  *  
+  *  \param[in] hUsb Handle to the USB device stack. 
+  *  \param[in] ep_index  Class specific EP0 handler function.
+  *  \param[in] pfn  Class specific EP0 handler function.
+  *  \param[in] data Pointer to the data which will be passed when callback function is called by the stack. 
+  *  \return Returns \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK On success
+  *          \retval ERR_USBD_TOO_MANY_CLASS_HDLR(0x0004000c)  Too many endpoint handlers. 
+  *                                             
+  */
+  ErrorCode_t (*RegisterEpHandler)(USBD_HANDLE_T hUsb, uint32_t ep_index, USB_EP_HANDLER_T pfn, void* data);
+  
+  /** \fn void SetupStage(USBD_HANDLE_T hUsb)
+   *  Function to set EP0 state machine in setup state.
+   *
+   *  This function is called by USB stack and the application layer to 
+   *  set the EP0 state machine in setup state. This function will read
+   *  the setup packet received from USB host into stack's buffer. 
+   *  \n
+   *  \note This interface is provided to users to invoke this function in other 
+   *  scenarios which are not handle by current stack. In most user applications 
+   *  this function is not called directly.Also this function can be used by  
+   *  users who are selectively modifying the USB device stack's standard handlers 
+   *  through callback interface exposed by the stack.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \return Nothing.
+   */
+  void (*SetupStage )(USBD_HANDLE_T hUsb); 
+  
+  /** \fn void DataInStage(USBD_HANDLE_T hUsb)
+   *  Function to set EP0 state machine in data_in state.
+   *
+   *  This function is called by USB stack and the application layer to 
+   *  set the EP0 state machine in data_in state. This function will write
+   *  the data present in EP0Data buffer to EP0 FIFO for tranmission to host. 
+   *  \n
+   *  \note This interface is provided to users to invoke this function in other 
+   *  scenarios which are not handle by current stack. In most user applications 
+   *  this function is not called directly.Also this function can be used by  
+   *  users who are selectively modifying the USB device stack's standard handlers 
+   *  through callback interface exposed by the stack.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \return Nothing.
+   */
+  void (*DataInStage)(USBD_HANDLE_T hUsb);
+
+  /** \fn void DataOutStage(USBD_HANDLE_T hUsb)
+   *  Function to set EP0 state machine in data_out state.
+   *
+   *  This function is called by USB stack and the application layer to 
+   *  set the EP0 state machine in data_out state. This function will read
+   *  the control data (EP0 out packets) received from USB host into EP0Data buffer. 
+   *  \n
+   *  \note This interface is provided to users to invoke this function in other 
+   *  scenarios which are not handle by current stack. In most user applications 
+   *  this function is not called directly.Also this function can be used by  
+   *  users who are selectively modifying the USB device stack's standard handlers 
+   *  through callback interface exposed by the stack.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \return Nothing.
+   */
+  void (*DataOutStage)(USBD_HANDLE_T hUsb); 
+
+  /** \fn void StatusInStage(USBD_HANDLE_T hUsb)
+   *  Function to set EP0 state machine in status_in state.
+   *
+   *  This function is called by USB stack and the application layer to 
+   *  set the EP0 state machine in status_in state. This function will send
+   *  zero length IN packet on EP0 to host, indicating positive status. 
+   *  \n
+   *  \note This interface is provided to users to invoke this function in other 
+   *  scenarios which are not handle by current stack. In most user applications 
+   *  this function is not called directly.Also this function can be used by  
+   *  users who are selectively modifying the USB device stack's standard handlers 
+   *  through callback interface exposed by the stack.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \return Nothing.
+   */
+  void (*StatusInStage)(USBD_HANDLE_T hUsb); 
+  /** \fn void StatusOutStage(USBD_HANDLE_T hUsb)
+   *  Function to set EP0 state machine in status_out state.
+   *
+   *  This function is called by USB stack and the application layer to 
+   *  set the EP0 state machine in status_out state. This function will read
+   *  the zero length OUT packet received from USB host on EP0. 
+   *  \n
+   *  \note This interface is provided to users to invoke this function in other 
+   *  scenarios which are not handle by current stack. In most user applications 
+   *  this function is not called directly.Also this function can be used by  
+   *  users who are selectively modifying the USB device stack's standard handlers 
+   *  through callback interface exposed by the stack.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \return Nothing.
+   */
+  void (*StatusOutStage)(USBD_HANDLE_T hUsb);
+
+  /** \fn void StallEp0(USBD_HANDLE_T hUsb)
+   *  Function to set EP0 state machine in stall state.
+   *
+   *  This function is called by USB stack and the application layer to 
+   *  generate STALL signalling on EP0 endpoint. This function will also 
+   *  reset the EP0Data buffer. 
+   *  \n
+   *  \note This interface is provided to users to invoke this function in other 
+   *  scenarios which are not handle by current stack. In most user applications 
+   *  this function is not called directly.Also this function can be used by  
+   *  users who are selectively modifying the USB device stack's standard handlers 
+   *  through callback interface exposed by the stack.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \return Nothing.
+   */
+  void (*StallEp0)(USBD_HANDLE_T hUsb);
+
+} USBD_CORE_API_T;
+
+/*-----------------------------------------------------------------------------
+ *  Private functions & structures prototypes
+ *-----------------------------------------------------------------------------*/
+
+ /** @cond  ADVANCED_API */
+
+/* forward declaration */
+struct _USB_CORE_CTRL_T;
+typedef struct _USB_CORE_CTRL_T  USB_CORE_CTRL_T;
+
+/* USB device Speed status defines */
+#define USB_FULL_SPEED    0
+#define USB_HIGH_SPEED    1
+
+/* USB Endpoint Data Structure */
+typedef struct _USB_EP_DATA
+{
+  uint8_t  *pData;
+  uint16_t   Count;
+  uint16_t pad0;
+} USB_EP_DATA;
+
+
+/* USB core controller data structure */
+struct _USB_CORE_CTRL_T
+{
+  /* overridable function pointers ~ c++ style virtual functions*/
+  USB_CB_T USB_EvtSetupHandler;
+  USB_CB_T USB_EvtOutHandler;
+  USB_PARAM_CB_T USB_ReqVendor;
+  USB_CB_T USB_ReqGetStatus;
+  USB_CB_T USB_ReqGetDescriptor;
+  USB_CB_T USB_ReqGetConfiguration;
+  USB_CB_T USB_ReqSetConfiguration;
+  USB_CB_T USB_ReqGetInterface;
+  USB_CB_T USB_ReqSetInterface;
+  USB_PARAM_CB_T USB_ReqSetClrFeature;
+
+  /* USB Device Events Callback Functions */
+  USB_CB_T USB_Reset_Event;
+  USB_CB_T USB_Suspend_Event;
+  USB_CB_T USB_Resume_Event;
+  USB_CB_T USB_SOF_Event;
+  USB_PARAM_CB_T USB_Power_Event;
+  USB_PARAM_CB_T USB_Error_Event;
+  USB_PARAM_CB_T USB_WakeUpCfg;
+
+  /* USB Core Events Callback Functions */
+  USB_CB_T USB_Configure_Event;
+  USB_CB_T USB_Interface_Event;
+  USB_CB_T USB_Feature_Event;
+
+  /* cache and mmu translation functions */
+  uint32_t (* virt_to_phys)(void* vaddr);
+  void (* cache_flush)(uint32_t* start_adr, uint32_t* end_adr);
+
+  /* event handlers for endpoints. */
+  USB_EP_HANDLER_T  ep_event_hdlr[2 * USB_MAX_EP_NUM];
+  void*  ep_hdlr_data[2 * USB_MAX_EP_NUM];
+
+  /* USB class handlers */
+  USB_EP_HANDLER_T  ep0_hdlr_cb[USB_MAX_IF_NUM];
+  void*  ep0_cb_data[USB_MAX_IF_NUM];
+  uint8_t num_ep0_hdlrs;
+  /* USB Core data Variables */
+  uint8_t max_num_ep; /* max number of endpoints supported by the HW */
+  uint8_t device_speed;
+  uint8_t  num_interfaces;
+  uint8_t  device_addr;
+  uint8_t  config_value;
+  uint16_t device_status;
+  uint8_t *device_desc;
+  uint8_t *string_desc;
+  uint8_t *full_speed_desc;
+  uint8_t *high_speed_desc;
+  uint8_t *device_qualifier;
+  uint32_t ep_mask;
+  uint32_t ep_halt;
+  uint32_t ep_stall;
+  uint8_t  alt_setting[USB_MAX_IF_NUM];
+  /* HW driver data pointer */
+  void* hw_data;
+
+  /* USB Endpoint 0 Data Info */
+  USB_EP_DATA EP0Data;
+
+  /* USB Endpoint 0 Buffer */
+  //ALIGNED(4)
+  uint8_t  EP0Buf[64];
+
+  /* USB Setup Packet */
+  //ALIGNED(4)
+  USB_SETUP_PACKET SetupPacket;
+
+};
+
+/* USB Core Functions */
+extern void mwUSB_InitCore(USB_CORE_CTRL_T* pCtrl, USB_CORE_DESCS_T* pdescr, USBD_API_INIT_PARAM_T* param);
+extern void mwUSB_ResetCore(USBD_HANDLE_T hUsb);
+
+/* inline functions */
+static __inline void USB_SetSpeedMode(USB_CORE_CTRL_T* pCtrl, uint8_t mode)
+{
+  pCtrl->device_speed = mode;
+}
+
+/** @cond  DIRECT_API */
+/* midleware API */
+extern ErrorCode_t mwUSB_RegisterClassHandler(USBD_HANDLE_T hUsb, USB_EP_HANDLER_T pfn, void* data);
+extern ErrorCode_t mwUSB_RegisterEpHandler(USBD_HANDLE_T hUsb, uint32_t ep_index, USB_EP_HANDLER_T pfn, void* data);
+extern void mwUSB_SetupStage (USBD_HANDLE_T hUsb); 
+extern void mwUSB_DataInStage(USBD_HANDLE_T hUsb);
+extern void mwUSB_DataOutStage(USBD_HANDLE_T hUsb); 
+extern void mwUSB_StatusInStage(USBD_HANDLE_T hUsb); 
+extern void mwUSB_StatusOutStage(USBD_HANDLE_T hUsb);
+extern void mwUSB_StallEp0(USBD_HANDLE_T hUsb);
+extern ErrorCode_t mwUSB_RegisterClassHandler(USBD_HANDLE_T hUsb, USB_EP_HANDLER_T pfn, void* data);
+extern ErrorCode_t mwUSB_RegisterEpHandler(USBD_HANDLE_T hUsb, uint32_t ep_index, USB_EP_HANDLER_T pfn, void* data);
+extern void mwUSB_SetupStage (USBD_HANDLE_T hUsb); 
+extern void mwUSB_DataInStage(USBD_HANDLE_T hUsb);
+extern void mwUSB_DataOutStage(USBD_HANDLE_T hUsb); 
+extern void mwUSB_StatusInStage(USBD_HANDLE_T hUsb); 
+extern void mwUSB_StatusOutStage(USBD_HANDLE_T hUsb);
+extern void mwUSB_StallEp0(USBD_HANDLE_T hUsb);
+/** @endcond */
+
+/** @endcond */
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif  /* __MW_USBD_CORE_H__ */
diff --git a/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_desc.h b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_desc.h
new file mode 100644
index 0000000000000000000000000000000000000000..f91755932d4e562bdd38b8c4f5abf20d2dcafe50
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_desc.h
@@ -0,0 +1,55 @@
+/***********************************************************************
+* $Id:: mw_usbd_desc.h 197 2011-06-12 20:22:41Z usb06052                      $
+*
+* Project: USB device ROM Stack
+*
+* Description:
+*     USB Descriptors Definitions.
+*
+***********************************************************************
+*   Copyright(C) 2011, NXP Semiconductor
+*   All rights reserved.
+*
+* Software that is described herein is for illustrative purposes only
+* which provides customers with programming information regarding the
+* products. This software is supplied "AS IS" without any warranties.
+* NXP Semiconductors assumes no responsibility or liability for the
+* use of the software, conveys no license or title under any patent,
+* copyright, or mask work right to the product. NXP Semiconductors
+* reserves the right to make changes in the software without
+* notification. NXP Semiconductors also make no representation or
+* warranty that such application will be suitable for the specified
+* use without further testing or modification.
+**********************************************************************/
+
+#ifndef __USBDESC_H__
+#define __USBDESC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "mw_usbd.h"
+
+#define WBVAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF)
+#define B3VAL(x) ((x) & 0xFF),(((x) >> 8) & 0xFF),(((x) >> 16) & 0xFF)
+
+#define USB_DEVICE_DESC_SIZE        (sizeof(USB_DEVICE_DESCRIPTOR))
+#define USB_CONFIGUARTION_DESC_SIZE (sizeof(USB_CONFIGURATION_DESCRIPTOR))
+#define USB_INTERFACE_DESC_SIZE     (sizeof(USB_INTERFACE_DESCRIPTOR))
+#define USB_ENDPOINT_DESC_SIZE      (sizeof(USB_ENDPOINT_DESCRIPTOR))
+#define USB_DEVICE_QUALI_SIZE       (sizeof(USB_DEVICE_QUALIFIER_DESCRIPTOR))
+#define USB_OTHER_SPEED_CONF_SIZE   (sizeof(USB_OTHER_SPEED_CONFIGURATION))
+
+#define HID_DESC_SIZE               (sizeof(HID_DESCRIPTOR))
+#define HID_REPORT_DESC_SIZE        (sizeof(HID_ReportDescriptor))
+
+extern const uint8_t  HID_ReportDescriptor[];
+extern const uint16_t HID_ReportDescSize;
+extern const uint16_t HID_DescOffset;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif  /* __USBDESC_H__ */
diff --git a/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_dfu.h b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_dfu.h
new file mode 100644
index 0000000000000000000000000000000000000000..0fedc62a8cfa3f51a948ca1ed2783142b85fcb02
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_dfu.h
@@ -0,0 +1,128 @@
+/***********************************************************************
+* $Id:: mw_usbd_dfu.h 216 2011-07-13 21:52:14Z usb06052                       $
+*
+* Project: USB device ROM Stack
+*
+* Description:
+*     Device Firmware Upgrade (DFU) module.
+*
+***********************************************************************
+*   Copyright(C) 2011, NXP Semiconductor
+*   All rights reserved.
+*
+* Software that is described herein is for illustrative purposes only
+* which provides customers with programming information regarding the
+* products. This software is supplied "AS IS" without any warranties.
+* NXP Semiconductors assumes no responsibility or liability for the
+* use of the software, conveys no license or title under any patent,
+* copyright, or mask work right to the product. NXP Semiconductors
+* reserves the right to make changes in the software without
+* notification. NXP Semiconductors also make no representation or
+* warranty that such application will be suitable for the specified
+* use without further testing or modification.
+**********************************************************************/
+#ifndef __MW_USBD_DFU_H__
+#define __MW_USBD_DFU_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "mw_usbd.h"
+
+/** \file
+ *  \brief Device Firmware Upgrade (DFU) calss descriptors.
+ *
+ *  Definition of DFU class descriptors and their bit defines.
+ *
+ */
+
+/**
+ * If USB device is only DFU capable, DFU Interface number is always 0.
+ * if USB device is (DFU + Other Class (Audio/Mass Storage/HID), DFU 
+ * Interface number should also be 0 in this implementation.
+ */ 
+#define USB_DFU_IF_NUM	0x0
+
+#define USB_DFU_DESCRIPTOR_TYPE     0x21
+#define USB_DFU_DESCRIPTOR_SIZE     9
+#define USB_DFU_SUBCLASS            0x01
+
+/* DFU class-specific requests (Section 3, DFU Rev 1.1) */
+#define USB_REQ_DFU_DETACH          0x00
+#define USB_REQ_DFU_DNLOAD          0x01
+#define USB_REQ_DFU_UPLOAD          0x02
+#define USB_REQ_DFU_GETSTATUS       0x03
+#define USB_REQ_DFU_CLRSTATUS       0x04
+#define USB_REQ_DFU_GETSTATE        0x05
+#define USB_REQ_DFU_ABORT           0x06
+
+#define DFU_STATUS_OK               0x00
+#define DFU_STATUS_errTARGET        0x01
+#define DFU_STATUS_errFILE          0x02
+#define DFU_STATUS_errWRITE         0x03
+#define DFU_STATUS_errERASE         0x04
+#define DFU_STATUS_errCHECK_ERASED  0x05
+#define DFU_STATUS_errPROG          0x06
+#define DFU_STATUS_errVERIFY        0x07
+#define DFU_STATUS_errADDRESS       0x08
+#define DFU_STATUS_errNOTDONE       0x09
+#define DFU_STATUS_errFIRMWARE      0x0a
+#define DFU_STATUS_errVENDOR        0x0b
+#define DFU_STATUS_errUSBR          0x0c
+#define DFU_STATUS_errPOR           0x0d
+#define DFU_STATUS_errUNKNOWN       0x0e
+#define DFU_STATUS_errSTALLEDPKT    0x0f
+
+enum dfu_state {
+  DFU_STATE_appIDLE             = 0,
+  DFU_STATE_appDETACH           = 1,
+  DFU_STATE_dfuIDLE             = 2,
+  DFU_STATE_dfuDNLOAD_SYNC      = 3,
+  DFU_STATE_dfuDNBUSY           = 4,
+  DFU_STATE_dfuDNLOAD_IDLE      = 5,
+  DFU_STATE_dfuMANIFEST_SYNC    = 6,
+  DFU_STATE_dfuMANIFEST         = 7,
+  DFU_STATE_dfuMANIFEST_WAIT_RST= 8,
+  DFU_STATE_dfuUPLOAD_IDLE      = 9,
+  DFU_STATE_dfuERROR            = 10
+};
+
+#define DFU_EP0_NONE            0
+#define DFU_EP0_UNHANDLED       1
+#define DFU_EP0_STALL           2
+#define DFU_EP0_ZLP             3
+#define DFU_EP0_DATA            4
+
+#define USB_DFU_CAN_DOWNLOAD    (1 << 0)
+#define USB_DFU_CAN_UPLOAD      (1 << 1)
+#define USB_DFU_MANIFEST_TOL    (1 << 2)
+#define USB_DFU_WILL_DETACH     (1 << 3)
+
+PRE_PACK struct POST_PACK _USB_DFU_FUNC_DESCRIPTOR {
+  uint8_t   bLength;
+  uint8_t   bDescriptorType;
+  uint8_t   bmAttributes;
+  uint16_t  wDetachTimeOut;
+  uint16_t  wTransferSize;
+  uint16_t  bcdDFUVersion;
+};
+typedef struct _USB_DFU_FUNC_DESCRIPTOR USB_DFU_FUNC_DESCRIPTOR;
+
+PRE_PACK struct POST_PACK _DFU_STATUS {
+  uint8_t bStatus;
+  uint8_t bwPollTimeout[3];
+  uint8_t bState;
+  uint8_t iString;
+};
+typedef struct _DFU_STATUS DFU_STATUS_T;
+
+#define DFU_FUNC_DESC_SIZE    sizeof(USB_DFU_FUNC_DESCRIPTOR)
+#define DFU_GET_STATUS_SIZE   0x6 
+
+#ifdef __cplusplus
+}
+#endif 
+
+
+#endif  /* __MW_USBD_DFU_H__ */
diff --git a/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_dfuuser.h b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_dfuuser.h
new file mode 100644
index 0000000000000000000000000000000000000000..232c9850760520270ed615298ca3ae26264f8312
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_dfuuser.h
@@ -0,0 +1,272 @@
+/***********************************************************************
+* $Id:: mw_usbd_dfuuser.h 202 2011-06-12 21:50:01Z usb06052                   $
+*
+* Project: USB device ROM Stack
+*
+* Description:
+*     Device Firmware Upgrade Class Custom User Module Definitions.
+*
+***********************************************************************
+*   Copyright(C) 2011, NXP Semiconductor
+*   All rights reserved.
+*
+* Software that is described herein is for illustrative purposes only
+* which provides customers with programming information regarding the
+* products. This software is supplied "AS IS" without any warranties.
+* NXP Semiconductors assumes no responsibility or liability for the
+* use of the software, conveys no license or title under any patent,
+* copyright, or mask work right to the product. NXP Semiconductors
+* reserves the right to make changes in the software without
+* notification. NXP Semiconductors also make no representation or
+* warranty that such application will be suitable for the specified
+* use without further testing or modification.
+**********************************************************************/
+
+#ifndef __DFUUSER_H__
+#define __DFUUSER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "mw_usbd.h"
+#include "mw_usbd_dfu.h"
+#include "mw_usbd_core.h"
+
+/** \file
+ *  \brief Device Firmware Upgrade (DFU) API structures and function prototypes.
+ *
+ *  Definition of functions exported by ROM based DFU function driver.
+ *
+ */
+
+
+/** \ingroup Group_USBD
+ *  @defgroup USBD_DFU Device Firmware Upgrade (DFU) Class Function Driver
+ *  \section Sec_MSCModDescription Module Description
+ *  DFU Class Function Driver module. This module contains an internal implementation of the USB DFU Class.
+ *  User applications can use this class driver instead of implementing the DFU class manually
+ *  via the low-level USBD_HW and USBD_Core APIs.
+ *
+ *  This module is designed to simplify the user code by exposing only the required interface needed to interface with
+ *  Devices using the USB DFU Class.
+ */
+
+/** \brief USB descriptors data structure.
+ *  \ingroup USBD_DFU
+ *
+ *  \details  This module exposes functions which interact directly with USB device stack's core layer.
+ *  The application layer uses this component when it has to implement custom class function driver or 
+ *  standard class function driver which is not part of the current USB device stack.
+ *  The functions exposed by this interface are to register class specific EP0 handlers and corresponding
+ *  utility functions to manipulate EP0 state machine of the stack. This interface also exposes
+ *  function to register custom endpoint interrupt handler.
+ *
+ */
+typedef struct USBD_DFU_INIT_PARAM
+{
+  /* memory allocation params */
+  uint32_t mem_base;  /**< Base memory location from where the stack can allocate
+                      data and buffers. \note The memory address set in this field
+                      should be accessible by USB DMA controller. Also this value
+                      should be aligned on 4 byte boundary.
+                      */
+  uint32_t mem_size;  /**< The size of memory buffer which stack can use. 
+                      \note The \em mem_size should be greater than the size 
+                      returned by USBD_DFU_API::GetMemSize() routine.*/
+  /* DFU paramas */
+  uint16_t wTransferSize; /**< DFU transfer block size in number of bytes.
+                          This value should match the value set in DFU descriptor
+                          provided as part of the descriptor array 
+                          (\em high_speed_desc) passed to Init() through 
+                          \ref USB_CORE_DESCS_T structure.  */
+
+  uint16_t pad;
+  /** Pointer to the DFU interface descriptor within the descriptor
+  * array (\em high_speed_desc) passed to Init() through \ref USB_CORE_DESCS_T 
+  * structure.  
+  */
+  uint8_t* intf_desc;
+  /* user defined functions */
+  /** 
+  *  DFU Write callback function.
+  *
+  *  This function is provided by the application software. This function gets called 
+  *  when host sends a write command. For application using zero-copy buffer scheme
+  *  this function is called for the first time with \em length parameter set to 0.
+  *  The application code should update the buffer pointer.
+  *  
+  *  \param[in] block_num Destination start address. 
+  *  \param[in, out] src  Pointer to a pointer to the source of data. Pointer-to-pointer
+  *                     is used to implement zero-copy buffers. See \ref USBD_ZeroCopy
+  *                     for more details on zero-copy concept.
+  *  \param[out] bwPollTimeout  Pointer to a 3 byte buffer which the callback implementer
+  *                     should fill with the amount of minimum time, in milliseconds, 
+  *                     that the host should wait before sending a subsequent
+  *                     DFU_GETSTATUS request. 
+  *  \param[in] length  Number of bytes to be written.
+  *  \return Returns DFU_STATUS_ values defined in mw_usbd_dfu.h. 
+  *                                             
+  */
+  uint8_t (*DFU_Write)( uint32_t block_num, uint8_t** src, uint32_t length, uint8_t* bwPollTimeout);
+
+  /** 
+  *  DFU Read callback function.
+  *
+  *  This function is provided by the application software. This function gets called 
+  *  when host sends a read command.
+  *  
+  *  \param[in] block_num Destination start address. 
+  *  \param[in, out] dst  Pointer to a pointer to the source of data. Pointer-to-pointer
+  *                       is used to implement zero-copy buffers. See \ref USBD_ZeroCopy
+  *                       for more details on zero-copy concept.
+  *  \param[in] length  Amount of data copied to destination buffer.
+  *  \return Returns DFU_STATUS_ values defined in mw_usbd_dfu.h. 
+  *                                             
+  */
+  uint32_t (*DFU_Read)( uint32_t block_num, uint8_t** dst, uint32_t length);
+
+  /** 
+  *  DFU done callback function.
+  *
+  *  This function is provided by the application software. This function gets called 
+  *  after download is finished.
+  *  
+  *  \return Nothing. 
+  *                                             
+  */
+  void (*DFU_Done)(void);
+
+  /** 
+  *  DFU detach callback function.
+  *
+  *  This function is provided by the application software. This function gets called 
+  *  after USB_REQ_DFU_DETACH is recieved. Applications which set USB_DFU_WILL_DETACH
+  *  bit in DFU descriptor should define this function. As part of this function
+  *  application can call Connect() routine to disconnect and then connect back with 
+  *  host. For application which rely on WinUSB based host application should use this
+  *  feature since USB reset can be invoked only by kernel drivers on Windows host. 
+  *  By implementing this feature host doen't have to issue reset instead the device
+  *  has to do it automatically by disconnect and connect procedure.
+  *  
+  *  \param[in] hUsb Handle DFU control structure. 
+  *  \return Nothing. 
+  *                                             
+  */
+  void (*DFU_Detach)(USBD_HANDLE_T hUsb);
+
+  /** 
+  *  Optional user overridable function to replace the default DFU class handler.
+  *
+  *  The application software could override the default EP0 class handler with their
+  *  own by providing the handler function address as this data member of the parameter
+  *  structure. Application which like the default handler should set this data member
+  *  to zero before calling the USBD_DFU_API::Init().
+  *  \n
+  *  \note 
+  *  
+  *  \param[in] hUsb Handle to the USB device stack. 
+  *  \param[in] data Pointer to the data which will be passed when callback function is called by the stack. 
+  *  \param[in] event  Type of endpoint event. See \ref USBD_EVENT_T for more details.
+  *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK On success.
+  *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+  *          \retval ERR_USBD_xxx  For other error conditions. 
+  *                                             
+  */
+  ErrorCode_t (*DFU_Ep0_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event);
+
+} USBD_DFU_INIT_PARAM_T;
+
+
+/** \brief DFU class API functions structure.
+ *  \ingroup USBD_DFU
+ *
+ *  This module exposes functions which interact directly with USB device controller hardware.
+ *
+ */
+typedef struct USBD_DFU_API
+{
+  /** \fn uint32_t GetMemSize(USBD_DFU_INIT_PARAM_T* param)
+   *  Function to determine the memory required by the DFU function driver module.
+   * 
+   *  This function is called by application layer before calling pUsbApi->dfu->Init(), to allocate memory used 
+   *  by DFU function driver module. The application should allocate the memory which is accessible by USB
+   *  controller/DMA controller. 
+   *  \note Some memory areas are not accessible by all bus masters.
+   *
+   *  \param[in] param Structure containing DFU function driver module initialization parameters.
+   *  \return Returns the required memory size in bytes.
+   */
+  uint32_t (*GetMemSize)(USBD_DFU_INIT_PARAM_T* param);
+
+  /** \fn ErrorCode_t init(USBD_HANDLE_T hUsb, USBD_DFU_INIT_PARAM_T* param)
+   *  Function to initialize DFU function driver module.
+   * 
+   *  This function is called by application layer to initialize DFU function driver module. 
+   *
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in, out] param Structure containing DFU function driver module initialization parameters.
+   *  \return Returns \ref ErrorCode_t type to indicate success or error condition.
+   *          \retval LPC_OK On success
+   *          \retval ERR_USBD_BAD_MEM_BUF  Memory buffer passed is not 4-byte aligned or smaller than required. 
+   *          \retval ERR_API_INVALID_PARAM2 Either DFU_Write() or DFU_Done() or DFU_Read() callbacks are not defined. 
+   *          \retval ERR_USBD_BAD_DESC  
+   *            - USB_DFU_DESCRIPTOR_TYPE is not defined immediately after 
+   *              interface descriptor.
+   *            - wTransferSize in descriptor doesn't match the value passed 
+   *              in param->wTransferSize.
+   *            - DFU_Detach() is not defined while USB_DFU_WILL_DETACH is set 
+   *              in DFU descriptor.
+   *          \retval ERR_USBD_BAD_INTF_DESC  Wrong interface descriptor is passed. 
+   */
+  ErrorCode_t (*init)(USBD_HANDLE_T hUsb, USBD_DFU_INIT_PARAM_T* param, uint32_t init_state);
+
+} USBD_DFU_API_T;
+
+/*-----------------------------------------------------------------------------
+ *  Private functions & structures prototypes
+ *-----------------------------------------------------------------------------*/
+/** @cond  ADVANCED_API */
+
+typedef struct _USBD_DFU_CTRL_T
+{
+  /*ALIGNED(4)*/ DFU_STATUS_T dfu_req_get_status;
+  uint16_t pad;
+  uint8_t dfu_state;
+  uint8_t dfu_status;
+  uint8_t download_done;
+  uint8_t if_num;                  /* interface number */
+
+  uint8_t* xfr_buf;
+  USB_DFU_FUNC_DESCRIPTOR* dfu_desc;
+
+  USB_CORE_CTRL_T*  pUsbCtrl;
+  /* user defined functions */
+  /* return DFU_STATUS_ values defined in mw_usbd_dfu.h */
+  uint8_t (*DFU_Write)( uint32_t block_num, uint8_t** src, uint32_t length, uint8_t* bwPollTimeout);
+  /* return 
+  * DFU_STATUS_ : values defined in mw_usbd_dfu.h in case of errors
+  * 0 : If end of memory reached
+  * length : Amount of data copied to destination buffer
+  */
+  uint32_t (*DFU_Read)( uint32_t block_num, uint8_t** dst, uint32_t length);
+  /* callback called after download is finished */
+  void (*DFU_Done)(void);
+  /* callback called after USB_REQ_DFU_DETACH is recived */
+  void (*DFU_Detach)(USBD_HANDLE_T hUsb);
+
+} USBD_DFU_CTRL_T;
+
+/** @cond  DIRECT_API */
+uint32_t mwDFU_GetMemSize(USBD_DFU_INIT_PARAM_T* param);
+extern ErrorCode_t mwDFU_init(USBD_HANDLE_T hUsb, USBD_DFU_INIT_PARAM_T* param, uint32_t init_state);
+/** @endcond */
+
+/** @endcond */
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif  /* __DFUUSER_H__ */
diff --git a/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_hid.h b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_hid.h
new file mode 100644
index 0000000000000000000000000000000000000000..d7f5b285d86e420c6499afc4bac829eeb9333fe7
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_hid.h
@@ -0,0 +1,437 @@
+/***********************************************************************
+* $Id:: mw_usbd_hid.h 202 2011-06-12 21:50:01Z usb06052                       $
+*
+* Project: USB device ROM Stack
+*
+* Description:
+*     HID Definitions.
+*
+***********************************************************************
+*   Copyright(C) 2011, NXP Semiconductor
+*   All rights reserved.
+*
+* Software that is described herein is for illustrative purposes only
+* which provides customers with programming information regarding the
+* products. This software is supplied "AS IS" without any warranties.
+* NXP Semiconductors assumes no responsibility or liability for the
+* use of the software, conveys no license or title under any patent,
+* copyright, or mask work right to the product. NXP Semiconductors
+* reserves the right to make changes in the software without
+* notification. NXP Semiconductors also make no representation or
+* warranty that such application will be suitable for the specified
+* use without further testing or modification.
+**********************************************************************/
+#ifndef __HID_H__
+#define __HID_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "mw_usbd.h"
+
+/** \file
+ *  \brief Common definitions and declarations for the library USB HID Class driver.
+ *
+ *  Common definitions and declarations for the library USB HID Class driver.
+ *  \addtogroup USBD_HID 
+ *  @{
+ */
+
+
+/** HID Subclass Codes  
+ * @{ 
+ */
+/** Descriptor Subclass value indicating that the device or interface does not implement a HID boot protocol. */
+#define HID_SUBCLASS_NONE               0x00
+/** Descriptor Subclass value indicating that the device or interface implements a HID boot protocol. */
+#define HID_SUBCLASS_BOOT               0x01
+/** @} */
+
+/** HID Protocol Codes 
+ * @{ 
+ */
+/** Descriptor Protocol value indicating that the device or interface does not belong to a HID boot protocol. */
+#define HID_PROTOCOL_NONE               0x00
+/** Descriptor Protocol value indicating that the device or interface belongs to the Keyboard HID boot protocol. */
+#define HID_PROTOCOL_KEYBOARD           0x01
+/** Descriptor Protocol value indicating that the device or interface belongs to the Mouse HID boot protocol. */
+#define HID_PROTOCOL_MOUSE              0x02
+/** @} */
+
+
+
+/** Descriptor Types  
+ * @{ 
+ */
+/** Descriptor header type value, to indicate a HID class HID descriptor. */
+#define HID_HID_DESCRIPTOR_TYPE         0x21
+/** Descriptor header type value, to indicate a HID class HID report descriptor. */
+#define HID_REPORT_DESCRIPTOR_TYPE      0x22
+/** Descriptor header type value, to indicate a HID class HID Physical descriptor. */
+#define HID_PHYSICAL_DESCRIPTOR_TYPE    0x23
+/** @} */
+
+
+/** \brief HID class-specific HID Descriptor.
+ *
+ *  Type define for the HID class-specific HID descriptor, to describe the HID device's specifications. Refer to the HID
+ *  specification for details on the structure elements.
+ *
+ */
+PRE_PACK struct POST_PACK _HID_DESCRIPTOR {
+  uint8_t  bLength;	/**< Size of the descriptor, in bytes. */
+  uint8_t  bDescriptorType;	/**< Type of HID descriptor. */
+  uint16_t bcdHID; /**< BCD encoded version that the HID descriptor and device complies to. */
+  uint8_t  bCountryCode; /**< Country code of the localized device, or zero if universal. */
+  uint8_t  bNumDescriptors; /**< Total number of HID report descriptors for the interface. */
+  
+  PRE_PACK struct POST_PACK _HID_DESCRIPTOR_LIST {
+    uint8_t  bDescriptorType; /**< Type of HID report. */
+    uint16_t wDescriptorLength; /**< Length of the associated HID report descriptor, in bytes. */
+  } DescriptorList[1]; /**< Array of one or more descriptors */
+} ;
+/** HID class-specific HID Descriptor. */
+typedef struct _HID_DESCRIPTOR HID_DESCRIPTOR;
+
+
+/** HID Request Codes  
+ * @{ 
+ */
+#define HID_REQUEST_GET_REPORT          0x01
+#define HID_REQUEST_GET_IDLE            0x02
+#define HID_REQUEST_GET_PROTOCOL        0x03
+#define HID_REQUEST_SET_REPORT          0x09
+#define HID_REQUEST_SET_IDLE            0x0A
+#define HID_REQUEST_SET_PROTOCOL        0x0B
+/** @} */
+
+/** HID Report Types  
+ * @{ 
+ */
+#define HID_REPORT_INPUT                0x01
+#define HID_REPORT_OUTPUT               0x02
+#define HID_REPORT_FEATURE              0x03
+/** @} */
+
+
+/** Usage Pages  
+ * @{ 
+ */
+#define HID_USAGE_PAGE_UNDEFINED        0x00
+#define HID_USAGE_PAGE_GENERIC          0x01
+#define HID_USAGE_PAGE_SIMULATION       0x02
+#define HID_USAGE_PAGE_VR               0x03
+#define HID_USAGE_PAGE_SPORT            0x04
+#define HID_USAGE_PAGE_GAME             0x05
+#define HID_USAGE_PAGE_DEV_CONTROLS     0x06
+#define HID_USAGE_PAGE_KEYBOARD         0x07
+#define HID_USAGE_PAGE_LED              0x08
+#define HID_USAGE_PAGE_BUTTON           0x09
+#define HID_USAGE_PAGE_ORDINAL          0x0A
+#define HID_USAGE_PAGE_TELEPHONY        0x0B
+#define HID_USAGE_PAGE_CONSUMER         0x0C
+#define HID_USAGE_PAGE_DIGITIZER        0x0D
+#define HID_USAGE_PAGE_UNICODE          0x10
+#define HID_USAGE_PAGE_ALPHANUMERIC     0x14
+/** @} */
+
+
+/** Generic Desktop Page (0x01)  
+ * @{ 
+ */
+#define HID_USAGE_GENERIC_POINTER               0x01
+#define HID_USAGE_GENERIC_MOUSE                 0x02
+#define HID_USAGE_GENERIC_JOYSTICK              0x04
+#define HID_USAGE_GENERIC_GAMEPAD               0x05
+#define HID_USAGE_GENERIC_KEYBOARD              0x06
+#define HID_USAGE_GENERIC_KEYPAD                0x07
+#define HID_USAGE_GENERIC_X                     0x30
+#define HID_USAGE_GENERIC_Y                     0x31
+#define HID_USAGE_GENERIC_Z                     0x32
+#define HID_USAGE_GENERIC_RX                    0x33
+#define HID_USAGE_GENERIC_RY                    0x34
+#define HID_USAGE_GENERIC_RZ                    0x35
+#define HID_USAGE_GENERIC_SLIDER                0x36
+#define HID_USAGE_GENERIC_DIAL                  0x37
+#define HID_USAGE_GENERIC_WHEEL                 0x38
+#define HID_USAGE_GENERIC_HATSWITCH             0x39
+#define HID_USAGE_GENERIC_COUNTED_BUFFER        0x3A
+#define HID_USAGE_GENERIC_BYTE_COUNT            0x3B
+#define HID_USAGE_GENERIC_MOTION_WAKEUP         0x3C
+#define HID_USAGE_GENERIC_VX                    0x40
+#define HID_USAGE_GENERIC_VY                    0x41
+#define HID_USAGE_GENERIC_VZ                    0x42
+#define HID_USAGE_GENERIC_VBRX                  0x43
+#define HID_USAGE_GENERIC_VBRY                  0x44
+#define HID_USAGE_GENERIC_VBRZ                  0x45
+#define HID_USAGE_GENERIC_VNO                   0x46
+#define HID_USAGE_GENERIC_SYSTEM_CTL            0x80
+#define HID_USAGE_GENERIC_SYSCTL_POWER          0x81
+#define HID_USAGE_GENERIC_SYSCTL_SLEEP          0x82
+#define HID_USAGE_GENERIC_SYSCTL_WAKE           0x83
+#define HID_USAGE_GENERIC_SYSCTL_CONTEXT_MENU   0x84
+#define HID_USAGE_GENERIC_SYSCTL_MAIN_MENU      0x85
+#define HID_USAGE_GENERIC_SYSCTL_APP_MENU       0x86
+#define HID_USAGE_GENERIC_SYSCTL_HELP_MENU      0x87
+#define HID_USAGE_GENERIC_SYSCTL_MENU_EXIT      0x88
+#define HID_USAGE_GENERIC_SYSCTL_MENU_SELECT    0x89
+#define HID_USAGE_GENERIC_SYSCTL_MENU_RIGHT     0x8A
+#define HID_USAGE_GENERIC_SYSCTL_MENU_LEFT      0x8B
+#define HID_USAGE_GENERIC_SYSCTL_MENU_UP        0x8C
+#define HID_USAGE_GENERIC_SYSCTL_MENU_DOWN      0x8D
+/** @} */
+
+/** Simulation Controls Page (0x02)  
+ * @{ 
+ */
+#define HID_USAGE_SIMULATION_RUDDER             0xBA
+#define HID_USAGE_SIMULATION_THROTTLE           0xBB
+/** @} */
+
+/* Virtual Reality Controls Page (0x03) */
+/* ... */
+
+/* Sport Controls Page (0x04) */
+/* ... */
+
+/* Game Controls Page (0x05) */
+/* ... */
+
+/* Generic Device Controls Page (0x06) */
+/* ... */
+
+/** Keyboard/Keypad Page (0x07)  
+ * @{ 
+ */
+/** Error "keys" */
+#define HID_USAGE_KEYBOARD_NOEVENT              0x00
+#define HID_USAGE_KEYBOARD_ROLLOVER             0x01
+#define HID_USAGE_KEYBOARD_POSTFAIL             0x02
+#define HID_USAGE_KEYBOARD_UNDEFINED            0x03
+
+/** Letters */
+#define HID_USAGE_KEYBOARD_aA                   0x04
+#define HID_USAGE_KEYBOARD_zZ                   0x1D
+
+/** Numbers */
+#define HID_USAGE_KEYBOARD_ONE                  0x1E
+#define HID_USAGE_KEYBOARD_ZERO                 0x27
+
+#define HID_USAGE_KEYBOARD_RETURN               0x28
+#define HID_USAGE_KEYBOARD_ESCAPE               0x29
+#define HID_USAGE_KEYBOARD_DELETE               0x2A
+
+/** Funtion keys */
+#define HID_USAGE_KEYBOARD_F1                   0x3A
+#define HID_USAGE_KEYBOARD_F12                  0x45
+
+#define HID_USAGE_KEYBOARD_PRINT_SCREEN         0x46
+
+/** Modifier Keys */
+#define HID_USAGE_KEYBOARD_LCTRL                0xE0
+#define HID_USAGE_KEYBOARD_LSHFT                0xE1
+#define HID_USAGE_KEYBOARD_LALT                 0xE2
+#define HID_USAGE_KEYBOARD_LGUI                 0xE3
+#define HID_USAGE_KEYBOARD_RCTRL                0xE4
+#define HID_USAGE_KEYBOARD_RSHFT                0xE5
+#define HID_USAGE_KEYBOARD_RALT                 0xE6
+#define HID_USAGE_KEYBOARD_RGUI                 0xE7
+#define HID_USAGE_KEYBOARD_SCROLL_LOCK          0x47
+#define HID_USAGE_KEYBOARD_NUM_LOCK             0x53
+#define HID_USAGE_KEYBOARD_CAPS_LOCK            0x39
+/** @} */
+
+/* ... */
+
+/** LED Page (0x08)  
+ * @{ 
+ */
+#define HID_USAGE_LED_NUM_LOCK                  0x01
+#define HID_USAGE_LED_CAPS_LOCK                 0x02
+#define HID_USAGE_LED_SCROLL_LOCK               0x03
+#define HID_USAGE_LED_COMPOSE                   0x04
+#define HID_USAGE_LED_KANA                      0x05
+#define HID_USAGE_LED_POWER                     0x06
+#define HID_USAGE_LED_SHIFT                     0x07
+#define HID_USAGE_LED_DO_NOT_DISTURB            0x08
+#define HID_USAGE_LED_MUTE                      0x09
+#define HID_USAGE_LED_TONE_ENABLE               0x0A
+#define HID_USAGE_LED_HIGH_CUT_FILTER           0x0B
+#define HID_USAGE_LED_LOW_CUT_FILTER            0x0C
+#define HID_USAGE_LED_EQUALIZER_ENABLE          0x0D
+#define HID_USAGE_LED_SOUND_FIELD_ON            0x0E
+#define HID_USAGE_LED_SURROUND_FIELD_ON         0x0F
+#define HID_USAGE_LED_REPEAT                    0x10
+#define HID_USAGE_LED_STEREO                    0x11
+#define HID_USAGE_LED_SAMPLING_RATE_DETECT      0x12
+#define HID_USAGE_LED_SPINNING                  0x13
+#define HID_USAGE_LED_CAV                       0x14
+#define HID_USAGE_LED_CLV                       0x15
+#define HID_USAGE_LED_RECORDING_FORMAT_DET      0x16
+#define HID_USAGE_LED_OFF_HOOK                  0x17
+#define HID_USAGE_LED_RING                      0x18
+#define HID_USAGE_LED_MESSAGE_WAITING           0x19
+#define HID_USAGE_LED_DATA_MODE                 0x1A
+#define HID_USAGE_LED_BATTERY_OPERATION         0x1B
+#define HID_USAGE_LED_BATTERY_OK                0x1C
+#define HID_USAGE_LED_BATTERY_LOW               0x1D
+#define HID_USAGE_LED_SPEAKER                   0x1E
+#define HID_USAGE_LED_HEAD_SET                  0x1F
+#define HID_USAGE_LED_HOLD                      0x20
+#define HID_USAGE_LED_MICROPHONE                0x21
+#define HID_USAGE_LED_COVERAGE                  0x22
+#define HID_USAGE_LED_NIGHT_MODE                0x23
+#define HID_USAGE_LED_SEND_CALLS                0x24
+#define HID_USAGE_LED_CALL_PICKUP               0x25
+#define HID_USAGE_LED_CONFERENCE                0x26
+#define HID_USAGE_LED_STAND_BY                  0x27
+#define HID_USAGE_LED_CAMERA_ON                 0x28
+#define HID_USAGE_LED_CAMERA_OFF                0x29
+#define HID_USAGE_LED_ON_LINE                   0x2A
+#define HID_USAGE_LED_OFF_LINE                  0x2B
+#define HID_USAGE_LED_BUSY                      0x2C
+#define HID_USAGE_LED_READY                     0x2D
+#define HID_USAGE_LED_PAPER_OUT                 0x2E
+#define HID_USAGE_LED_PAPER_JAM                 0x2F
+#define HID_USAGE_LED_REMOTE                    0x30
+#define HID_USAGE_LED_FORWARD                   0x31
+#define HID_USAGE_LED_REVERSE                   0x32
+#define HID_USAGE_LED_STOP                      0x33
+#define HID_USAGE_LED_REWIND                    0x34
+#define HID_USAGE_LED_FAST_FORWARD              0x35
+#define HID_USAGE_LED_PLAY                      0x36
+#define HID_USAGE_LED_PAUSE                     0x37
+#define HID_USAGE_LED_RECORD                    0x38
+#define HID_USAGE_LED_ERROR                     0x39
+#define HID_USAGE_LED_SELECTED_INDICATOR        0x3A
+#define HID_USAGE_LED_IN_USE_INDICATOR          0x3B
+#define HID_USAGE_LED_MULTI_MODE_INDICATOR      0x3C
+#define HID_USAGE_LED_INDICATOR_ON              0x3D
+#define HID_USAGE_LED_INDICATOR_FLASH           0x3E
+#define HID_USAGE_LED_INDICATOR_SLOW_BLINK      0x3F
+#define HID_USAGE_LED_INDICATOR_FAST_BLINK      0x40
+#define HID_USAGE_LED_INDICATOR_OFF             0x41
+#define HID_USAGE_LED_FLASH_ON_TIME             0x42
+#define HID_USAGE_LED_SLOW_BLINK_ON_TIME        0x43
+#define HID_USAGE_LED_SLOW_BLINK_OFF_TIME       0x44
+#define HID_USAGE_LED_FAST_BLINK_ON_TIME        0x45
+#define HID_USAGE_LED_FAST_BLINK_OFF_TIME       0x46
+#define HID_USAGE_LED_INDICATOR_COLOR           0x47
+#define HID_USAGE_LED_RED                       0x48
+#define HID_USAGE_LED_GREEN                     0x49
+#define HID_USAGE_LED_AMBER                     0x4A
+#define HID_USAGE_LED_GENERIC_INDICATOR         0x4B
+/** @} */
+
+/*  Button Page (0x09)  
+ */
+/*   There is no need to label these usages. */
+
+/*  Ordinal Page (0x0A)  
+ */
+/*   There is no need to label these usages. */
+
+/** Telephony Device Page (0x0B)  
+ * @{ 
+ */
+#define HID_USAGE_TELEPHONY_PHONE               0x01
+#define HID_USAGE_TELEPHONY_ANSWERING_MACHINE   0x02
+#define HID_USAGE_TELEPHONY_MESSAGE_CONTROLS    0x03
+#define HID_USAGE_TELEPHONY_HANDSET             0x04
+#define HID_USAGE_TELEPHONY_HEADSET             0x05
+#define HID_USAGE_TELEPHONY_KEYPAD              0x06
+#define HID_USAGE_TELEPHONY_PROGRAMMABLE_BUTTON 0x07
+/** @} */
+/* ... */
+
+/** Consumer Page (0x0C)  
+ * @{ 
+ */
+#define HID_USAGE_CONSUMER_CONTROL              0x01
+#define HID_USAGE_CONSUMER_FAST_FORWARD       0xB3
+#define HID_USAGE_CONSUMER_REWIND             0xB4
+#define HID_USAGE_CONSUMER_PLAY_PAUSE			    0xCD
+#define HID_USAGE_CONSUMER_VOLUME_INCREMENT		0xE9
+#define HID_USAGE_CONSUMER_VOLUME_DECREMENT		0xEA
+/** @} */
+/* ... */
+
+/* and others ... */
+
+
+/** HID Report Item Macros  
+ * @{ 
+ */
+/** Main Items */
+#define HID_Input(x)           0x81,x
+#define HID_Output(x)          0x91,x
+#define HID_Feature(x)         0xB1,x
+#define HID_Collection(x)      0xA1,x
+#define HID_EndCollection      0xC0
+
+/** Data (Input, Output, Feature) */
+#define HID_Data               0<<0
+#define HID_Constant           1<<0
+#define HID_Array              0<<1
+#define HID_Variable           1<<1
+#define HID_Absolute           0<<2
+#define HID_Relative           1<<2
+#define HID_NoWrap             0<<3
+#define HID_Wrap               1<<3
+#define HID_Linear             0<<4
+#define HID_NonLinear          1<<4
+#define HID_PreferredState     0<<5
+#define HID_NoPreferred        1<<5
+#define HID_NoNullPosition     0<<6
+#define HID_NullState          1<<6
+#define HID_NonVolatile        0<<7
+#define HID_Volatile           1<<7
+
+/** Collection Data */
+#define HID_Physical           0x00
+#define HID_Application        0x01
+#define HID_Logical            0x02
+#define HID_Report             0x03
+#define HID_NamedArray         0x04
+#define HID_UsageSwitch        0x05
+#define HID_UsageModifier      0x06
+
+/** Global Items */
+#define HID_UsagePage(x)       0x05,x
+#define HID_UsagePageVendor(x) 0x06,x,0xFF
+#define HID_LogicalMin(x)      0x15,x
+#define HID_LogicalMinS(x)     0x16,(x&0xFF),((x>>8)&0xFF)
+#define HID_LogicalMinL(x)     0x17,(x&0xFF),((x>>8)&0xFF),((x>>16)&0xFF),((x>>24)&0xFF)
+#define HID_LogicalMax(x)      0x25,x
+#define HID_LogicalMaxS(x)     0x26,(x&0xFF),((x>>8)&0xFF)
+#define HID_LogicalMaxL(x)     0x27,(x&0xFF),((x>>8)&0xFF),((x>>16)&0xFF),((x>>24)&0xFF)
+#define HID_PhysicalMin(x)     0x35,x
+#define HID_PhysicalMinS(x)    0x36,(x&0xFF),((x>>8)&0xFF)
+#define HID_PhysicalMinL(x)    0x37,(x&0xFF),((x>>8)&0xFF),((x>>16)&0xFF),((x>>24)&0xFF)
+#define HID_PhysicalMax(x)     0x45,x
+#define HID_PhysicalMaxS(x)    0x46,(x&0xFF),((x>>8)&0xFF)
+#define HID_PhysicalMaxL(x)    0x47,(x&0xFF),((x>>8)&0xFF),((x>>16)&0xFF),((x>>24)&0xFF)
+#define HID_UnitExponent(x)    0x55,x
+#define HID_Unit(x)            0x65,x
+#define HID_UnitS(x)           0x66,(x&0xFF),((x>>8)&0xFF)
+#define HID_UnitL(x)           0x67,(x&0xFF),((x>>8)&0xFF),((x>>16)&0xFF),((x>>24)&0xFF)
+#define HID_ReportSize(x)      0x75,x
+#define HID_ReportID(x)        0x85,x
+#define HID_ReportCount(x)     0x95,x
+#define HID_Push               0xA0
+#define HID_Pop                0xB0
+
+/** Local Items */
+#define HID_Usage(x)           0x09,x
+#define HID_UsageMin(x)        0x19,x
+#define HID_UsageMax(x)        0x29,x
+/** @} */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif  /* __HID_H__ */
diff --git a/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_hiduser.h b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_hiduser.h
new file mode 100644
index 0000000000000000000000000000000000000000..d46d667ace71f109f1abb730dc91ee1c0cad27a4
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_hiduser.h
@@ -0,0 +1,429 @@
+/***********************************************************************
+* $Id:: mw_usbd_hiduser.h 202 2011-06-12 21:50:01Z usb06052                   $
+*
+* Project: USB device ROM Stack
+*
+* Description:
+*     HID Custom User Module Definitions.
+*
+***********************************************************************
+*   Copyright(C) 2011, NXP Semiconductor
+*   All rights reserved.
+*
+* Software that is described herein is for illustrative purposes only
+* which provides customers with programming information regarding the
+* products. This software is supplied "AS IS" without any warranties.
+* NXP Semiconductors assumes no responsibility or liability for the
+* use of the software, conveys no license or title under any patent,
+* copyright, or mask work right to the product. NXP Semiconductors
+* reserves the right to make changes in the software without
+* notification. NXP Semiconductors also make no representation or
+* warranty that such application will be suitable for the specified
+* use without further testing or modification.
+**********************************************************************/
+
+#ifndef __HIDUSER_H__
+#define __HIDUSER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "mw_usbd.h"
+#include "mw_usbd_hid.h"
+#include "mw_usbd_core.h"
+
+/** \file
+ *  \brief Human Interface Device (HID) API structures and function prototypes.
+ *
+ *  Definition of functions exported by ROM based HID function driver.
+ *
+ */
+
+/** \ingroup Group_USBD
+ *  @defgroup USBD_HID HID Class Function Driver
+ *  \section Sec_HIDModDescription Module Description
+ *  HID Class Function Driver module. This module contains an internal implementation of the USB HID Class.
+ *  User applications can use this class driver instead of implementing the HID class manually
+ *  via the low-level HW and core APIs.
+ *
+ *  This module is designed to simplify the user code by exposing only the required interface needed to interface with
+ *  Devices using the USB HID Class.
+ */
+
+/** \brief HID report descriptor data structure. 
+ *  \ingroup USBD_HID
+ *
+ *  \details  This structure is used as part of HID function driver initialization 
+ *  parameter structure \ref USBD_HID_INIT_PARAM. This structure contains
+ *  details of a report type supported by the application. An application
+ *  can support multiple report types as a single HID device. The application
+ *  should define this report type data struture per report it supports and
+ *  the array of reoprt types to USBD_HID_API::init() through \ref USBD_HID_INIT_PARAM
+ *  structure. 
+ *
+ *  \note All descriptor pointers assigned in this structure should be on 4 byte
+ *  aligned address boundary. 
+ *
+ */
+typedef struct _HID_REPORT_T {
+  uint16_t len; /**< Size of the report descriptor in bytes. */ 
+  uint8_t idle_time; /**< This value is used by stack to respond to Set_Idle & 
+                     GET_Idle requests for the specified report ID. The value
+                     of this field specified the rate at which duplicate reports 
+                     are generated for the specified Report ID. For example, a 
+                     device with two input reports could specify an idle rate of 
+                     20 milliseconds for report ID 1 and 500 milliseconds for 
+                     report ID 2.
+                     */
+  uint8_t __pad; /**< Padding space. */
+  uint8_t* desc; /**< Report descriptor. */
+} USB_HID_REPORT_T;
+
+/** \brief USB descriptors data structure. 
+ *  \ingroup USBD_HID
+ *
+ *  \details  This module exposes functions which interact directly with USB device stack's core layer.
+ *  The application layer uses this component when it has to implement custom class function driver or 
+ *  standard class function driver which is not part of the current USB device stack.
+ *  The functions exposed by this interface are to register class specific EP0 handlers and corresponding
+ *  utility functions to manipulate EP0 state machine of the stack. This interface also exposes
+ *  function to register custom endpoint interrupt handler.
+ *
+ */
+typedef struct USBD_HID_INIT_PARAM
+{
+  /* memory allocation params */
+  uint32_t mem_base;  /**< Base memory location from where the stack can allocate
+                      data and buffers. \note The memory address set in this field
+                      should be accessible by USB DMA controller. Also this value
+                      should be aligned on 4 byte boundary.
+                      */
+  uint32_t mem_size;  /**< The size of memory buffer which stack can use. 
+                      \note The \em mem_size should be greater than the size 
+                      returned by USBD_HID_API::GetMemSize() routine.*/
+  /* HID paramas */
+  uint8_t max_reports; /**< Number of HID reports supported by this instance
+                       of HID class driver. 
+                       */
+  uint8_t pad[3];
+  uint8_t* intf_desc; /**< Pointer to the HID interface descriptor within the 
+                      descriptor array (\em high_speed_desc) passed to Init()
+                      through \ref USB_CORE_DESCS_T structure.  
+                      */
+  USB_HID_REPORT_T* report_data; /**< Pointer to an array of HID report descriptor
+                                 data structure (\ref USB_HID_REPORT_T). The number
+                                 of elements in the array should be same a \em max_reports
+                                 value. The stack uses this array to respond to 
+                                 requests recieved for various HID report descriptor
+                                 information. \note This array should be of global scope.
+                                 */
+
+  /* user defined functions */
+  /* required functions */
+  /** 
+  *  HID get report callback function.
+  *
+  *  This function is provided by the application software. This function gets called 
+  *  when host sends a HID_REQUEST_GET_REPORT request. The setup packet data (\em pSetup)
+  *  is passed to the callback so that application can extract the report ID, report
+  *  type and other information need to generate the report. \note HID reports are sent
+  *  via interrupt IN endpoint also. This function is called only when report request
+  *  is received on control endpoint. Application should implement \em HID_EpIn_Hdlr to
+  *  send reports to host via interrupt IN endpoint.
+  *   
+  *  
+  *  \param[in] hHid Handle to HID function driver. 
+  *  \param[in] pSetup Pointer to setup packet recived from host. 
+  *  \param[in, out] pBuffer  Pointer to a pointer of data buffer containing report data. 
+  *                       Pointer-to-pointer is used to implement zero-copy buffers. 
+  *                       See \ref USBD_ZeroCopy for more details on zero-copy concept.
+  *  \param[in] length  Amount of data copied to destination buffer.
+  *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK On success.
+  *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+  *          \retval ERR_USBD_xxx  For other error conditions. 
+  *                                             
+  */
+  ErrorCode_t (*HID_GetReport)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t* length); 
+  
+  /** 
+  *  HID set report callback function.
+  *
+  *  This function is provided by the application software. This function gets called 
+  *  when host sends a HID_REQUEST_SET_REPORT request. The setup packet data (\em pSetup)
+  *  is passed to the callback so that application can extract the report ID, report
+  *  type and other information need to modify the report. An application might choose 
+  *  to ignore input Set_Report requests as meaningless. Alternatively these reports 
+  *  could be used to reset the origin of a control (that is, current position should 
+  *  report zero).
+  *  
+  *  \param[in] hHid Handle to HID function driver. 
+  *  \param[in] pSetup Pointer to setup packet recived from host. 
+  *  \param[in, out] pBuffer  Pointer to a pointer of data buffer containing report data. 
+  *                       Pointer-to-pointer is used to implement zero-copy buffers. 
+  *                       See \ref USBD_ZeroCopy for more details on zero-copy concept.
+  *  \param[in] length  Amount of data copied to destination buffer.
+  *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK On success.
+  *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+  *          \retval ERR_USBD_xxx  For other error conditions. 
+  *                                             
+  */
+  ErrorCode_t (*HID_SetReport)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t length);
+  
+  /* optional functions */
+  
+  /** 
+  *  Optional callback function to handle HID_GetPhysDesc request.
+  *
+  *  The application software could provide this callback HID_GetPhysDesc handler to
+  *  handle get physical descriptor requests sent by the host. When host requests 
+  *  Physical Descriptor set 0, application should return a special descriptor
+  *  identifying the number of descriptor sets and their sizes. A Get_Descriptor 
+  *  request with the Physical Index equal to 1 should return the first Physical 
+  *  Descriptor set. A device could possibly have alternate uses for its items. 
+  *  These can be enumerated by issuing subsequent Get_Descriptor requests while 
+  *  incrementing the Descriptor Index. A device should return the last descriptor
+  *  set to requests with an index greater than the last number defined in the HID 
+  *  descriptor.
+  *  \note Applications which don't have physical descriptor should set this data member
+  *  to zero before calling the USBD_HID_API::Init().
+  *  \n
+  *  
+  *  \param[in] hHid Handle to HID function driver. 
+  *  \param[in] pSetup Pointer to setup packet recived from host. 
+  *  \param[in] pBuf Pointer to a pointer of data buffer containing physical descriptor 
+  *                   data. If the physical descriptor is in USB accessable memory area
+  *                   application could just update the pointer or else it should copy 
+  *                   the descriptor to the address pointed by this pointer.
+  *  \param[in] length  Amount of data copied to destination buffer or descriptor length.
+  *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK On success.
+  *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+  *          \retval ERR_USBD_xxx  For other error conditions. 
+  *                                             
+  */
+  ErrorCode_t (*HID_GetPhysDesc)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuf, uint16_t* length);
+
+  /** 
+  *  Optional callback function to handle HID_REQUEST_SET_IDLE request.
+  *
+  *  The application software could provide this callback to handle HID_REQUEST_SET_IDLE
+  *  requests sent by the host. This callback is provided to applications to adjust
+  *  timers associated with various reports, which are sent to host over interrupt 
+  *  endpoint. The setup packet data (\em pSetup) is passed to the callback so that
+  *  application can extract the report ID, report type and other information need 
+  *  to modify the report's idle time.
+  *  \note Applications which don't send reports on Interrupt endpoint or don't
+  *  have idle time between reports should set this data member to zero before 
+  *  calling the USBD_HID_API::Init().
+  *  \n
+  *  
+  *  \param[in] hHid Handle to HID function driver. 
+  *  \param[in] pSetup Pointer to setup packet recived from host. 
+  *  \param[in] idleTime  Idle time to be set for the specified report.
+  *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK On success.
+  *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+  *          \retval ERR_USBD_xxx  For other error conditions. 
+  *                                             
+  */
+  ErrorCode_t (*HID_SetIdle)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t idleTime); 
+ 
+  /** 
+  *  Optional callback function to handle HID_REQUEST_SET_PROTOCOL request.
+  *
+  *  The application software could provide this callback to handle HID_REQUEST_SET_PROTOCOL
+  *  requests sent by the host. This callback is provided to applications to adjust
+  *  modes of their code between boot mode and report mode. 
+  *  \note Applications which don't support protocol modes should set this data member
+  *  to zero before calling the USBD_HID_API::Init().
+  *  \n
+  *  
+  *  \param[in] hHid Handle to HID function driver. 
+  *  \param[in] pSetup Pointer to setup packet recived from host. 
+  *  \param[in] protocol  Protocol mode. 
+  *                       0 = Boot Protocol
+  *                       1 = Report Protocol
+  *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK On success.
+  *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+  *          \retval ERR_USBD_xxx  For other error conditions. 
+  *                                             
+  */
+  ErrorCode_t (*HID_SetProtocol)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t protocol); 
+  
+  /** 
+  *  Optional Interrupt IN endpoint event handler.
+  *
+  *  The application software could provide Interrupt IN endpoint event handler. 
+  *  Application which send reports to host on interrupt endpoint should provide
+  *  an endpoint event handler through this data member. This data memeber is 
+  *  ignored if the interface descriptor \em intf_desc doesn't have any IN interrupt 
+  *  endpoint descriptor associated. 
+  *  \n
+  *  
+  *  \param[in] hUsb Handle to the USB device stack. 
+  *  \param[in] data Handle to HID function driver. 
+  *  \param[in] event  Type of endpoint event. See \ref USBD_EVENT_T for more details.
+  *  \return The call back should return \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK On success.
+  *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+  *          \retval ERR_USBD_xxx  For other error conditions. 
+  *                                             
+  */
+  ErrorCode_t (*HID_EpIn_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event);
+  /** 
+  *  Optional Interrupt OUT endpoint event handler.
+  *
+  *  The application software could provide Interrupt OUT endpoint event handler. 
+  *  Application which recieves reports from host on interrupt endpoint should provide
+  *  an endpoint event handler through this data member. This data memeber is 
+  *  ignored if the interface descriptor \em intf_desc doesn't have any OUT interrupt 
+  *  endpoint descriptor associated. 
+  *  \n
+  *  
+  *  \param[in] hUsb Handle to the USB device stack. 
+  *  \param[in] data Handle to HID function driver. 
+  *  \param[in] event  Type of endpoint event. See \ref USBD_EVENT_T for more details.
+  *  \return The call back should return \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK On success.
+  *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+  *          \retval ERR_USBD_xxx  For other error conditions. 
+  *                                             
+  */
+  ErrorCode_t (*HID_EpOut_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event);
+
+  /* user overridable function */
+  /** 
+  *  Optional user overridable function to replace the default HID_GetReportDesc handler.
+  *
+  *  The application software could override the default HID_GetReportDesc handler with their
+  *  own by providing the handler function address as this data member of the parameter
+  *  structure. Application which like the default handler should set this data member
+  *  to zero before calling the USBD_HID_API::Init() and also provide report data array
+  *  \em report_data field.
+  *  \n
+  *  \note 
+  *  
+  *  \param[in] hUsb Handle to the USB device stack. 
+  *  \param[in] data Pointer to the data which will be passed when callback function is called by the stack. 
+  *  \param[in] event  Type of endpoint event. See \ref USBD_EVENT_T for more details.
+  *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK On success.
+  *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+  *          \retval ERR_USBD_xxx  For other error conditions. 
+  *                                             
+  */
+  ErrorCode_t (*HID_GetReportDesc)(USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuf, uint16_t* length);
+  /** 
+  *  Optional user overridable function to replace the default HID class handler.
+  *
+  *  The application software could override the default EP0 class handler with their
+  *  own by providing the handler function address as this data member of the parameter
+  *  structure. Application which like the default handler should set this data member
+  *  to zero before calling the USBD_HID_API::Init().
+  *  \n
+  *  \note 
+  *  
+  *  \param[in] hUsb Handle to the USB device stack. 
+  *  \param[in] data Pointer to the data which will be passed when callback function is called by the stack. 
+  *  \param[in] event  Type of endpoint event. See \ref USBD_EVENT_T for more details.
+  *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK On success.
+  *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+  *          \retval ERR_USBD_xxx  For other error conditions. 
+  *                                             
+  */
+  ErrorCode_t (*HID_Ep0_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event);
+
+} USBD_HID_INIT_PARAM_T;
+
+/** \brief HID class API functions structure.
+ *  \ingroup USBD_HID
+ *
+ *  This structure contains pointers to all the function exposed by HID function driver module.
+ *
+ */
+typedef struct USBD_HID_API 
+{
+  /** \fn uint32_t GetMemSize(USBD_HID_INIT_PARAM_T* param)
+   *  Function to determine the memory required by the HID function driver module.
+   * 
+   *  This function is called by application layer before calling pUsbApi->hid->Init(), to allocate memory used 
+   *  by HID function driver module. The application should allocate the memory which is accessible by USB
+   *  controller/DMA controller. 
+   *  \note Some memory areas are not accessible by all bus masters.
+   *
+   *  \param[in] param Structure containing HID function driver module initialization parameters.
+   *  \return Returns the required memory size in bytes.
+   */
+  uint32_t (*GetMemSize)(USBD_HID_INIT_PARAM_T* param);
+
+  /** \fn ErrorCode_t init(USBD_HANDLE_T hUsb, USBD_HID_INIT_PARAM_T* param)
+   *  Function to initialize HID function driver module.
+   * 
+   *  This function is called by application layer to initialize HID function driver  
+   *  module. On successful initialization the function returns a handle to HID 
+   *  function driver module in passed param structure.  
+   *
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in, out] param Structure containing HID function driver module 
+   *      initialization parameters.
+   *  \return Returns \ref ErrorCode_t type to indicate success or error condition.
+   *          \retval LPC_OK On success
+   *          \retval ERR_USBD_BAD_MEM_BUF  Memory buffer passed is not 4-byte 
+   *              aligned or smaller than required. 
+   *          \retval ERR_API_INVALID_PARAM2 Either HID_GetReport() or HID_SetReport()
+   *              callback are not defined. 
+   *          \retval ERR_USBD_BAD_DESC  HID_HID_DESCRIPTOR_TYPE is not defined 
+   *              immediately after interface descriptor. 
+   *          \retval ERR_USBD_BAD_INTF_DESC  Wrong interface descriptor is passed. 
+   *          \retval ERR_USBD_BAD_EP_DESC  Wrong endpoint descriptor is passed. 
+   */
+  ErrorCode_t (*init)(USBD_HANDLE_T hUsb, USBD_HID_INIT_PARAM_T* param);
+
+} USBD_HID_API_T;
+
+/*-----------------------------------------------------------------------------
+ *  Private functions & structures prototypes
+ *-----------------------------------------------------------------------------*/
+/** @cond  ADVANCED_API */
+
+typedef struct _HID_CTRL_T {
+  /* pointer to controller */
+  USB_CORE_CTRL_T*  pUsbCtrl;
+  /* descriptor pointers */
+  uint8_t* hid_desc;
+  USB_HID_REPORT_T* report_data;
+
+  uint8_t protocol;
+  uint8_t if_num;                  /* interface number */
+  uint8_t epin_adr;                /* IN interrupt endpoint */
+  uint8_t epout_adr;               /* OUT interrupt endpoint */
+
+  /* user defined functions */
+  ErrorCode_t (*HID_GetReport)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t* length); 
+  ErrorCode_t (*HID_SetReport)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t length);
+  ErrorCode_t (*HID_GetPhysDesc)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuf, uint16_t* length);
+  ErrorCode_t (*HID_SetIdle)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t idleTime); 
+  ErrorCode_t (*HID_SetProtocol)( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t protocol); 
+
+  /* virtual overridable functions */ 
+  ErrorCode_t (*HID_GetReportDesc)(USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuf, uint16_t* length);
+
+}USB_HID_CTRL_T;
+
+/** @cond  DIRECT_API */
+extern uint32_t mwHID_GetMemSize(USBD_HID_INIT_PARAM_T* param);
+extern ErrorCode_t mwHID_init(USBD_HANDLE_T hUsb, USBD_HID_INIT_PARAM_T* param);
+/** @endcond */
+
+/** @endcond */
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif  /* __HIDUSER_H__ */
diff --git a/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_hw.h b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_hw.h
new file mode 100644
index 0000000000000000000000000000000000000000..080d389b43fe29040834957d9ed736d416bc8a25
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_hw.h
@@ -0,0 +1,463 @@
+/***********************************************************************
+* $Id:: mw_usbd_hw.h 202 2011-06-12 21:50:01Z usb06052                        $
+*
+* Project: USB device ROM Stack
+*
+* Description:
+*     USB Hardware Function prototypes.
+*
+***********************************************************************
+*   Copyright(C) 2011, NXP Semiconductor
+*   All rights reserved.
+*
+* Software that is described herein is for illustrative purposes only
+* which provides customers with programming information regarding the
+* products. This software is supplied "AS IS" without any warranties.
+* NXP Semiconductors assumes no responsibility or liability for the
+* use of the software, conveys no license or title under any patent,
+* copyright, or mask work right to the product. NXP Semiconductors
+* reserves the right to make changes in the software without
+* notification. NXP Semiconductors also make no representation or
+* warranty that such application will be suitable for the specified
+* use without further testing or modification.
+**********************************************************************/
+#ifndef __USBHW_H__
+#define __USBHW_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "error.h"
+#include "mw_usbd.h"
+#include "mw_usbd_core.h"
+
+/** \file
+ *  \brief USB Hardware Function prototypes.
+ *
+ *  Definition of functions exported by ROM based Device Controller Driver (DCD).
+ *
+ */
+
+/** \ingroup Group_USBD
+ *  @defgroup USBD_HW USB Device Controller Driver 
+ *  \section Sec_HWModDescription Module Description
+ *  The Device Controller Driver Layer implements the routines to deal directly with the hardware. 
+ */
+
+/** \ingroup USBD_HW
+*  USB Endpoint/class handler Callback Events. 
+* 
+*/
+enum USBD_EVENT_T {
+  USB_EVT_SETUP =1,    /**< 1   Setup Packet received */
+  USB_EVT_OUT,         /**< 2   OUT Packet received */
+  USB_EVT_IN,          /**< 3    IN Packet sent */
+  USB_EVT_OUT_NAK,     /**< 4   OUT Packet - Not Acknowledged */
+  USB_EVT_IN_NAK,      /**< 5    IN Packet - Not Acknowledged */
+  USB_EVT_OUT_STALL,   /**< 6   OUT Packet - Stalled */
+  USB_EVT_IN_STALL,    /**< 7    IN Packet - Stalled */
+  USB_EVT_OUT_DMA_EOT, /**< 8   DMA OUT EP - End of Transfer */
+  USB_EVT_IN_DMA_EOT,  /**< 9   DMA  IN EP - End of Transfer */
+  USB_EVT_OUT_DMA_NDR, /**< 10  DMA OUT EP - New Descriptor Request */
+  USB_EVT_IN_DMA_NDR,  /**< 11  DMA  IN EP - New Descriptor Request */
+  USB_EVT_OUT_DMA_ERR, /**< 12  DMA OUT EP - Error */
+  USB_EVT_IN_DMA_ERR,  /**< 13  DMA  IN EP - Error */
+  USB_EVT_RESET,       /**< 14  Reset event recieved */
+  USB_EVT_SOF,         /**< 15  Start of Frame event */
+  USB_EVT_DEV_STATE,   /**< 16  Device status events */
+  USB_EVT_DEV_ERROR   /**< 17  Device error events */
+};
+
+/** 
+ *  \brief Hardware API functions structure.
+ *  \ingroup USBD_HW
+ *
+ *  This module exposes functions which interact directly with USB device controller hardware.
+ *
+ */
+typedef struct USBD_HW_API
+{
+  /** \fn uint32_t GetMemSize(USBD_API_INIT_PARAM_T* param)
+   *  Function to determine the memory required by the USB device stack's DCD and core layers.
+   * 
+   *  This fuction is called by application layer before calling pUsbApi->hw->Init(), to allocate memory used 
+   *  by DCD and core layers. The application should allocate the memory which is accessible by USB
+   *  controller/DMA controller. 
+   *  \note Some memory areas are not accessible by all bus masters.
+   *
+   *  \param[in] param Structure containing USB device stack initialization parameters.
+   *  \return Returns the required memory size in bytes.
+   */
+  uint32_t (*GetMemSize)(USBD_API_INIT_PARAM_T* param);
+  
+  /** \fn ErrorCode_t Init(USBD_HANDLE_T* phUsb, USB_CORE_DESCS_T* pDesc, USBD_API_INIT_PARAM_T* param)
+   *  Function to initialize USB device stack's DCD and core layers.
+   * 
+   *  This function is called by application layer to initialize USB hardware and core layers. 
+   *  On successful initialization the function returns a handle to USB device stack which should
+   *  be passed to the rest of the functions.  
+   *
+   *  \param[in,out] phUsb Pointer to the USB device stack handle of type USBD_HANDLE_T. 
+   *  \param[in]  param Structure containing USB device stack initialization parameters.
+   *  \return Returns \ref ErrorCode_t type to indicate success or error condition.
+   *          \retval LPC_OK(0) On success
+   *          \retval ERR_USBD_BAD_MEM_BUF(0x0004000b) When insufficient memory buffer is passed or memory
+   *                                             is not aligned on 2048 boundary.
+   */
+  ErrorCode_t (*Init)(USBD_HANDLE_T* phUsb, USB_CORE_DESCS_T* pDesc, USBD_API_INIT_PARAM_T* param);
+  
+  /** \fn void Connect(USBD_HANDLE_T hUsb, uint32_t con)
+   *  Function to make USB device visible/invisible on the USB bus.
+   *
+   *  This function is called after the USB initialization. This function uses the soft connect
+   *  feature to make the device visible on the USB bus. This function is called only after the
+   *  application is ready to handle the USB data. The enumeration process is started by the
+   *  host after the device detection. The driver handles the enumeration process according to
+   *  the USB descriptors passed in the USB initialization function.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] con  States whether to connect (1) or to disconnect (0).
+   *  \return Nothing.
+   */
+  void (*Connect)(USBD_HANDLE_T hUsb, uint32_t con);
+  
+  /** \fn void ISR(USBD_HANDLE_T hUsb)
+   *  Function to USB device controller interrupt events.
+   *  
+   *  When the user application is active the interrupt handlers are mapped in the user flash
+   *  space. The user application must provide an interrupt handler for the USB interrupt and
+   *  call this function in the interrupt handler routine. The driver interrupt handler takes
+   *  appropriate action according to the data received on the USB bus. 
+   *  
+   *  \param[in]  hUsb Handle to the USB device stack. 
+   *  \return Nothing.
+   */
+  void (*ISR)(USBD_HANDLE_T hUsb);
+
+  /** \fn void Reset(USBD_HANDLE_T hUsb)
+   *  Function to Reset USB device stack and hardware controller.
+   *  
+   *  Reset USB device stack and hardware controller. Disables all endpoints except EP0.
+   *  Clears all pending interrupts and resets endpoint transfer queues.
+   *  This function is called internally by pUsbApi->hw->init() and from reset event.
+   *  
+   *  \param[in]  hUsb Handle to the USB device stack. 
+   *  \return Nothing.
+   */
+  void  (*Reset)(USBD_HANDLE_T hUsb);
+  
+  /** \fn void ForceFullSpeed(USBD_HANDLE_T hUsb, uint32_t cfg)
+   *  Function to force high speed USB device to operate in full speed mode.
+   *
+   *  This function is useful for testing the behaviour of current device when connected
+   *  to a full speed only hosts.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] cfg  When 1 - set force full-speed or 
+   *                       0 - clear force full-speed.
+   *  \return Nothing.
+   */
+  void  (*ForceFullSpeed )(USBD_HANDLE_T hUsb, uint32_t cfg);
+  
+  /** \fn void WakeUpCfg(USBD_HANDLE_T hUsb, uint32_t cfg)
+   *  Function to configure USB device controller to wakeup host on remote events.
+   *
+   *  This function is called by application layer to configure the USB device controller 
+   *  to wakeup on remote events. It is recommended to call this function from users's 
+   *  USB_WakeUpCfg() callback routine registered with stack. 
+   *  \note User's USB_WakeUpCfg() is registered with stack by setting the USB_WakeUpCfg member 
+   *  of USBD_API_INIT_PARAM_T structure before calling pUsbApi->hw->Init() routine.
+   *  Certain USB device controllers needed to keep some clocks always on to generate 
+   *  resume signaling through pUsbApi->hw->WakeUp(). This hook is provided to support 
+   *  such controllers. In most controllers cases this is an empty routine.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] cfg  When 1 - Configure controller to wake on remote events or 
+   *                       0 - Configure controller not to wake on remote events.
+   *  \return Nothing.
+   */
+  void  (*WakeUpCfg)(USBD_HANDLE_T hUsb, uint32_t  cfg);
+  
+  /** \fn void SetAddress(USBD_HANDLE_T hUsb, uint32_t adr)
+   *  Function to set USB address assigned by host in device controller hardware.
+   *
+   *  This function is called automatically when USB_REQUEST_SET_ADDRESS request is received  
+   *  by the stack from USB host.
+   *  This interface is provided to users to invoke this function in other scenarios which are not 
+   *  handle by current stack. In most user applications this function is not called directly.
+   *  Also this function can be used by users who are selectively modifying the USB device stack's 
+   *  standard handlers through callback interface exposed by the stack. 
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] adr  USB bus Address to which the device controller should respond. Usually 
+   *                  assigned by the USB host.
+   *  \return Nothing.
+   */
+  void  (*SetAddress)(USBD_HANDLE_T hUsb, uint32_t adr);
+
+  /** \fn void Configure(USBD_HANDLE_T hUsb, uint32_t cfg)
+   *  Function to configure device controller hardware with selected configuration.
+   *
+   *  This function is called automatically when USB_REQUEST_SET_CONFIGURATION request is received  
+   *  by the stack from USB host.
+   *  This interface is provided to users to invoke this function in other scenarios which are not 
+   *  handle by current stack. In most user applications this function is not called directly.
+   *  Also this function can be used by users who are selectively modifying the USB device stack's 
+   *  standard handlers through callback interface exposed by the stack. 
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] cfg  Configuration index. 
+   *  \return Nothing.
+   */
+  void  (*Configure)(USBD_HANDLE_T hUsb, uint32_t  cfg);
+
+  /** \fn void ConfigEP(USBD_HANDLE_T hUsb, USB_ENDPOINT_DESCRIPTOR *pEPD)
+   *  Function to configure USB Endpoint according to descriptor.
+   *
+   *  This function is called automatically when USB_REQUEST_SET_CONFIGURATION request is received  
+   *  by the stack from USB host. All the endpoints associated with the selected configuration
+   *  are configured.
+   *  This interface is provided to users to invoke this function in other scenarios which are not 
+   *  handle by current stack. In most user applications this function is not called directly.
+   *  Also this function can be used by users who are selectively modifying the USB device stack's 
+   *  standard handlers through callback interface exposed by the stack. 
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] pEPD Endpoint descriptor structure defined in USB 2.0 specification.
+   *  \return Nothing.
+   */
+  void  (*ConfigEP)(USBD_HANDLE_T hUsb, USB_ENDPOINT_DESCRIPTOR *pEPD);
+
+  /** \fn void DirCtrlEP(USBD_HANDLE_T hUsb, uint32_t dir)
+   *  Function to set firection for USB control endpoint EP0.
+   *
+   *  This function is called automatically by the stack on need bassis. 
+   *  This interface is provided to users to invoke this function in other scenarios which are not 
+   *  handle by current stack. In most user applications this function is not called directly.
+   *  Also this function can be used by users who are selectively modifying the USB device stack's 
+   *  standard handlers through callback interface exposed by the stack. 
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] cfg  When 1 - Set EP0 in IN transfer mode 
+   *                       0 - Set EP0 in OUT transfer mode
+   *  \return Nothing.
+   */
+  void  (*DirCtrlEP)(USBD_HANDLE_T hUsb, uint32_t dir);
+
+  /** \fn void EnableEP(USBD_HANDLE_T hUsb, uint32_t EPNum)
+   *  Function to enable selected USB endpoint.
+   *
+   *  This function enables interrupts on selected endpoint.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] EPNum  Endpoint number as per USB specification. 
+   *                    ie. An EP1_IN is represented by 0x81 number.
+   *  \return Nothing.
+   */
+  void  (*EnableEP)(USBD_HANDLE_T hUsb, uint32_t EPNum);
+
+  /** \fn void DisableEP(USBD_HANDLE_T hUsb, uint32_t EPNum)
+   *  Function to disable selected USB endpoint.
+   *
+   *  This function disables interrupts on selected endpoint.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] EPNum  Endpoint number as per USB specification. 
+   *                    ie. An EP1_IN is represented by 0x81 number.
+   *  \return Nothing.
+   */
+  void  (*DisableEP)(USBD_HANDLE_T hUsb, uint32_t EPNum);
+
+  /** \fn void ResetEP(USBD_HANDLE_T hUsb, uint32_t EPNum)
+   *  Function to reset selected USB endpoint.
+   *
+   *  This function flushes the endpoint buffers and resets data toggle logic.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] EPNum  Endpoint number as per USB specification. 
+   *                    ie. An EP1_IN is represented by 0x81 number.
+   *  \return Nothing.
+  */
+  void  (*ResetEP)(USBD_HANDLE_T hUsb, uint32_t EPNum);
+
+  /** \fn void SetStallEP(USBD_HANDLE_T hUsb, uint32_t EPNum)
+   *  Function to STALL selected USB endpoint.
+   *
+   *  Generates STALL signalling for requested endpoint.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] EPNum  Endpoint number as per USB specification. 
+   *                    ie. An EP1_IN is represented by 0x81 number.
+   *  \return Nothing.
+   */
+  void  (*SetStallEP)(USBD_HANDLE_T hUsb, uint32_t EPNum);
+
+  /** \fn void ClrStallEP(USBD_HANDLE_T hUsb, uint32_t EPNum)
+   *  Function to clear STALL state for the requested endpoint.
+   *
+   *  This function clears STALL state for the requested endpoint.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] EPNum  Endpoint number as per USB specification. 
+   *                    ie. An EP1_IN is represented by 0x81 number.
+   *  \return Nothing.
+   */
+  void  (*ClrStallEP)(USBD_HANDLE_T hUsb, uint32_t EPNum);
+
+  /** \fn ErrorCode_t SetTestMode(USBD_HANDLE_T hUsb, uint8_t mode)
+   *  Function to set high speed USB device controller in requested test mode.
+   *
+   *  USB-IF requires the high speed device to be put in various test modes
+   *  for electrical testing. This USB device stack calls this function whenever
+   *  it receives USB_REQUEST_CLEAR_FEATURE request for USB_FEATURE_TEST_MODE. 
+   *  Users can put the device in test mode by directly calling this function.
+   *  Returns ERR_USBD_INVALID_REQ when device controller is full-speed only.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] mode  Test mode defined in USB 2.0 electrical testing specification.
+   *  \return Returns \ref ErrorCode_t type to indicate success or error condition.
+   *          \retval LPC_OK(0) - On success
+   *          \retval ERR_USBD_INVALID_REQ(0x00040001) - Invalid test mode or 
+   *                                             Device controller is full-speed only.
+   */
+  ErrorCode_t (*SetTestMode)(USBD_HANDLE_T hUsb, uint8_t mode); 
+
+  /** \fn uint32_t ReadEP(USBD_HANDLE_T hUsb, uint32_t EPNum, uint8_t *pData)
+   *  Function to read data received on the requested endpoint.
+   *
+   *  This function is called by USB stack and the application layer to read the data
+   *  received on the requested endpoint.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] EPNum  Endpoint number as per USB specification. 
+   *                    ie. An EP1_IN is represented by 0x81 number.
+   *  \param[in,out] pData Pointer to the data buffer where data is to be copied. 
+   *  \return Returns the number of bytes copied to the buffer.
+   */
+  uint32_t (*ReadEP)(USBD_HANDLE_T hUsb, uint32_t EPNum, uint8_t *pData);
+
+  /** \fn uint32_t ReadReqEP(USBD_HANDLE_T hUsb, uint32_t EPNum, uint8_t *pData, uint32_t len)
+   *  Function to queue read request on the specified endpoint.
+   *
+   *  This function is called by USB stack and the application layer to queue a read request
+   *  on the specified endpoint.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] EPNum  Endpoint number as per USB specification. 
+   *                    ie. An EP1_IN is represented by 0x81 number.
+   *  \param[in,out] pData Pointer to the data buffer where data is to be copied. This buffer
+   *                       address should be accessible by USB DMA master.
+   *  \param[in] len  Length of the buffer passed. 
+   *  \return Returns the length of the requested buffer.
+   */
+  uint32_t (*ReadReqEP)(USBD_HANDLE_T hUsb, uint32_t EPNum, uint8_t *pData, uint32_t len);
+
+  /** \fn uint32_t ReadSetupPkt(USBD_HANDLE_T hUsb, uint32_t EPNum, uint32_t *pData)
+   *  Function to read setup packet data received on the requested endpoint.
+   *
+   *  This function is called by USB stack and the application layer to read setup packet data
+   *  received on the requested endpoint.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] EPNum  Endpoint number as per USB specification. 
+   *                    ie. An EP0_IN is represented by 0x80 number.
+   *  \param[in,out] pData Pointer to the data buffer where data is to be copied. 
+   *  \return Returns the number of bytes copied to the buffer.
+   */
+  uint32_t (*ReadSetupPkt)(USBD_HANDLE_T hUsb, uint32_t EPNum, uint32_t *pData);
+
+  /** \fn uint32_t WriteEP(USBD_HANDLE_T hUsb, uint32_t EPNum, uint8_t *pData, uint32_t cnt)
+   *  Function to write data to be sent on the requested endpoint.
+   *
+   *  This function is called by USB stack and the application layer to send data
+   *  on the requested endpoint.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] EPNum  Endpoint number as per USB specification. 
+   *                    ie. An EP1_IN is represented by 0x81 number.
+   *  \param[in] pData Pointer to the data buffer from where data is to be copied. 
+   *  \param[in] cnt  Number of bytes to write. 
+   *  \return Returns the number of bytes written.
+   */
+  uint32_t (*WriteEP)(USBD_HANDLE_T hUsb, uint32_t EPNum, uint8_t *pData, uint32_t cnt);
+
+  /** \fn void WakeUp(USBD_HANDLE_T hUsb)
+   *  Function to generate resume signaling on bus for remote host wakeup.
+   *
+   *  This function is called by application layer to remotely wakeup host controller 
+   *  when system is in suspend state. Application should indicate this remote wakeup
+   *  capability by setting USB_CONFIG_REMOTE_WAKEUP in bmAttributes of Configuration 
+   *  Descriptor. Also this routine will generate resume signalling only if host
+   *  enables USB_FEATURE_REMOTE_WAKEUP by sending SET_FEATURE request before suspending
+   *  the bus.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \return Nothing.
+   */
+  void  (*WakeUp)(USBD_HANDLE_T hUsb);
+
+  /** \fn void EnableEP(USBD_HANDLE_T hUsb, uint32_t EPNum)
+   *  Function to enable/disable selected USB event.
+   *
+   *  This function enables interrupts on selected endpoint.
+   *  
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in] EPNum  Endpoint number corresponding to the eventas per USB specification. 
+   *                    ie. An EP1_IN is represented by 0x81 number. For device events 
+   *                    set this param to 0x0. 
+   *  \param[in] event  Type of endpoint event. See \ref USBD_EVENT_T for more details.
+   *  \param[in] enable  1 - enable event, 0 - disable event.
+   *  \return Returns \ref ErrorCode_t type to indicate success or error condition.
+   *          \retval LPC_OK(0) - On success
+   *          \retval ERR_USBD_INVALID_REQ(0x00040001) - Invalid event type.
+   */
+  ErrorCode_t  (*EnableEvent)(USBD_HANDLE_T hUsb, uint32_t EPNum, uint32_t event_type, 
+    uint32_t enable);
+
+} USBD_HW_API_T;
+
+/*-----------------------------------------------------------------------------
+ *  Private functions & structures prototypes used by stack internally
+ *-----------------------------------------------------------------------------*/
+/** @cond  DIRECT_API */
+
+/* Driver functions */
+uint32_t hwUSB_GetMemSize(USBD_API_INIT_PARAM_T* param);
+ErrorCode_t hwUSB_Init(USBD_HANDLE_T* phUsb, USB_CORE_DESCS_T* pDesc, USBD_API_INIT_PARAM_T* param);
+void hwUSB_Connect(USBD_HANDLE_T hUsb, uint32_t con);
+void hwUSB_ISR(USBD_HANDLE_T hUsb);
+
+/* USB Hardware Functions */
+extern void  hwUSB_Reset(USBD_HANDLE_T hUsb);
+extern void  hwUSB_ForceFullSpeed (USBD_HANDLE_T hUsb, uint32_t con);
+extern void  hwUSB_WakeUpCfg(USBD_HANDLE_T hUsb, uint32_t  cfg);
+extern void  hwUSB_SetAddress(USBD_HANDLE_T hUsb, uint32_t adr);
+extern void  hwUSB_Configure(USBD_HANDLE_T hUsb, uint32_t  cfg);
+extern void  hwUSB_ConfigEP(USBD_HANDLE_T hUsb, USB_ENDPOINT_DESCRIPTOR *pEPD);
+extern void  hwUSB_DirCtrlEP(USBD_HANDLE_T hUsb, uint32_t dir);
+extern void  hwUSB_EnableEP(USBD_HANDLE_T hUsb, uint32_t EPNum);
+extern void  hwUSB_DisableEP(USBD_HANDLE_T hUsb, uint32_t EPNum);
+extern void  hwUSB_ResetEP(USBD_HANDLE_T hUsb, uint32_t EPNum);
+extern void  hwUSB_SetStallEP(USBD_HANDLE_T hUsb, uint32_t EPNum);
+extern void  hwUSB_ClrStallEP(USBD_HANDLE_T hUsb, uint32_t EPNum);
+extern ErrorCode_t hwUSB_SetTestMode(USBD_HANDLE_T hUsb, uint8_t mode); /* for FS only devices return ERR_USBD_INVALID_REQ */
+extern uint32_t hwUSB_ReadEP(USBD_HANDLE_T hUsb, uint32_t EPNum, uint8_t *pData);
+extern uint32_t hwUSB_ReadReqEP(USBD_HANDLE_T hUsb, uint32_t EPNum, uint8_t *pData, uint32_t len);
+extern uint32_t hwUSB_ReadSetupPkt(USBD_HANDLE_T hUsb, uint32_t, uint32_t *);
+extern uint32_t hwUSB_WriteEP(USBD_HANDLE_T hUsb, uint32_t EPNum, uint8_t *pData, uint32_t cnt);
+
+/* generate resume signalling on the bus */
+extern void  hwUSB_WakeUp(USBD_HANDLE_T hUsb);
+extern ErrorCode_t  hwUSB_EnableEvent(USBD_HANDLE_T hUsb, uint32_t EPNum, uint32_t event_type, uint32_t enable);
+/* TODO implement following routines
+- function to program TD and queue them to ep Qh
+*/
+
+/** @endcond */
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif  /* __USBHW_H__ */
diff --git a/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_msc.h b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_msc.h
new file mode 100644
index 0000000000000000000000000000000000000000..64175843b16ed2d02ab65b57b6bd3d84a15bf6c8
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_msc.h
@@ -0,0 +1,126 @@
+/***********************************************************************
+* $Id:: mw_usbd_msc.h 197 2011-06-12 20:22:41Z usb06052                       $
+*
+* Project: USB device ROM Stack
+*
+* Description:
+*     Mass Storage Class definitions.
+*
+***********************************************************************
+*   Copyright(C) 2011, NXP Semiconductor
+*   All rights reserved.
+*
+* Software that is described herein is for illustrative purposes only
+* which provides customers with programming information regarding the
+* products. This software is supplied "AS IS" without any warranties.
+* NXP Semiconductors assumes no responsibility or liability for the
+* use of the software, conveys no license or title under any patent,
+* copyright, or mask work right to the product. NXP Semiconductors
+* reserves the right to make changes in the software without
+* notification. NXP Semiconductors also make no representation or
+* warranty that such application will be suitable for the specified
+* use without further testing or modification.
+**********************************************************************/
+
+#ifndef __MSC_H__
+#define __MSC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "mw_usbd.h"
+
+/** \file
+ *  \brief Mass Storage calss (MSC) descriptors.
+ *
+ *  Definition of MSC class descriptors and their bit defines.
+ *
+ */
+
+/* MSC Subclass Codes */
+#define MSC_SUBCLASS_RBC                0x01
+#define MSC_SUBCLASS_SFF8020I_MMC2      0x02
+#define MSC_SUBCLASS_QIC157             0x03
+#define MSC_SUBCLASS_UFI                0x04
+#define MSC_SUBCLASS_SFF8070I           0x05
+#define MSC_SUBCLASS_SCSI               0x06
+
+/* MSC Protocol Codes */
+#define MSC_PROTOCOL_CBI_INT            0x00
+#define MSC_PROTOCOL_CBI_NOINT          0x01
+#define MSC_PROTOCOL_BULK_ONLY          0x50
+
+
+/* MSC Request Codes */
+#define MSC_REQUEST_RESET               0xFF
+#define MSC_REQUEST_GET_MAX_LUN         0xFE
+
+
+/* MSC Bulk-only Stage */
+#define MSC_BS_CBW                      0       /* Command Block Wrapper */
+#define MSC_BS_DATA_OUT                 1       /* Data Out Phase */
+#define MSC_BS_DATA_IN                  2       /* Data In Phase */
+#define MSC_BS_DATA_IN_LAST             3       /* Data In Last Phase */
+#define MSC_BS_DATA_IN_LAST_STALL       4       /* Data In Last Phase with Stall */
+#define MSC_BS_CSW                      5       /* Command Status Wrapper */
+#define MSC_BS_ERROR                    6       /* Error */
+
+
+/* Bulk-only Command Block Wrapper */
+PRE_PACK struct POST_PACK _MSC_CBW
+{
+  uint32_t dSignature;
+  uint32_t dTag;
+  uint32_t dDataLength;
+  uint8_t  bmFlags;
+  uint8_t  bLUN;
+  uint8_t  bCBLength;
+  uint8_t  CB[16];
+} ;
+typedef struct _MSC_CBW MSC_CBW;
+
+/* Bulk-only Command Status Wrapper */
+PRE_PACK struct POST_PACK _MSC_CSW
+{
+  uint32_t dSignature;
+  uint32_t dTag;
+  uint32_t dDataResidue;
+  uint8_t  bStatus;
+} ;
+typedef struct _MSC_CSW MSC_CSW;
+
+#define MSC_CBW_Signature               0x43425355
+#define MSC_CSW_Signature               0x53425355
+
+
+/* CSW Status Definitions */
+#define CSW_CMD_PASSED                  0x00
+#define CSW_CMD_FAILED                  0x01
+#define CSW_PHASE_ERROR                 0x02
+
+
+/* SCSI Commands */
+#define SCSI_TEST_UNIT_READY            0x00
+#define SCSI_REQUEST_SENSE              0x03
+#define SCSI_FORMAT_UNIT                0x04
+#define SCSI_INQUIRY                    0x12
+#define SCSI_MODE_SELECT6               0x15
+#define SCSI_MODE_SENSE6                0x1A
+#define SCSI_START_STOP_UNIT            0x1B
+#define SCSI_MEDIA_REMOVAL              0x1E
+#define SCSI_READ_FORMAT_CAPACITIES     0x23
+#define SCSI_READ_CAPACITY              0x25
+#define SCSI_READ10                     0x28
+#define SCSI_WRITE10                    0x2A
+#define SCSI_VERIFY10                   0x2F
+#define SCSI_READ12                     0xA8
+#define SCSI_WRITE12                    0xAA
+#define SCSI_MODE_SELECT10              0x55
+#define SCSI_MODE_SENSE10               0x5A
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif  /* __MSC_H__ */
diff --git a/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_mscuser.h b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_mscuser.h
new file mode 100644
index 0000000000000000000000000000000000000000..2dd04f8a45ca7a024bad14795805fbb57581cdbe
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_mscuser.h
@@ -0,0 +1,274 @@
+/***********************************************************************
+* $Id:: mw_usbd_mscuser.h 202 2011-06-12 21:50:01Z usb06052                   $
+*
+* Project: USB device ROM Stack
+*
+* Description:
+*     Mass Storage Class Custom User Module definitions.
+*
+***********************************************************************
+*   Copyright(C) 2011, NXP Semiconductor
+*   All rights reserved.
+*
+* Software that is described herein is for illustrative purposes only
+* which provides customers with programming information regarding the
+* products. This software is supplied "AS IS" without any warranties.
+* NXP Semiconductors assumes no responsibility or liability for the
+* use of the software, conveys no license or title under any patent,
+* copyright, or mask work right to the product. NXP Semiconductors
+* reserves the right to make changes in the software without
+* notification. NXP Semiconductors also make no representation or
+* warranty that such application will be suitable for the specified
+* use without further testing or modification.
+**********************************************************************/
+#ifndef __MSCUSER_H__
+#define __MSCUSER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "error.h"
+#include "mw_usbd.h"
+#include "mw_usbd_msc.h"
+#include "mw_usbd_core.h"
+#include "../app_usbd_cfg.h"
+
+/** \file
+ *  \brief Mass Storage Class (MSC) API structures and function prototypes.
+ *
+ *  Definition of functions exported by ROM based MSC function driver.
+ *
+ */
+
+/** \ingroup Group_USBD
+ *  @defgroup USBD_MSC Mass Storage Class (MSC) Function Driver
+ *  \section Sec_MSCModDescription Module Description
+ *  MSC Class Function Driver module. This module contains an internal implementation of the USB MSC Class.
+ *  User applications can use this class driver instead of implementing the MSC class manually
+ *  via the low-level USBD_HW and USBD_Core APIs.
+ *
+ *  This module is designed to simplify the user code by exposing only the required interface needed to interface with
+ *  Devices using the USB MSC Class.
+ */
+
+/** \brief Mass Storage class function driver initilization parameter data structure.
+ *  \ingroup USBD_MSC
+ *
+ *  \details  This data structure is used to pass initialization parameters to the 
+ *  Mass Storage class function driver's init function.
+ *
+ */
+typedef struct USBD_MSC_INIT_PARAM
+{
+  /* memory allocation params */
+  uint32_t mem_base;  /**< Base memory location from where the stack can allocate
+                      data and buffers. \note The memory address set in this field
+                      should be accessible by USB DMA controller. Also this value
+                      should be aligned on 4 byte boundary.
+                      */
+  uint32_t mem_size;  /**< The size of memory buffer which stack can use. 
+                      \note The \em mem_size should be greater than the size 
+                      returned by USBD_MSC_API::GetMemSize() routine.*/
+  /* mass storage paramas */
+  uint8_t*  InquiryStr; /**< Pointer to the 28 character string. This string is 
+                        sent in response to the SCSI Inquiry command. \note The data 
+                        pointed by the pointer should be of global scope. 
+                        */
+  uint32_t  BlockCount; /**< Number of blocks present in the mass storage device */
+  uint32_t  BlockSize; /**< Block size in number of bytes */
+  uint32_t  MemorySize; /**< Memory size in number of bytes */
+  /** Pointer to the interface descriptor within the descriptor
+  * array (\em high_speed_desc) passed to Init() through \ref USB_CORE_DESCS_T 
+  * structure. The stack assumes both HS and FS use same BULK endpoints. 
+  */
+  uint8_t* intf_desc;
+  /* user defined functions */
+
+ /** 
+  *  MSC Write callback function.
+  *
+  *  This function is provided by the application software. This function gets called 
+  *  when host sends a write command.
+  *  
+  *  \param[in] offset Destination start address. 
+  *  \param[in, out] src  Pointer to a pointer to the source of data. Pointer-to-pointer
+  *                       is used to implement zero-copy buffers. See \ref USBD_ZeroCopy
+  *                       for more details on zero-copy concept.
+  *  \param[in] length  Number of bytes to be written.
+  *  \return Nothing. 
+  *                                             
+  */
+  void (*MSC_Write)( uint32_t offset, uint8_t** src, uint32_t length); 
+ /** 
+  *  MSC Read callback function.
+  *
+  *  This function is provided by the application software. This function gets called 
+  *  when host sends a read command.
+  *  
+  *  \param[in] offset Source start address. 
+  *  \param[in, out] dst  Pointer to a pointer to the source of data. The MSC function drivers 
+  *         implemented in stack are written with zero-copy model. Meaning the stack doesn't make an 
+  *          extra copy of buffer before writing/reading data from USB hardware FIFO. Hence the 
+  *          parameter is pointer to a pointer containing address buffer (<em>uint8_t** dst</em>). 
+  *          So that the user application can update the buffer pointer instead of copying data to 
+  *          address pointed by the parameter. /note The updated buffer address should be accessable 
+  *          by USB DMA master. If user doesn't want to use zero-copy model, then the user should copy
+  *          data to the address pointed by the passed buffer pointer parameter and shouldn't change 
+  *          the address value. See \ref USBD_ZeroCopy for more details on zero-copy concept.
+  *  \param[in] length  Number of bytes to be read.
+  *  \return Nothing. 
+  *                                             
+  */
+  void (*MSC_Read)( uint32_t offset, uint8_t** dst, uint32_t length);
+ /** 
+  *  MSC Verify callback function.
+  *
+  *  This function is provided by the application software. This function gets called 
+  *  when host sends a verify command. The callback function should compare the buffer
+  *  with the destination memory at the requested offset and 
+  *  
+  *  \param[in] offset Destination start address. 
+  *  \param[in] buf  Buffer containing the data sent by the host.
+  *  \param[in] length  Number of bytes to verify.
+  *  \return Returns \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK If data in the buffer matches the data at destination
+  *          \retval ERR_FAILED  Atleast one byte is different. 
+  *                                             
+  */
+  ErrorCode_t (*MSC_Verify)( uint32_t offset, uint8_t buf[], uint32_t length);
+  /** 
+  *  Optional callback function to optimize MSC_Write buffer transfer.
+  *
+  *  This function is provided by the application software. This function gets called 
+  *  when host sends SCSI_WRITE10/SCSI_WRITE12 command. The callback function should 
+  *  update the \em buff_adr pointer so that the stack transfers the data directly
+  *  to the target buffer. /note The updated buffer address should be accessable 
+  *  by USB DMA master. If user doesn't want to use zero-copy model, then the user 
+  *  should not update the buffer pointer. See \ref USBD_ZeroCopy for more details
+  *  on zero-copy concept.
+  *  
+  *  \param[in] offset Destination start address. 
+  *  \param[in,out] buf  Buffer containing the data sent by the host.
+  *  \param[in] length  Number of bytes to write.
+  *  \return Nothing. 
+  *                                             
+  */
+  void (*MSC_GetWriteBuf)( uint32_t offset, uint8_t** buff_adr, uint32_t length); 
+
+  /** 
+  *  Optional user overridable function to replace the default MSC class handler.
+  *
+  *  The application software could override the default EP0 class handler with their
+  *  own by providing the handler function address as this data member of the parameter
+  *  structure. Application which like the default handler should set this data member
+  *  to zero before calling the USBD_MSC_API::Init().
+  *  \n
+  *  \note 
+  *  
+  *  \param[in] hUsb Handle to the USB device stack. 
+  *  \param[in] data Pointer to the data which will be passed when callback function is called by the stack. 
+  *  \param[in] event  Type of endpoint event. See \ref USBD_EVENT_T for more details.
+  *  \return The call back should returns \ref ErrorCode_t type to indicate success or error condition.
+  *          \retval LPC_OK On success.
+  *          \retval ERR_USBD_UNHANDLED  Event is not handled hence pass the event to next in line. 
+  *          \retval ERR_USBD_xxx  For other error conditions. 
+  *                                             
+  */
+  ErrorCode_t (*MSC_Ep0_Hdlr) (USBD_HANDLE_T hUsb, void* data, uint32_t event);
+
+} USBD_MSC_INIT_PARAM_T;
+
+/** \brief MSC class API functions structure.
+ *  \ingroup USBD_MSC
+ *
+ *  This module exposes functions which interact directly with USB device controller hardware.
+ *
+ */
+typedef struct USBD_MSC_API
+{
+  /** \fn uint32_t GetMemSize(USBD_MSC_INIT_PARAM_T* param)
+   *  Function to determine the memory required by the MSC function driver module.
+   * 
+   *  This function is called by application layer before calling pUsbApi->msc->Init(), to allocate memory used 
+   *  by MSC function driver module. The application should allocate the memory which is accessible by USB
+   *  controller/DMA controller. 
+   *  \note Some memory areas are not accessible by all bus masters.
+   *
+   *  \param[in] param Structure containing MSC function driver module initialization parameters.
+   *  \return Returns the required memory size in bytes.
+   */
+  uint32_t (*GetMemSize)(USBD_MSC_INIT_PARAM_T* param);
+  
+  /** \fn ErrorCode_t init(USBD_HANDLE_T hUsb, USBD_MSC_INIT_PARAM_T* param)
+   *  Function to initialize MSC function driver module.
+   * 
+   *  This fuction is called by application layer to initialize MSC function driver module. 
+   *
+   *  \param[in] hUsb Handle to the USB device stack. 
+   *  \param[in, out] param Structure containing MSC function driver module initialization parameters.
+   *  \return Returns \ref ErrorCode_t type to indicate success or error condition.
+   *          \retval LPC_OK On success
+   *          \retval ERR_USBD_BAD_MEM_BUF  Memory buffer passed is not 4-byte 
+   *              aligned or smaller than required. 
+   *          \retval ERR_API_INVALID_PARAM2 Either MSC_Write() or MSC_Read() or
+   *              MSC_Verify() callbacks are not defined. 
+   *          \retval ERR_USBD_BAD_INTF_DESC  Wrong interface descriptor is passed. 
+   *          \retval ERR_USBD_BAD_EP_DESC  Wrong endpoint descriptor is passed. 
+   */
+  ErrorCode_t (*init)(USBD_HANDLE_T hUsb, USBD_MSC_INIT_PARAM_T* param);
+
+} USBD_MSC_API_T;
+
+/*-----------------------------------------------------------------------------
+ *  Private functions & structures prototypes
+ *-----------------------------------------------------------------------------*/
+/** @cond  ADVANCED_API */
+
+typedef struct _MSC_CTRL_T
+{
+  /* If it's a USB HS, the max packet is 512, if it's USB FS,
+  the max packet is 64. Use 512 for both HS and FS. */
+  /*ALIGNED(4)*/ uint8_t  BulkBuf[USB_HS_MAX_BULK_PACKET]; /* Bulk In/Out Buffer */
+  /*ALIGNED(4)*/MSC_CBW CBW;                   /* Command Block Wrapper */
+  /*ALIGNED(4)*/MSC_CSW CSW;                   /* Command Status Wrapper */
+
+  USB_CORE_CTRL_T*  pUsbCtrl;
+  
+  uint32_t Offset;                  /* R/W Offset */
+  uint32_t Length;                  /* R/W Length */
+  uint32_t BulkLen;                 /* Bulk In/Out Length */
+  uint8_t* rx_buf;
+  
+  uint8_t BulkStage;               /* Bulk Stage */
+  uint8_t if_num;                  /* interface number */
+  uint8_t epin_num;                /* BULK IN endpoint number */
+  uint8_t epout_num;               /* BULK OUT endpoint number */
+  uint32_t MemOK;                  /* Memory OK */
+
+  uint8_t*  InquiryStr;
+  uint32_t  BlockCount;
+  uint32_t  BlockSize;
+  uint32_t  MemorySize;
+  /* user defined functions */
+  void (*MSC_Write)( uint32_t offset, uint8_t** src, uint32_t length); 
+  void (*MSC_Read)( uint32_t offset, uint8_t** dst, uint32_t length);
+  ErrorCode_t (*MSC_Verify)( uint32_t offset, uint8_t src[], uint32_t length);
+  /* optional call back for MSC_Write optimization */
+  void (*MSC_GetWriteBuf)( uint32_t offset, uint8_t** buff_adr, uint32_t length); 
+
+
+}USB_MSC_CTRL_T;
+
+/** @cond  DIRECT_API */
+extern uint32_t mwMSC_GetMemSize(USBD_MSC_INIT_PARAM_T* param);
+extern ErrorCode_t mwMSC_init(USBD_HANDLE_T hUsb, USBD_MSC_INIT_PARAM_T* param);
+/** @endcond */
+
+/** @endcond */
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif  /* __MSCUSER_H__ */
diff --git a/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_rom_api.h b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_rom_api.h
new file mode 100644
index 0000000000000000000000000000000000000000..152159a4fb6036d0fc1c170e3451f3f133d09092
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/romdriver/mw_usbd_rom_api.h
@@ -0,0 +1,100 @@
+/***********************************************************************
+* $Id:: mw_usbd_rom_api.h 197 2011-06-12 20:22:41Z usb06052                   $
+*
+* Project: USB device ROM Stack
+*
+* Description:
+*     ROM API Module definitions.
+*
+***********************************************************************
+*   Copyright(C) 2011, NXP Semiconductor
+*   All rights reserved.
+*
+* Software that is described herein is for illustrative purposes only
+* which provides customers with programming information regarding the
+* products. This software is supplied "AS IS" without any warranties.
+* NXP Semiconductors assumes no responsibility or liability for the
+* use of the software, conveys no license or title under any patent,
+* copyright, or mask work right to the product. NXP Semiconductors
+* reserves the right to make changes in the software without
+* notification. NXP Semiconductors also make no representation or
+* warranty that such application will be suitable for the specified
+* use without further testing or modification.
+**********************************************************************/
+#ifndef __MW_USBD_ROM_API_H
+#define __MW_USBD_ROM_API_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \file
+ *  \brief ROM API for USB device stack.
+ *
+ *  Definition of functions exported by ROM based USB device stack.
+ *
+ */
+
+#include "error.h"
+#include "mw_usbd.h"
+#include "mw_usbd_hw.h"
+#include "mw_usbd_desc.h"
+#include "mw_usbd_core.h"
+#include "mw_usbd_mscuser.h"
+#include "mw_usbd_dfuuser.h"
+#include "mw_usbd_hiduser.h"
+#include "mw_usbd_cdcuser.h"
+
+/** \brief Main USBD API functions structure.
+ *  \ingroup Group_USBD
+ *
+ *  This structure contains pointer to various USB Device stack's sub-module 
+ *  function tables. This structure is used as main entry point to access
+ *  various methods (grouped in sub-modules) exposed by ROM based USB device 
+ *  stack.
+ *
+ */
+typedef struct USBD_API 
+{
+  const USBD_HW_API_T* hw; /**< Pointer to function table which exposes functions 
+                           which interact directly with USB device stack's core 
+                           layer.*/
+  const USBD_CORE_API_T* core; /**< Pointer to function table which exposes functions 
+                           which interact directly with USB device controller 
+                           hardware.*/
+  const USBD_MSC_API_T* msc; /**< Pointer to function table which exposes functions 
+                           provided by MSC function driver module.
+                           */
+  const USBD_DFU_API_T* dfu; /**< Pointer to function table which exposes functions 
+                           provided by DFU function driver module.
+                           */
+  const USBD_HID_API_T* hid; /**< Pointer to function table which exposes functions 
+                           provided by HID function driver module.
+                           */
+  const USBD_CDC_API_T* cdc; /**< Pointer to function table which exposes functions 
+                           provided by CDC-ACM function driver module.
+                           */
+  const uint32_t* reserved6; /**< Reserved for future function driver module.
+                           */
+  const uint32_t version; /**< Version identifier of USB ROM stack. The version is
+                          defined as 0x0CHDMhCC where each nibble represnts version 
+                          number of the corresponding component.
+                          CC -  7:0  - 8bit core version number
+                           h - 11:8  - 4bit hardware interface version number
+                           M - 15:12 - 4bit MSC class module version number
+                           D - 19:16 - 4bit DFU class module version number
+                           H - 23:20 - 4bit HID class module version number
+                           C - 27:24 - 4bit CDC class module version number
+                           H - 31:28 - 4bit reserved 
+                           */
+
+} USBD_API_T;
+
+extern const  USBD_API_T usb_api;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif /*__MW_USBD_ROM_API_H*/
+
diff --git a/reform2-lpc-fw/src/core/usb/usb_cdc.c b/reform2-lpc-fw/src/core/usb/usb_cdc.c
new file mode 100644
index 0000000000000000000000000000000000000000..c5a0c0c3355f0627fc4461452e95415d7b676730
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/usb_cdc.c
@@ -0,0 +1,357 @@
+/**************************************************************************/
+/*!
+    @file     usb_cdc.c
+    @author   Thach Ha (tinyusb.net)
+
+    @section DESCRIPTION
+
+    CDC support functions for USB
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <string.h>
+#include "usbd.h"
+#include "core/fifo/fifo.h"
+#include "core/delay/delay.h"
+
+#ifdef CFG_USB_CDC
+
+#define ALIAS(f) __attribute__ ((weak, alias (#f)))
+
+static USBD_HANDLE_T g_hCdc;
+static CDC_LINE_CODING line_coding;
+static bool isConnected = false;             /* ToDo: Consider work-around */
+
+#if defined CFG_MCU_FAMILY_LPC11UXX
+  FIFO_DEF(ff_cdc_tx, CDC_BUFFER_SIZE, uint8_t, false, USB_IRQn);
+  FIFO_DEF(ff_cdc_rx, CDC_BUFFER_SIZE, uint8_t, true , USB_IRQn);
+#elif defined CFG_MCU_FAMILY_LPC13UXX
+  FIFO_DEF(ff_cdc_tx, CDC_BUFFER_SIZE, uint8_t, false, USB_IRQ_IRQn);
+  FIFO_DEF(ff_cdc_rx, CDC_BUFFER_SIZE, uint8_t, true , USB_IRQ_IRQn);
+#else
+    #error __FILE__ No MCU defined
+#endif
+
+void usb_cdc_recv_isr(void) ALIAS(usb_cdc_recv_isr_default);
+/**************************************************************************/
+/*!
+    @brief  Stub for the optional CDC receive ISR that can be used
+            to perform some action when data arrives via USB CDC
+*/
+/**************************************************************************/
+void usb_cdc_recv_isr_default (void)
+{
+  return;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+bool usb_cdc_isConnected(void)
+{
+  return isConnected;
+}
+
+/**************************************************************************/
+/*!
+    @brief Adds a single byte to the transmit buffer for USB CDC
+
+    @param[in]  c
+                The byte to send
+
+    @returns  TRUE if the byte was successfully added to the TX buffer
+
+    @note See example for usb_cdc_getc
+*/
+/**************************************************************************/
+bool usb_cdc_putc(uint8_t c)
+{
+  uint32_t start_time = delayGetSecondsActive();
+
+  while ( !fifo_write(&ff_cdc_tx, &c) ) /* TODO: blocking until fifo is available */
+  {
+    if(delayGetSecondsActive() - start_time > 2)
+    {
+      isConnected = false;
+      fifo_clear(&ff_cdc_tx);
+      return false;
+    }
+  }
+
+  return true;
+}
+
+/**************************************************************************/
+/*!
+    @brief Reads a single byte from the USB CDC buffer
+
+    @param[in]  c
+                Pointer to the location where the byte should be written
+
+    @returns  TRUE if a byte was read from the buffer
+
+    @code
+    // Convert incoming characters to upper case and send back via CDC
+    if (usb_isConfigured())
+    {
+      uint8_t cdc_char;
+      if( usb_cdc_getc(&cdc_char) )
+      {
+        switch (cdc_char)
+        {
+          default :
+            cdc_char = toupper(cdc_char);
+            usb_cdc_putc(cdc_char);
+            break;
+        }
+      }
+    }
+    @endcode
+*/
+/**************************************************************************/
+bool usb_cdc_getc(uint8_t *c)
+{
+  ASSERT(c, false); /* Make sure pointer isn't NULL */
+
+  return fifo_read(&ff_cdc_rx, c);
+}
+
+/**************************************************************************/
+/*!
+    @brief Writes the supplied buffer to the USB CDC device
+
+    @param[in]  buffer
+                Pointer to the buffer that should be written via USB CDC
+    @param[in]  count
+                The number of bytes to write
+
+    @returns  The actual number of bytes sent out via USB CDC
+
+    @code
+    // Capture printf output (in Red Suite) and send it to USB CDC
+    // (Note: With newlib this function should be renamed to _write)
+    int __sys_write(int file, char *ptr, int len)
+    {
+      #ifdef CFG_PRINTF_USBCDC
+        // Handle USB CDC output
+        if (usb_isConfigured())
+        {
+          int length = len;
+          while(length > 0)
+          {
+            uint16_t transferredCount;
+
+            transferredCount = usb_cdc_send( (uint8_t*) ptr, length);
+            ptr += transferredCount;
+            length -= transferredCount;
+          }
+        }
+      #endif
+
+      return len;
+    }
+
+    @endcode
+*/
+/**************************************************************************/
+uint16_t usb_cdc_send(uint8_t* buffer, uint16_t count)
+{
+  uint16_t i=0;
+
+  ASSERT(buffer && count, 0);
+
+  while (i < count && usb_cdc_putc(buffer[i]) )
+  {
+    i++;
+  }
+
+  return i;
+}
+
+/**************************************************************************/
+/*!
+    @brief Reads the incoming CDC buffer up to a maximum number of bytes
+
+    @param[in]  buffer
+                Pointer to the buffer where data should be written
+    @param[in]  max
+                The maximum number of bytes to read
+
+    @returns  The actual number of bytes received
+*/
+/**************************************************************************/
+uint16_t usb_cdc_recv(uint8_t* buffer, uint16_t max)
+{
+  ASSERT(buffer && max, 0);
+
+  return fifo_readArray(&ff_cdc_rx, buffer, max);
+}
+
+// ROM driver bug: cannot hook this to CIC_GetRequest
+// Need this to implement GetLineCode & detect
+//ErrorCode_t CDC_Control_GetRequest(USBD_HANDLE_T hUsb, USB_SETUP_PACKET *pSetup, uint8_t **pBuffer, uint16_t *length)
+//{
+//  return LPC_OK;
+//}
+
+/**************************************************************************/
+/*!
+    @brief TODO Add description
+*/
+/**************************************************************************/
+ErrorCode_t CDC_SetLineCoding(USBD_HANDLE_T hUsb, CDC_LINE_CODING *lineCoding)
+{
+  ASSERT(lineCoding, ERR_FAILED);
+  memcpy(&line_coding, lineCoding, sizeof(CDC_LINE_CODING));
+  return LPC_OK;
+}
+
+/**************************************************************************/
+/*!
+    @brief TODO Add description
+*/
+/**************************************************************************/
+ErrorCode_t CDC_SendBreak(USBD_HANDLE_T hCDC, uint16_t mstime)
+{
+  return LPC_OK;
+}
+
+/**************************************************************************/
+/*!
+    @brief Bulk Out handler for the USB ROM drivers (UART TX)
+*/
+/**************************************************************************/
+ErrorCode_t CDC_BulkIn_Hdlr(USBD_HANDLE_T hUsb, void* data, uint32_t event)
+{
+  if (USB_EVT_IN == event)
+  {
+    uint8_t buffer[CDC_DATA_EP_MAXPACKET_SIZE];
+    uint16_t count;
+
+    count = fifo_readArray(&ff_cdc_tx, buffer, CDC_DATA_EP_MAXPACKET_SIZE);
+    USBD_API->hw->WriteEP(hUsb, CDC_DATA_EP_IN, buffer, count); // write data to EP
+
+    isConnected = true;
+  }
+
+  return LPC_OK;
+}
+
+/**************************************************************************/
+/*!
+    @brief Bulk Out handler for the USB ROM drivers (UART RX)
+*/
+/**************************************************************************/
+ErrorCode_t CDC_BulkOut_Hdlr(USBD_HANDLE_T hUsb, void* data, uint32_t event)
+{
+  if (USB_EVT_OUT == event)
+  {
+    uint16_t count, i;
+    uint8_t buffer[CDC_DATA_EP_MAXPACKET_SIZE];
+
+    count = USBD_API->hw->ReadEP(hUsb, CDC_DATA_EP_OUT, buffer);
+    for (i=0; i<count; i++)
+    {
+      fifo_write(&ff_cdc_rx, buffer+i);
+    }
+
+    isConnected = true;
+
+    usb_cdc_recv_isr();
+  }
+
+  return LPC_OK;
+}
+
+/**************************************************************************/
+/*!
+    @brief Initialises USB CDC using the ROM driver
+*/
+/**************************************************************************/
+ErrorCode_t usb_cdc_init(USBD_HANDLE_T hUsb, USB_INTERFACE_DESCRIPTOR const *const pControlIntfDesc, USB_INTERFACE_DESCRIPTOR const *const pDataIntfDesc, uint32_t* mem_base, uint32_t* mem_size)
+{
+  USBD_CDC_INIT_PARAM_T cdc_param =
+  {
+    .mem_base      = *mem_base,
+    .mem_size      = *mem_size,
+
+    .cif_intf_desc = (uint8_t*) pControlIntfDesc,
+    .dif_intf_desc = (uint8_t*) pDataIntfDesc,
+
+    .SetLineCode   = CDC_SetLineCoding,
+    .SendBreak     = CDC_SendBreak,
+
+    // .CIC_GetRequest   = CDC_Control_GetRequest, // bug from romdrive cannot hook to this handler
+    // Bug from ROM driver: can not hook bulk in & out handler here, must use USBD API register instead
+    // .CDC_BulkIN_Hdlr  = CDC_BulkIn_Hdlr,
+    // .CDC_BulkOUT_Hdlr = CDC_BulkOut_Hdlr,
+  };
+
+  ASSERT (pControlIntfDesc && pDataIntfDesc, ERR_FAILED);
+
+  /* register Bulk IN & OUT endpoint interrupt handler */
+  ASSERT_USB_STATUS ( USBD_API->core->RegisterEpHandler (hUsb , ((CDC_DATA_EP_IN & 0x0F) << 1) +1 , CDC_BulkIn_Hdlr  , NULL) );
+  ASSERT_USB_STATUS ( USBD_API->core->RegisterEpHandler (hUsb , (CDC_DATA_EP_OUT & 0x0F) << 1     , CDC_BulkOut_Hdlr , NULL) );
+
+  ASSERT_USB_STATUS( USBD_API->cdc->init(hUsb, &cdc_param, &g_hCdc) );
+
+  /* Update memory variables */
+  ASSERT_MESSAGE(*mem_size > cdc_param.mem_size, ERR_FAILED, "not enough memory");
+
+  *mem_base += (*mem_size - cdc_param.mem_size);
+  *mem_size = cdc_param.mem_size;
+
+  isConnected = false;
+
+  return LPC_OK;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Callback when the USB Set Configured request is received
+*/
+/**************************************************************************/
+ErrorCode_t usb_cdc_configured(USBD_HANDLE_T hUsb)
+{
+  uint8_t dummy=0;
+  USBD_API->hw->WriteEP(hUsb, CDC_DATA_EP_IN, &dummy, 1); // initial packet for IN endpoint, will not work if omitted
+
+  isConnected = true;
+
+  fifo_clear(&ff_cdc_tx);
+  fifo_clear(&ff_cdc_rx);
+
+  return LPC_OK;
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/core/usb/usb_cdc.h b/reform2-lpc-fw/src/core/usb/usb_cdc.h
new file mode 100644
index 0000000000000000000000000000000000000000..e5fc50bb4d5f484c68f4027dbccd73bc0380329f
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/usb_cdc.h
@@ -0,0 +1,63 @@
+/**************************************************************************/
+/*!
+    @file     usb_cdc.h
+    @author   Thach Ha (tinyusb.net)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __USB_CDC_H__
+#define __USB_CDC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "romdriver/mw_usbd_rom_api.h"
+
+// #define CDC_BUFFER_SIZE (2*CDC_DATA_EP_MAXPACKET_SIZE)
+#define CDC_BUFFER_SIZE (4*CDC_DATA_EP_MAXPACKET_SIZE)
+
+bool usb_cdc_putc(uint8_t c);
+bool usb_cdc_getc(uint8_t *c);
+bool usb_cdc_isConnected();
+
+uint16_t usb_cdc_send(uint8_t* buffer, uint16_t count);
+uint16_t usb_cdc_recv(uint8_t* buffer, uint16_t max);
+
+ErrorCode_t usb_cdc_init(USBD_HANDLE_T hUsb, USB_INTERFACE_DESCRIPTOR const *const pControlIntfDesc, USB_INTERFACE_DESCRIPTOR const *const pDataIntfDesc, uint32_t* mem_base, uint32_t* mem_size);
+ErrorCode_t usb_cdc_configured(USBD_HANDLE_T hUsb);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/core/usb/usb_custom_class.c b/reform2-lpc-fw/src/core/usb/usb_custom_class.c
new file mode 100644
index 0000000000000000000000000000000000000000..950c2afb02a57982141543bc834d0c3c0d471260
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/usb_custom_class.c
@@ -0,0 +1,127 @@
+/**************************************************************************/
+/*!
+ @file     usb_custom_class.c
+ @author   hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2012, K. Townsend (microBuilder.eu)
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/**************************************************************************/
+
+//--------------------------------------------------------------------+
+// INCLUDE
+//--------------------------------------------------------------------+
+#include <string.h>
+#include "usbd.h"
+
+#ifdef CFG_USB_CUSTOM_CLASS
+
+//--------------------------------------------------------------------+
+// MACRO CONSTANT TYPEDEF
+//--------------------------------------------------------------------+
+
+//--------------------------------------------------------------------+
+// INTERNAL OBJECT & FUNCTION DECLARATION
+//--------------------------------------------------------------------+
+static volatile bool is_bulk_in_ready = false;
+
+//--------------------------------------------------------------------+
+// APPLICATION API (parameter validation required)
+//--------------------------------------------------------------------+
+bool usb_custom_is_ready_to_send(void)
+{
+  return usb_isConfigured() && is_bulk_in_ready;
+}
+
+ErrorCode_t usb_custom_send(uint8_t const * p_data, uint32_t length)
+{
+  ASSERT(p_data != NULL && length != 0 && usb_custom_is_ready_to_send(), ERR_FAILED );
+
+  uint32_t written_length = USBD_API->hw->WriteEP(g_hUsb, CUSTOM_EP_IN, (uint8_t*) p_data, length);
+  if ( written_length != length)
+  {
+    return ERR_FAILED;
+  }
+  is_bulk_in_ready = false;
+
+  return LPC_OK;
+}
+
+//--------------------------------------------------------------------+
+// IMPLEMENTATION
+//--------------------------------------------------------------------+
+
+//static ErrorCode_t endpoint_control_isr(USBD_HANDLE_T hUsb, void* data, uint32_t event)
+//{
+//  return LPC_OK;
+//}
+
+static ErrorCode_t endpoint_bulk_in_isr (USBD_HANDLE_T husb, void* data, uint32_t event)
+{
+  if (USB_EVT_IN == event)
+  {
+    is_bulk_in_ready = true;
+  }
+
+  return LPC_OK;
+}
+
+static ErrorCode_t endpoint_bulk_out_isr (USBD_HANDLE_T husb, void* data, uint32_t event)
+{
+  if (USB_EVT_OUT == event)
+  {
+    uint8_t buffer[64] = { 0 }; // size is 64
+    uint32_t length = USBD_API->hw->ReadEP(husb, CUSTOM_EP_OUT, buffer);
+    if (usb_custom_received_isr)
+    {
+      usb_custom_received_isr( buffer, length);
+    }
+  }
+  return LPC_OK;
+}
+
+ErrorCode_t usb_custom_init (USBD_HANDLE_T husb, USB_INTERFACE_DESCRIPTOR const * p_interface)
+{
+  (void) p_interface;
+
+//  ASSERT_USB_STATUS ( USBD_API->core->RegisterClassHandler(husb, endpoint_control_isr, NULL) );
+
+  ASSERT_USB_STATUS ( USBD_API->core->RegisterEpHandler (husb, ((CUSTOM_EP_IN & 0x0F) << 1) +1, endpoint_bulk_in_isr , NULL) );
+  ASSERT_USB_STATUS ( USBD_API->core->RegisterEpHandler (husb, (CUSTOM_EP_OUT & 0x0F) << 1 , endpoint_bulk_out_isr, NULL) );
+  return LPC_OK;
+}
+
+ErrorCode_t usb_custom_configured (USBD_HANDLE_T husb)
+{
+  is_bulk_in_ready = true;
+
+  return LPC_OK;
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/core/usb/usb_custom_class.h b/reform2-lpc-fw/src/core/usb/usb_custom_class.h
new file mode 100644
index 0000000000000000000000000000000000000000..5717310f2aa26c9f1cec6fffb701a40853d749a3
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/usb_custom_class.h
@@ -0,0 +1,74 @@
+/**************************************************************************/
+/*!
+    @file     usb_custom_class.h
+    @author   hathach (tinyusb.org)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+
+/** \ingroup TBD
+ *  \defgroup TBD
+ *  \brief TBD
+ *
+ *  @{
+ */
+
+#ifndef __USB_CUSTOM_CLASS_H__
+#define __USB_CUSTOM_CLASS_H__
+
+#include "projectconfig.h"
+#include "romdriver/mw_usbd_rom_api.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+//--------------------------------------------------------------------+
+// APPLICATION API
+//--------------------------------------------------------------------+
+bool usb_custom_is_ready_to_send(void);
+ErrorCode_t usb_custom_send(uint8_t const * p_data, uint32_t length);
+void usb_custom_received_isr(uint8_t * p_buffer, uint32_t length) __attribute__((weak));
+
+//--------------------------------------------------------------------+
+// USBD-CLASS API
+//--------------------------------------------------------------------+
+ErrorCode_t usb_custom_init(USBD_HANDLE_T husb, USB_INTERFACE_DESCRIPTOR const * p_interface);
+ErrorCode_t usb_custom_configured(USBD_HANDLE_T husb);
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* __USB_CUSTOM_CLASS_H__ */
+
+/** @} */
diff --git a/reform2-lpc-fw/src/core/usb/usb_hid.c b/reform2-lpc-fw/src/core/usb/usb_hid.c
new file mode 100644
index 0000000000000000000000000000000000000000..a88fc50fa174e470d0c8ccf7f1a2013b42fad45c
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/usb_hid.c
@@ -0,0 +1,469 @@
+/**************************************************************************/
+/*!
+    @file     usb_hid.c
+    @author   Thach Ha (tinyusb.net)
+
+    @section DESCRIPTION
+
+    HID support functions for USB
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <string.h>
+#include "usbd.h"
+#include "../delay/delay.h"
+
+#ifdef CFG_USB_HID
+
+#ifdef CFG_USB_HID_KEYBOARD
+USB_HID_KeyboardReport_t hid_keyboard_report;
+volatile static bool bKeyChanged = false;
+#endif
+
+#ifdef CFG_USB_HID_MOUSE
+USB_HID_MouseReport_t hid_mouse_report;
+volatile static bool bMouseChanged = false;
+#endif
+
+#ifdef CFG_USB_HID_GENERIC
+
+uint8_t hid_generic_report_in[CFG_USB_HID_GENERIC_REPORT_SIZE];
+volatile static bool bGenericChanged= false;
+
+#endif
+
+/**************************************************************************/
+/*!
+    @brief Handler for HID_GetReport in the USB ROM driver
+*/
+/**************************************************************************/
+ErrorCode_t HID_GetReport( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t* plength)
+{
+  USB_HID_CTRL_T* pHidCtrl = (USB_HID_CTRL_T*) hHid;
+
+  /* ReportID = SetupPacket.wValue.WB.L; */
+  if (pSetup->wValue.WB.H != HID_REPORT_INPUT)
+    return (ERR_USBD_STALL);          /* Not Supported */
+
+  switch (pHidCtrl->protocol)
+  {
+#ifdef CFG_USB_HID_KEYBOARD
+    case HID_PROTOCOL_KEYBOARD:
+      *pBuffer = (uint8_t*) &hid_keyboard_report;
+      *plength = sizeof(USB_HID_KeyboardReport_t);
+
+      if (!bKeyChanged)
+      {
+        memset(pBuffer, 0, *plength);
+      }
+      bKeyChanged = false;
+      break;
+#endif
+
+#ifdef CFG_USB_HID_MOUSE
+    case HID_PROTOCOL_MOUSE:
+      *pBuffer = (uint8_t*) &hid_mouse_report;
+      *plength = sizeof(USB_HID_MouseReport_t);
+
+      if (!bMouseChanged)
+      {
+        memset(pBuffer, 0, *plength);
+      }
+      bMouseChanged = false;
+      break;
+#endif
+
+    default:
+#ifdef CFG_USB_HID_GENERIC
+      if (pHidCtrl->epin_adr == HID_GENERIC_EP_IN)
+      {
+        if (!bGenericChanged) // no report to send
+        {
+          // callback is not defined in application or return false --> sent 0s
+          if ( ! (usb_hid_generic_report_request_isr && usb_hid_generic_report_request_isr(hid_generic_report_in)) )
+          {
+            memset(hid_generic_report_in, 0x00, CFG_USB_HID_GENERIC_REPORT_SIZE);
+          }
+        }
+
+        *pBuffer = hid_generic_report_in;
+        *plength = CFG_USB_HID_GENERIC_REPORT_SIZE;
+
+        bGenericChanged = false;
+      }
+#endif
+    break;
+  }
+
+  return (LPC_OK);
+}
+
+/**************************************************************************/
+/*!
+    @brief Handler for HID_SetReport in the USB ROM driver
+*/
+/**************************************************************************/
+ErrorCode_t HID_SetReport( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t length)
+{
+  USB_HID_CTRL_T* pHidCtrl = (USB_HID_CTRL_T*) hHid;
+
+  /* Reuse standard EP0Buf */
+  if (length == 0)
+    return LPC_OK;
+
+  /* ReportID = SetupPacket.wValue.WB.L; */
+  if (pSetup->wValue.WB.H != HID_REPORT_OUTPUT)
+    return (ERR_USBD_STALL);          /* Not Supported */
+
+  switch (pHidCtrl->protocol)
+  {
+#ifdef CFG_USB_HID_KEYBOARD
+    case HID_PROTOCOL_KEYBOARD:
+
+    break;
+#endif
+
+#ifdef CFG_USB_HID_MOUSE
+    case HID_PROTOCOL_MOUSE:
+
+    break;
+#endif
+
+    default:
+#ifdef CFG_USB_HID_GENERIC
+      if (pHidCtrl->epout_adr == HID_GENERIC_EP_OUT)
+      {
+        if ( usb_hid_generic_recv_isr )
+        {
+          usb_hid_generic_recv_isr( (*pBuffer), (uint32_t) length );
+        }
+      }
+#endif
+    break;
+  }
+  return (LPC_OK);
+}
+
+/**************************************************************************/
+/*!
+    @brief HID endpoint in handler for the USB ROM driver
+*/
+/**************************************************************************/
+ErrorCode_t HID_EpIn_Hdlr (USBD_HANDLE_T hUsb, void* data, uint32_t event)
+{
+  if (USB_EVT_IN == event)
+  {
+    USB_HID_CTRL_T* pHidCtrl = (USB_HID_CTRL_T*)data;
+    switch(pHidCtrl->protocol)
+    {
+      #ifdef CFG_USB_HID_KEYBOARD
+        case HID_PROTOCOL_KEYBOARD:
+          if (!bKeyChanged)
+          {
+            memset(&hid_keyboard_report, 0, sizeof(USB_HID_KeyboardReport_t));
+          }
+          USBD_API->hw->WriteEP(hUsb, pHidCtrl->epin_adr, (uint8_t*) &hid_keyboard_report, sizeof(USB_HID_KeyboardReport_t));
+          bKeyChanged = false;
+        break;
+      #endif
+
+      #ifdef CFG_USB_HID_MOUSE
+        case HID_PROTOCOL_MOUSE:
+          if (!bMouseChanged)
+          {
+            memset(&hid_mouse_report, 0, sizeof(USB_HID_MouseReport_t));
+          }
+          USBD_API->hw->WriteEP(hUsb, pHidCtrl->epin_adr, (uint8_t*) &hid_mouse_report, sizeof(USB_HID_MouseReport_t));
+          bMouseChanged = false;
+        break;
+      #endif
+
+      default:
+      #ifdef CFG_USB_HID_GENERIC
+        if (pHidCtrl->epin_adr == HID_GENERIC_EP_IN)
+        {
+          // report is ready or callback is define and return with true
+          if (bGenericChanged || (usb_hid_generic_report_request_isr && usb_hid_generic_report_request_isr(hid_generic_report_in)) )
+          {
+            USBD_API->hw->WriteEP(hUsb, pHidCtrl->epin_adr, hid_generic_report_in, CFG_USB_HID_GENERIC_REPORT_SIZE);
+          }else
+          {
+            // callback is not defined in application or return false --> NAK
+            USBD_API->hw->WriteEP(hUsb, pHidCtrl->epin_adr, NULL, 0); // write size = 0 for NAK TODO need to be confirmed
+          }
+          bGenericChanged = false;
+        }
+      #endif
+        break;
+    }
+  }
+
+  return LPC_OK;
+}
+
+/**************************************************************************/
+/*!
+    @brief HID endpoint out handler for the USB ROM driver
+*/
+/**************************************************************************/
+ErrorCode_t HID_EpOut_Hdlr (USBD_HANDLE_T hUsb, void* data, uint32_t event)
+{
+  if (USB_EVT_OUT == event)
+  {
+    USB_HID_CTRL_T* pHidCtrl = (USB_HID_CTRL_T*)data;
+
+#ifdef CFG_USB_HID_GENERIC
+    if (pHidCtrl->epout_adr == HID_GENERIC_EP_OUT)
+    {
+      uint8_t out_report[CFG_USB_HID_GENERIC_REPORT_SIZE];
+      uint32_t length;
+
+      length = USBD_API->hw->ReadEP(hUsb, pHidCtrl->epout_adr, out_report);
+
+      if (usb_hid_generic_recv_isr)
+      {
+        usb_hid_generic_recv_isr(out_report, length);
+      }
+    }
+#endif
+  }
+  return LPC_OK;
+}
+
+/**************************************************************************/
+/*!
+    @brief Initialises USB HID using the ROM based drivers
+*/
+/**************************************************************************/
+ErrorCode_t usb_hid_init(USBD_HANDLE_T hUsb, USB_INTERFACE_DESCRIPTOR const *const pIntfDesc, uint8_t const * const pHIDReportDesc, uint32_t ReportDescLength, uint32_t* mem_base, uint32_t* mem_size)
+{
+  USB_HID_REPORT_T reports_data =
+  {
+      .desc      = (uint8_t*) pHIDReportDesc,
+      .len       = ReportDescLength,
+      .idle_time = 0,
+  };
+
+  USBD_HID_INIT_PARAM_T hid_param =
+  {
+      .mem_base       = *mem_base,
+      .mem_size       = *mem_size,
+
+      .intf_desc      = (uint8_t*)pIntfDesc,
+      .report_data    = &reports_data,
+      .max_reports    = 1,
+
+      /* user defined functions */
+      .HID_GetReport  = HID_GetReport,
+      .HID_SetReport  = HID_SetReport,
+      .HID_EpIn_Hdlr  = HID_EpIn_Hdlr,
+      .HID_EpOut_Hdlr = HID_EpOut_Hdlr
+  };
+
+  ASSERT( (pIntfDesc != NULL) && (pIntfDesc->bInterfaceClass == USB_DEVICE_CLASS_HUMAN_INTERFACE), ERR_FAILED);
+
+  ASSERT_USB_STATUS( USBD_API->hid->init(hUsb, &hid_param) );
+
+  /* update memory variables */
+  ASSERT_MESSAGE(*mem_size > hid_param.mem_size, ERR_FAILED, "not enough memory");
+
+  *mem_base += (*mem_size - hid_param.mem_size);
+  *mem_size = hid_param.mem_size;
+
+  return LPC_OK;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Callback when the USB Set Configured request is received
+*/
+/**************************************************************************/
+ErrorCode_t usb_hid_configured(USBD_HANDLE_T hUsb)
+{
+  #ifdef  CFG_USB_HID_KEYBOARD
+    USBD_API->hw->WriteEP(hUsb , HID_KEYBOARD_EP_IN , (uint8_t* ) &hid_keyboard_report , sizeof(USB_HID_KeyboardReport_t) ); // initial packet for IN endpoint , will not work if omitted
+  #endif
+
+  #ifdef  CFG_USB_HID_MOUSE
+    USBD_API->hw->WriteEP(hUsb , HID_MOUSE_EP_IN    , (uint8_t* ) &hid_mouse_report    , sizeof(USB_HID_MouseReport_t) ); // initial packet for IN endpoint, will not work if omitted
+  #endif
+
+  #ifdef CFG_USB_HID_GENERIC
+    USBD_API->hw->WriteEP(hUsb , HID_GENERIC_EP_IN  , hid_generic_report_in, CFG_USB_HID_GENERIC_REPORT_SIZE); // initial packet for IN endpoint, will not work if omitted
+  #endif
+
+  return LPC_OK;
+}
+
+#ifdef CFG_USB_HID_KEYBOARD
+/**************************************************************************/
+/*!
+    @brief Send the supplied key codes out via HID USB keyboard emulation
+
+    @param[in]  modifier
+                KB modifier code bits (see USB_HID_KB_KEYMODIFIER_CODE)
+    @param[in]  keycodes
+                A buffer containing up to six keycodes
+    @param[in]  numkey
+                The number of keys to send (max 6)
+
+    @note Note that for HID KBs, letter codes are not case sensitive. To
+          create an upper-case letter, you need to include the correct
+          KB modifier code(s), for ex: HID_KEYMODIFIER_LEFTSHIFT
+
+    @code
+    // Send an unmodified 'a' character
+    if (usb_isConfigured())
+    {
+      uint8_t keys[6] = {HID_USAGE_KEYBOARD_aA};
+      usb_hid_keyboard_sendKeys(0x00, keys, 1);
+    }
+
+    // Send Windows + 'e' (shortcut for 'explorer.exe')
+    if (usb_isConfigured())
+    {
+      uint8_t keys[6] = {HID_USAGE_KEYBOARD_aA + 'e' - 'a'};
+      usb_hid_keyboard_sendKeys(HID_KEYMODIFIER_LEFTGUI, keys, 1);
+    }
+    @endcode
+*/
+/**************************************************************************/
+ErrorCode_t usb_hid_keyboard_sendKeys(uint8_t modifier, uint8_t keycodes[], uint8_t numkey)
+{
+  uint32_t start_time = delayGetSecondsActive();
+  while (bKeyChanged) // TODO blocking while previous key has yet sent - can use fifo to improve this
+  {
+    ASSERT_MESSAGE(delayGetSecondsActive() - start_time < 5, ERR_FAILED, "HID Keyboard Timeout");
+  }
+  ASSERT(keycodes && numkey && numkey <=6, ERR_FAILED);
+
+  hid_keyboard_report.Modifier = modifier;
+  memset(hid_keyboard_report.KeyCode, 0, 6);
+  memcpy(hid_keyboard_report.KeyCode, keycodes, numkey);
+
+  bKeyChanged = true;
+
+  return LPC_OK;
+}
+#endif
+
+#ifdef CFG_USB_HID_MOUSE
+/**************************************************************************/
+/*!
+    @brief Send the supplied mouse event out via HID USB mouse emulation
+
+    @param[in]  buttons
+                Indicate which button(s) are being pressed (see
+                USB_HID_MOUSE_BUTTON_CODE)
+    @param[in]  x
+                Position adjustment on the X scale
+    @param[in]  y
+                Position adjustment on the Y scale
+    @param[in]  wheel
+                Position adjustment of the vertical scroll wheel
+    @param[in]  pan
+                Position adjustment on the horizontal scroll wheel
+
+    @code
+    if (usb_isConfigured())
+    {
+      // Move the mouse +10 in the X direction and + 10 in the Y direction
+      usb_hid_mouse_send(0, 10, 10, 0, 0);
+
+      // Click the back mouse button
+      usb_hid_mouse_send(HID_MOUSEBUTTON_BACKWARD, 0, 0, 0, 0);
+
+      // Advance the middle scroll wheel
+      usb_hid_mouse_send(0, 0, 0, 5, 0);
+    }
+    @endcode
+*/
+/**************************************************************************/
+ErrorCode_t usb_hid_mouse_send(uint8_t buttons, int8_t x, int8_t y, int8_t wheel, int8_t pan)
+{
+  uint32_t start_time = delayGetSecondsActive();
+  while (bMouseChanged) // TODO Block while previous key hasn't been sent - can use fifo to improve this
+  {
+    ASSERT_MESSAGE(delayGetSecondsActive() - start_time < 5, ERR_FAILED, "HID Mouse Timeout");
+  }
+
+  hid_mouse_report.Button = buttons;
+  hid_mouse_report.X      = x;
+  hid_mouse_report.Y      = y;
+  hid_mouse_report.Wheel  = wheel;
+  hid_mouse_report.Pan    = pan;
+
+  bMouseChanged = true;
+
+  return LPC_OK;
+}
+#endif
+
+#ifdef CFG_USB_HID_GENERIC
+
+
+/**************************************************************************/
+/*!
+    @brief Send the specified HID report to the host
+
+    @param[in]  report
+                The USB_HID_GenericReport_t instance containing the
+                report values to transmit to the host
+
+    @code
+    if (usb_isConfigured())
+    {
+      uint32_t currentSecond = delayGetSecondsActive();
+      uint8_t in_report[CFG_USB_HID_GENERIC_REPORT_SIZE] = { currentSecond % 100 };
+      usb_hid_generic_send(in_report, CFG_USB_HID_GENERIC_REPORT_SIZE);
+    }
+    @endcode
+*/
+/**************************************************************************/
+ErrorCode_t usb_hid_generic_send(uint8_t const* p_report_in, uint32_t length)
+{
+  uint32_t start_time = delayGetSecondsActive();
+
+  ASSERT(p_report_in && length <= CFG_USB_HID_GENERIC_REPORT_SIZE, ERR_FAILED);
+  while (bGenericChanged) // TODO Block while previous key hasn't been sent - can use fifo to improve this
+  {
+    ASSERT_MESSAGE(delayGetSecondsActive() - start_time < 5, ERR_FAILED, "HID Generic Timeout");
+  }
+
+  memset(&hid_generic_report_in, 0, CFG_USB_HID_GENERIC_REPORT_SIZE);
+  memcpy(&hid_generic_report_in, p_report_in, length);
+  bGenericChanged = true;
+
+  return LPC_OK;
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/core/usb/usb_hid.h b/reform2-lpc-fw/src/core/usb/usb_hid.h
new file mode 100644
index 0000000000000000000000000000000000000000..393e081150476e79b7a4d382d1303c90c3400a90
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/usb_hid.h
@@ -0,0 +1,206 @@
+/**************************************************************************/
+/*!
+    @file     usb_hid.h
+    @author   Thach Ha (tinyusb.net)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __USB_HID_H__
+#define __USB_HID_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "romdriver/mw_usbd_rom_api.h"
+
+#define HID_USAGE_CONSUMER_ACPAN     0x38, 0x02 // 0x0238
+#define HID_Usage_2Bytes(x)          0x0a, x
+
+ErrorCode_t usb_hid_init(USBD_HANDLE_T hUsb, USB_INTERFACE_DESCRIPTOR const *const pIntfDesc, uint8_t const * const pHIDReportDesc, uint32_t ReportDescLength, uint32_t* mem_base, uint32_t* mem_size);
+ErrorCode_t usb_hid_configured(USBD_HANDLE_T hUsb);
+
+ErrorCode_t usb_hid_keyboard_sendKeys(uint8_t modifier, uint8_t keycodes[], uint8_t numkey);
+ErrorCode_t usb_hid_mouse_send(uint8_t buttons, int8_t x, int8_t y, int8_t wheel, int8_t pan);
+ErrorCode_t usb_hid_generic_send(uint8_t const* p_report_in, uint32_t length);
+/**************************************************************************/
+/*!
+    @brief      Weak ISR handler for HID Generic out reports (PC to LPC).
+
+    @param[in]  report
+                Pointer to the buffer that holds the
+                incoming report data
+
+    @param[in]  length
+                For most of the time it is CFG_USB_HID_GENERIC_REPORT_SIZE
+                except for few time (if any) host sends out short-packet
+
+    @note       Since this is a 'weak' function, to override it you
+                simply need to declare a new function with the same name
+                somewhere else in your code.
+
+    @code
+    // Buffer to hold incoming HID data
+    static uint8_t hid_out_report[CFG_USB_HID_GENERIC_REPORT_SIZE];
+    static bool is_received_report = false;
+
+    int main(void)
+    {
+      ...
+      while(1)
+      {
+        ...
+        #ifdef CFG_USB_HID_GENERIC
+          if(usb_isConfigured())
+          {
+            if(is_received_report)
+            {
+              for (uint32_t i=0; i<CFG_USB_HID_GENERIC_REPORT_SIZE; i++)
+              {
+                // Display incoming HID data with CDC using printf
+                printf("%02x ", hid_out_report.report[i]);
+              }
+              printf(CFG_PRINTF_NEWLINE);
+              is_received_report = false;
+            }
+          }
+        #endif
+      }
+    }
+
+    void usb_hid_generic_recv_isr(uint8_t out_report[], uint32_t length)
+    {
+      // Copy out_report to a buffer in case new data comes in
+      memcpy(hid_out_report, out_report, length);
+      is_received_report = true;
+    }
+    @endcode
+*/
+/**************************************************************************/
+void usb_hid_generic_recv_isr(uint8_t * p_buffer, uint32_t length) __attribute__((weak));
+
+// receive report in request from HOST, but have nothing to report
+bool usb_hid_generic_report_request_isr(uint8_t in_report[]) __attribute__((weak));
+
+
+/** \brief Standard HID Boot Protocol Mouse Report.
+ *
+ *  Type define for a standard Boot Protocol Mouse report
+ */
+typedef PRE_PACK struct
+{
+  uint8_t Button;      /**< Button mask for currently pressed buttons in the mouse. */
+  int8_t  X;           /**< Current delta X movement of the mouse. */
+  int8_t  Y;           /**< Current delta Y movement on the mouse. */
+  int8_t  Wheel;
+  int8_t  Pan;
+} POST_PACK USB_HID_MouseReport_t;
+
+/** \brief Standard HID Boot Protocol Keyboard Report.
+ *
+ *  Type define for a standard Boot Protocol Keyboard report
+ */
+typedef PRE_PACK struct
+{
+  uint8_t Modifier;    /**< Keyboard modifier byte, indicating pressed modifier keys (a combination of HID_KEYBOARD_MODIFER_* masks). */
+  uint8_t Reserved;    /**< Reserved for OEM use, always set to 0. */
+  uint8_t KeyCode[6];  /**< Key codes of the currently pressed keys. */
+} POST_PACK USB_HID_KeyboardReport_t;
+
+/* Button codes for HID mouse */
+enum USB_HID_MOUSE_BUTTON_CODE
+{
+  HID_MOUSEBUTTON_LEFT     = 1,
+  HID_MOUSEBUTTON_RIGHT    = 2,
+  HID_MOUSEBUTTON_MIDDLE   = 4,
+  HID_MOUSEBUTTON_BACKWARD = 8,
+  HID_MOUSEBUTTON_FORWARD  = 16
+};
+
+/* KB modifier codes for HID KB */
+enum USB_HID_KB_KEYMODIFIER_CODE
+{
+  HID_KEYMODIFIER_LEFTCTRL   = 1,
+  HID_KEYMODIFIER_LEFTSHIFT  = 2,
+  HID_KEYMODIFIER_LEFTALT    = 4,
+  HID_KEYMODIFIER_LEFTGUI    = 8,
+  HID_KEYMODIFIER_RIGHTCTRL  = 16,
+  HID_KEYMODIFIER_RIGHTSHIFT = 32,
+  HID_KEYMODIFIER_RIGHTALT   = 64,
+  HID_KEYMODIFIER_RIGHTGUI   = 128
+};
+
+enum USB_HID_LOCAL_CODE
+{
+  HID_Local_NotSupported = 0,
+  HID_Local_Arabic,
+  HID_Local_Belgian,
+  HID_Local_Canadian_Bilingual,
+  HID_Local_Canadian_French,
+  HID_Local_Czech_Republic,
+  HID_Local_Danish,
+  HID_Local_Finnish,
+  HID_Local_French,
+  HID_Local_German,
+  HID_Local_Greek,
+  HID_Local_Hebrew,
+  HID_Local_Hungary,
+  HID_Local_International,
+  HID_Local_Italian,
+  HID_Local_Japan_Katakana,
+  HID_Local_Korean,
+  HID_Local_Latin_American,
+  HID_Local_Netherlands_Dutch,
+  HID_Local_Norwegian,
+  HID_Local_Persian_Farsi,
+  HID_Local_Poland,
+  HID_Local_Portuguese,
+  HID_Local_Russia,
+  HID_Local_Slovakia,
+  HID_Local_Spanish,
+  HID_Local_Swedish,
+  HID_Local_Swiss_French,
+  HID_Local_Swiss_German,
+  HID_Local_Switzerland,
+  HID_Local_Taiwan,
+  HID_Local_Turkish_Q,
+  HID_Local_UK,
+  HID_Local_US,
+  HID_Local_Yugoslavia,
+  HID_Local_Turkish_F
+};
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/core/usb/usb_msc.c b/reform2-lpc-fw/src/core/usb/usb_msc.c
new file mode 100644
index 0000000000000000000000000000000000000000..31e4bc8951783d17d63a2e2fcac534b995d498d5
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/usb_msc.c
@@ -0,0 +1,198 @@
+/**************************************************************************/
+/*!
+    @file     usb_msc.c
+    @author   Thach Ha (tinyusb.net)
+
+    @section DESCRIPTION
+
+    MSC support functions for USB
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <string.h>
+#include "usbd.h"
+#include "core/fifo/fifo.h"
+#include "drivers/storage/fatfs/diskio.h"
+
+#ifdef CFG_USB_MSC
+#define CACHE_SIZE 512
+
+const uint8_t usb_msc_inquiry[] = "microBuilder.eu";
+
+/* void print_cache(uint8_t* buffer)
+{
+  uint32_t i;
+  for (i=0; i<512; i++)
+  {
+    if (i%16 == 0)
+    {
+      printf("\n");
+    }
+    printf("%X ", buffer[i]);
+  }
+  printf("\n");
+}*/
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void MSC_Write(uint32_t offset, uint8_t **src, uint32_t length)
+{
+  static uint8_t cache_data[CACHE_SIZE];
+  static uint32_t cache_sector = UINT32_MAX;
+  static uint32_t cache_count = 0;
+
+  ASSERT(length + cache_count <= CACHE_SIZE, (void) 0); // current implementation of Rom Driver does not has length > 512, here is just safe guard
+
+  if ( cache_sector != (offset / CACHE_SIZE) ) // new block
+  {
+    cache_sector = (offset / CACHE_SIZE);
+    cache_count = 0;
+  }
+
+  memcpy(cache_data + cache_count, *src, length);
+  cache_count += length;
+
+  if ( cache_count == CACHE_SIZE) // not enough to write, continue caching
+  {
+    ASSERT( disk_write(0, cache_data, cache_sector, 1) == RES_OK, (void) 0 );
+    cache_count = 0;
+  }
+
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void MSC_Read(uint32_t offset, uint8_t **dst, uint32_t length)
+{
+  static uint8_t cache_data[CACHE_SIZE];
+  static uint32_t cache_sector = UINT32_MAX;
+
+  ASSERT(length <= CACHE_SIZE, (void) 0); // current implementation of Rom Driver does not has length > 512, here is just safe guard
+
+  if ( cache_sector != (offset / CACHE_SIZE) ) // new block
+  {
+    cache_sector = (offset / CACHE_SIZE);
+    ASSERT( disk_read(0, cache_data, cache_sector, 1) == RES_OK, (void) 0 );
+  }
+
+  memcpy(*dst, cache_data + (offset%CACHE_SIZE), length);
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+ErrorCode_t MSC_Verify(uint32_t offset, uint8_t buf[], uint32_t length)
+{
+//  return memcmp(DiskImage + offset, buf, length) ? ERR_FAILED : LPC_OK;
+  return LPC_OK;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void MSC_GetWriteBuf(uint32_t offset, uint8_t **buff_adr, uint32_t length)
+{
+
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+ErrorCode_t usb_msc_init(USBD_HANDLE_T hUsb, USB_INTERFACE_DESCRIPTOR const * const pInterface, uint32_t *mem_base, uint32_t *mem_size)
+{
+  uint16_t sector_size = 0;
+  uint32_t sector_count = 0;
+
+  ASSERT( pInterface, ERR_FAILED);
+
+  if (disk_status(0) & STA_NOINIT)
+  {
+    ASSERT( !(disk_initialize(0) & (STA_NOINIT | STA_NODISK) ), ERR_FAILED);
+  }
+
+  ASSERT ( disk_ioctl(0, GET_SECTOR_SIZE , &sector_size)  == RES_OK, ERR_FAILED);
+  ASSERT ( disk_ioctl(0, GET_SECTOR_COUNT, &sector_count) == RES_OK, ERR_FAILED);
+
+  USBD_MSC_INIT_PARAM_T msc_param =
+  {
+      .mem_base        = *mem_base,
+      .mem_size        = *mem_size,
+
+      .BlockSize       = sector_size,
+      .BlockCount      = sector_count,
+      .MemorySize      = sector_size*sector_count,
+
+      .InquiryStr      = (uint8_t*) usb_msc_inquiry,
+      .intf_desc       = (uint8_t*) pInterface,
+
+      .MSC_Write       = MSC_Write,
+      .MSC_Read        = MSC_Read,
+      .MSC_Verify      = MSC_Verify,
+      .MSC_GetWriteBuf = MSC_GetWriteBuf
+  };
+
+
+  ASSERT_USB_STATUS( USBD_API->msc->init(hUsb, &msc_param) );
+
+  ASSERT_MESSAGE( *mem_size > msc_param.mem_size, ERR_FAILED, "not enough memory");
+
+  *mem_base += (*mem_size - msc_param.mem_size);
+  *mem_size = msc_param.mem_size;
+
+  return LPC_OK;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+ErrorCode_t usb_msc_configured(USBD_HANDLE_T hUsb)
+{
+  uint8_t dummy = 0;
+
+  USBD_API->hw->WriteEP(hUsb , MSC_EP_IN , &dummy , 1); // initial packet for IN endpoint , will not work if omitted
+  return LPC_OK;
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/core/usb/usb_msc.h b/reform2-lpc-fw/src/core/usb/usb_msc.h
new file mode 100644
index 0000000000000000000000000000000000000000..0821285412c6c857ba0ce6fd5a7fe0da813f4169
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/usb_msc.h
@@ -0,0 +1,53 @@
+/**************************************************************************/
+/*!
+    @file     usb_msc.h
+    @author   Thach Ha (tinyusb.net)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __USB_MSC_H__
+#define __USB_MSC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "romdriver/mw_usbd_rom_api.h"
+
+ErrorCode_t usb_msc_init(USBD_HANDLE_T hUsb, USB_INTERFACE_DESCRIPTOR const * const pInterface, uint32_t *mem_base, uint32_t *mem_size);
+ErrorCode_t usb_msc_configured(USBD_HANDLE_T hUsb);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif /* USB_MSC_H_ */
diff --git a/reform2-lpc-fw/src/core/usb/usbd.c b/reform2-lpc-fw/src/core/usb/usbd.c
new file mode 100644
index 0000000000000000000000000000000000000000..db4ea67b70a50442a7c546c2940dc958087b4092
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/usbd.c
@@ -0,0 +1,256 @@
+/**************************************************************************/
+/*!
+    @file     usbd.c
+    @author   Thach Ha (tinyusb.net)
+
+    @section DESCRIPTION
+
+    Core USB functions
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifdef __CODE_RED
+  #include <cr_section_macros.h>
+#endif
+
+#include "projectconfig.h"
+
+#include <string.h>
+
+#include "usbd.h"
+#include "core/iap/iap.h"
+
+#ifdef CFG_USB
+
+#define USB_ROM_SIZE (1024*2)
+
+volatile static bool isConfigured = false;
+
+#if defined(__CODE_RED)
+  /* Comment or uncomment the __DATA(RAM2) appendix to place the
+     buffer in the 2KB USB SRAM or the regular 8KB SRAM block.
+     This may need to go in the 8KB block if the buffer requires
+     more than 2KB, and should be verified when modifying the
+     USB drivers */
+  uint8_t usb_RomDriver_buffer[USB_ROM_SIZE] ALIGNED(2048) __DATA(RAM2);
+#elif defined(__CROSSWORKS_ARM)
+  /* Crossworks doesn't define a 2KB USB SRAM region in the */
+  /* default memory map so just point to the address for now */
+  uint8_t *usb_RomDriver_buffer = (uint8_t*)0x20004800;
+#else
+  uint8_t *usb_RomDriver_buffer = (uint8_t*)0x20004800;
+#endif
+
+USBD_HANDLE_T g_hUsb;
+
+/**************************************************************************/
+/*!
+    @brief Indicates whether USB is configured or not
+*/
+/**************************************************************************/
+bool usb_isConfigured(void)
+{
+  return isConfigured;
+}
+
+
+/**************************************************************************/
+/*!
+    @brief Handler for the USB Configure Event
+*/
+/**************************************************************************/
+ErrorCode_t USB_Configure_Event (USBD_HANDLE_T hUsb)
+{
+  USB_CORE_CTRL_T* pCtrl = (USB_CORE_CTRL_T*)hUsb;
+  if (pCtrl->config_value)
+  {
+    #if defined(CFG_USB_HID)
+    ASSERT_USB_STATUS( usb_hid_configured(hUsb) );
+    #endif
+
+    #ifdef CFG_USB_CDC
+    ASSERT_USB_STATUS( usb_cdc_configured(hUsb) );
+    #endif
+
+    #ifdef CFG_USB_MSC
+    ASSERT_USB_STATUS( usb_msc_configured(hUsb));
+    #endif
+
+    #ifdef CFG_USB_CUSTOM_CLASS
+    ASSERT_USB_STATUS( usb_custom_configured(hUsb) );
+    #endif
+  }
+
+  isConfigured = true;
+
+  return LPC_OK;
+}
+
+/**************************************************************************/
+/*!
+    @brief Handler for the USB Reset Event
+*/
+/**************************************************************************/
+ErrorCode_t USB_Reset_Event (USBD_HANDLE_T hUsb)
+{
+  isConfigured = false;
+  return LPC_OK;
+}
+
+/**************************************************************************/
+/*!
+    @brief Initialises device for USB and starts the enumeration process
+*/
+/**************************************************************************/
+ErrorCode_t usb_init(void)
+{
+  uint32_t i;
+  uint32_t uid[4];
+
+  /* HARDWARE INIT */
+
+  /* Enable AHB clock to the USB block and USB RAM. */
+  LPC_SYSCON->SYSAHBCLKCTRL |= ((0x1<<14) | (0x1<<27));
+
+  /* Pull-down is needed, or internally, VBUS will be floating. This is to
+  address the wrong status in VBUSDebouncing bit in CmdStatus register.  */
+  LPC_IOCON->PIO0_3   &= ~0x1F;
+  LPC_IOCON->PIO0_3   |= (0x01<<0);            /* Secondary function VBUS */
+  LPC_IOCON->PIO0_6   &= ~0x07;
+  LPC_IOCON->PIO0_6   |= (0x01<<0);            /* Secondary function SoftConn */
+
+  for (i=0; i < strlen(CFG_USB_STRING_MANUFACTURER); i++)
+    USB_StringDescriptor.strManufacturer[i] = CFG_USB_STRING_MANUFACTURER[i];
+
+  for (i=0; i < strlen(CFG_USB_STRING_PRODUCT); i++)
+    USB_StringDescriptor.strProduct[i] = CFG_USB_STRING_PRODUCT[i];
+
+  /* Use the 128-bit chip ID for USB serial to make sure it's unique */
+  iapReadUID(uid);  /* 1st byte is LSB, 4th byte is MSB */
+  sprintf((char*)USB_StringDescriptor.strSerial , "%08X%08X%08X%08X", (unsigned int)uid[3], (unsigned int)uid[2], (unsigned int)uid[1], (unsigned int)uid[0]);
+  for (i = USB_STRING_SERIAL_LEN-1; i > 0; i--)
+  {
+    USB_StringDescriptor.strSerial[i] = ((uint8_t*)USB_StringDescriptor.strSerial)[i];
+    ((uint8_t*)USB_StringDescriptor.strSerial)[i] = 0;
+  }
+
+  /* ROM DRIVER INIT */
+  uint32_t membase = (uint32_t) usb_RomDriver_buffer;
+  uint32_t memsize = USB_ROM_SIZE;
+
+  USBD_API_INIT_PARAM_T usb_param =
+    {
+    .usb_reg_base        = LPC_USB_BASE,
+    .max_num_ep          = USB_MAX_EP_NUM,
+    .mem_base            = membase,
+    .mem_size            = memsize,
+
+    .USB_Configure_Event = USB_Configure_Event,
+    .USB_Reset_Event     = USB_Reset_Event
+  };
+
+  USB_CORE_DESCS_T DeviceDes =
+  {
+    .device_desc      = (uint8_t*) &USB_DeviceDescriptor,
+    .string_desc      = (uint8_t*) &USB_StringDescriptor,
+    .full_speed_desc  = (uint8_t*) &USB_FsConfigDescriptor,
+    .high_speed_desc  = (uint8_t*) &USB_FsConfigDescriptor,
+    .device_qualifier = NULL
+  };
+
+  /* Start USB hardware initialisation */
+  ASSERT_USB_STATUS(USBD_API->hw->Init(&g_hUsb, &DeviceDes, &usb_param));
+
+  membase += (memsize - usb_param.mem_size);
+  memsize = usb_param.mem_size;
+
+  /* Initialise the class driver(s) */
+  #ifdef CFG_USB_CDC
+    ASSERT_USB_STATUS( usb_cdc_init(g_hUsb, &USB_FsConfigDescriptor.CDC_CCI_Interface,
+            &USB_FsConfigDescriptor.CDC_DCI_Interface, &membase, &memsize) );
+  #endif
+
+  #ifdef CFG_USB_HID_KEYBOARD
+    ASSERT_USB_STATUS( usb_hid_init(g_hUsb , &USB_FsConfigDescriptor.HID_KeyboardInterface ,
+            HID_KeyboardReportDescriptor, USB_FsConfigDescriptor.HID_KeyboardHID.DescriptorList[0].wDescriptorLength,
+            &membase , &memsize) );
+  #endif
+
+  #ifdef CFG_USB_HID_MOUSE
+    ASSERT_USB_STATUS( usb_hid_init(g_hUsb , &USB_FsConfigDescriptor.HID_MouseInterface    ,
+            HID_MouseReportDescriptor, USB_FsConfigDescriptor.HID_MouseHID.DescriptorList[0].wDescriptorLength,
+            &membase , &memsize) );
+  #endif
+
+  #ifdef CFG_USB_HID_GENERIC
+    ASSERT_USB_STATUS( usb_hid_init(g_hUsb , &USB_FsConfigDescriptor.HID_GenericInterface    ,
+            HID_GenericReportDescriptor, USB_FsConfigDescriptor.HID_GenericHID.DescriptorList[0].wDescriptorLength,
+            &membase , &memsize) );
+  #endif
+
+  #ifdef CFG_USB_MSC
+    // there is chance where SD card is not inserted, thus the msc init fails, should continue instead of return
+    if ( usb_msc_init(g_hUsb, &USB_FsConfigDescriptor.MSC_Interface, &membase, &memsize) != LPC_OK)
+    {
+      _PRINTF("MSC class fails to init\n");
+    }
+  #endif
+
+  #ifdef CFG_USB_CUSTOM_CLASS
+    ASSERT_USB_STATUS( usb_custom_init(g_hUsb, &USB_FsConfigDescriptor.Custom_Interface) );
+  #endif
+
+  /* Enable the USB interrupt */
+  #if defined CFG_MCU_FAMILY_LPC11UXX
+    NVIC_EnableIRQ(USB_IRQn);
+  #elif defined CFG_MCU_FAMILY_LPC13UXX
+    NVIC_EnableIRQ(USB_IRQ_IRQn);
+  #else
+    #error "No MCU defined"
+  #endif
+
+  /* Perform USB soft connect */
+  USBD_API->hw->Connect(g_hUsb, 1);
+
+  return LPC_OK;
+}
+
+/**************************************************************************/
+/*!
+    @brief Redirect the USB IRQ handler to the ROM handler
+*/
+/**************************************************************************/
+void USB_IRQHandler(void)
+{
+  USBD_API->hw->ISR(g_hUsb);
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/core/usb/usbd.h b/reform2-lpc-fw/src/core/usb/usbd.h
new file mode 100644
index 0000000000000000000000000000000000000000..43489015e34dda3682654cadf6b8f7100da8dd97
--- /dev/null
+++ b/reform2-lpc-fw/src/core/usb/usbd.h
@@ -0,0 +1,86 @@
+/**************************************************************************/
+/*!
+    @file     usbd.h
+    @author   Thach Ha (tinyusb.net)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __USBD_H__
+#define __USBD_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "romdriver/mw_usbd_rom_api.h"
+#include "../power_api.h"
+#include "descriptors.h"
+
+#ifdef CFG_USB_HID
+  #include "usb_hid.h"
+#endif
+
+#ifdef CFG_USB_CDC
+  #include "usb_cdc.h"
+#endif
+
+#ifdef CFG_USB_MSC
+  #include "usb_msc.h"
+#endif
+
+#ifdef CFG_USB_CUSTOM_CLASS
+  #include "usb_custom_class.h"
+#endif
+
+#define USBD_API     ((*(ROM **)(0x1FFF1FF8))->pUSBD)
+
+ErrorCode_t usb_init(void);
+bool usb_isConfigured(void);
+
+extern USBD_HANDLE_T g_hUsb;
+
+#define ASSERT_USB_STATUS_MESSAGE(sts, message) \
+        do{\
+          ErrorCode_t status = (sts);\
+          if (LPC_OK != status) {\
+            _PRINTF("Assert: '%s' at line %d: 0x%X %s%s", __func__, __LINE__, (uint32_t) status, message, CFG_PRINTF_NEWLINE);\
+            return status;\
+          }\
+        }while(0)
+
+#define ASSERT_USB_STATUS(sts)                ASSERT_USB_STATUS_MESSAGE(sts, NULL)
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/bitbanging/swspi/swspi.c b/reform2-lpc-fw/src/drivers/bitbanging/swspi/swspi.c
new file mode 100644
index 0000000000000000000000000000000000000000..b35bc679b02e2d6fd605679b8250fc3dca13ab60
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/bitbanging/swspi/swspi.c
@@ -0,0 +1,199 @@
+/**************************************************************************/
+/*! 
+    @file     swspi.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section DESCRIPTION
+
+    Basic bit-banged SPI driver.
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "swspi.h"
+#include "core/gpio/gpio.h"
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void swspiDelay(uint32_t ticks)
+{
+  uint32_t i;
+
+  for (i = 0; i < ticks/4; i++)
+  {
+    ASM("nop");
+  }
+}
+
+/**************************************************************************/
+/*!
+    @section EXAMPLE
+
+    @code
+
+    static swspi_config_t devicename_swspi_cfg;
+    ...
+    // Setup SW SPI settings and HW
+    devicename_swspi_cfg.miso_port  = 1;
+    devicename_swspi_cfg.miso_pin   = 26;
+    devicename_swspi_cfg.mosi_port  = 1;
+    devicename_swspi_cfg.mosi_pin   = 27;
+    devicename_swspi_cfg.sck_port   = 1;
+    devicename_swspi_cfg.sck_pin    = 28;
+    devicename_swspi_cfg.cpol       = 1;      // Clock is high between frames
+    devicename_swspi_cfg.cpha       = 1;      // Slave reads on rising clock edge, Master on falling edge
+    devicename_swspi_cfg.sck_delay  = 0;      // Delay between SCK state changes (high to low, etc.) in ticks
+
+    // Setup the SW SPI pin (assumes they are already set to GPIO)
+    swspiInit(&devicename_swspi_cfg);
+
+    uint8_t results = 0x00;
+
+    DEVICENAME_SPI_ENABLE;                                      // User-defined macro to Enable SPI
+    results = swspiTransferByte(&devicename_swspi_cfg, 0xFF);   // Transfer 0xFF and return read to 'results'
+    DEVICENAME_SPI_DISABLE;                                     // User-defined macro to Disable SPI
+
+    @endcode
+
+*/
+/**************************************************************************/
+void swspiInit(swspi_config_t *config)
+{
+  // Note: This function assumes that the IOCON registers have already
+  // been configured to set the pins to GPIO!
+  LPC_GPIO->DIR[config->miso_port] &= ~(1 << config->miso_pin);
+  LPC_GPIO->DIR[config->mosi_port] |=  (1 << config->mosi_pin);
+  LPC_GPIO->DIR[config->sck_port] |=  (1 << config->sck_pin);
+}
+
+/**************************************************************************/
+/*!
+    This function both reads and writes data. For write operations,
+    include the data to be written as an argument. For read operations,
+    use dummy data as an argument. The returned value is the data read
+    on the MISO pin.
+*/
+/**************************************************************************/
+uint8_t swspiTransferByte(swspi_config_t *config, uint8_t byte)
+{
+  int8_t i, b;
+  uint8_t output = 0x00;
+
+  // ToDo: This can be significantly optimised by only checking the
+  // mode once and writing optimised code for each of the four modes
+  // Current code yields <1MHz @ 72MHz!
+  for (i=8; i>0; i--)
+  {
+    // Drive SCK early for CPHA = 1
+    if (config->cpha)
+    {
+      // Drive SCK low if CPOL == 1, high if CPOL == 0
+      if (config->cpol)
+      {
+        LPC_GPIO->CLR[config->sck_port] = (1 << config->sck_pin);
+      }
+      else
+      {
+        LPC_GPIO->SET[config->sck_port] = (1 << config->sck_pin);
+      }
+      if (config->sck_delay)
+      {
+        swspiDelay(config->sck_delay);
+      }
+    }
+
+    // Write current bit
+    if (byte & (1 << (i-1)))
+    {
+      LPC_GPIO->SET[config->mosi_port] = (1 << config->mosi_pin);
+    }
+    else
+    {
+      LPC_GPIO->CLR[config->mosi_port] = (1 << config->mosi_pin);
+    }
+
+    // Mid SCK
+    if (config->cpha)
+    {
+      // Drive SCK high if CPOL == 1, low if CPOL == 0
+      if (config->cpol)
+      {
+        LPC_GPIO->SET[config->sck_port] = (1 << config->sck_pin);
+      }
+      else
+      {
+        LPC_GPIO->CLR[config->sck_port] = (1 << config->sck_pin);
+      }
+    }
+    else
+    {
+      // Drive SCK low if CPOL == 1, high if CPOL = 0
+      if (config->cpol)
+      {
+        LPC_GPIO->CLR[config->sck_port] = (1 << config->sck_pin);
+      }
+      else
+      {
+        LPC_GPIO->SET[config->sck_port] = (1 << config->sck_pin);
+      }
+    }
+    if (config->sck_delay)
+    {
+      swspiDelay(config->sck_delay);
+    }
+
+    // Read current bit and shift it into output at the appropriate location
+    b = GPIOGetPinValue(config->miso_port, config->miso_pin);
+    output |= ((b & 0x01) << (i-1));
+
+    // Drive SCK later for CPHA = 0
+    if (!(config->cpha))
+    {
+      // Drive SCK high if CPOL == 1, low if CPOL == 0
+      if (config->cpol)
+      {
+        LPC_GPIO->SET[config->sck_port] = (1 << config->sck_pin);
+      }
+      else
+      {
+        LPC_GPIO->CLR[config->sck_port] = (1 << config->sck_pin);
+      }
+      if (config->sck_delay)
+      {
+        swspiDelay(config->sck_delay);
+      }
+    }
+  }
+
+  return output;
+}
diff --git a/reform2-lpc-fw/src/drivers/bitbanging/swspi/swspi.h b/reform2-lpc-fw/src/drivers/bitbanging/swspi/swspi.h
new file mode 100644
index 0000000000000000000000000000000000000000..a5f2f3a4714be74bd7a9aafd396afef3da37e860
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/bitbanging/swspi/swspi.h
@@ -0,0 +1,65 @@
+/**************************************************************************/
+/*! 
+    @file     swspi.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _SWSPI_H_
+#define _SWSPI_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+typedef struct
+{
+  uint8_t  miso_port;
+  uint8_t  miso_pin;
+  uint8_t  mosi_port;
+  uint8_t  mosi_pin;
+  uint8_t  sck_port;
+  uint8_t  sck_pin;
+  uint8_t  cpol;            // Clock Polarity (1 = SCK high between frames, 0 = low)
+  uint8_t  cpha;            // Clock Phase (1 = slave reads on rising clock edge, master on falling edge, 0 = inverse)
+  uint32_t sck_delay;       // Delay in ticks between state changes on SCK
+} swspi_config_t;
+
+void    swspiInit(swspi_config_t *config);
+uint8_t swspiTransferByte(swspi_config_t *config, uint8_t byte);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/bitmap/ssd1306/ssd1306_i2c.c b/reform2-lpc-fw/src/drivers/displays/bitmap/ssd1306/ssd1306_i2c.c
new file mode 100644
index 0000000000000000000000000000000000000000..16dda3a8c81bf19a167e037a083cdbf9c61f1664
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/bitmap/ssd1306/ssd1306_i2c.c
@@ -0,0 +1,411 @@
+/**************************************************************************/
+/*!
+    @file     ssd1306_i2c.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section DESCRIPTION
+
+    I2C Driver for 128x64 OLED display based on the SSD1306 controller.
+
+    This driver is based on the SSD1306 Library from Limor Fried
+    (Adafruit Industries) at: https://github.com/adafruit/SSD1306
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+#include <string.h>
+#include "ssd1306_i2c.h"
+#include "core/i2c/i2c.h"
+#include "core/delay/delay.h"
+#include "drivers/displays/smallfonts.h"
+
+#define DELAY(mS)     do { delay(mS); } while(0);
+
+uint8_t _ssd1306buffer[SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8];
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+/**************************************************************************/
+/* Private Methods                                                        */
+/**************************************************************************/
+
+/**************************************************************************/
+/*!
+    @brief Sends a command via I2C
+
+    @param[in]  byte
+                The byte to send
+*/
+/**************************************************************************/
+err_t ssd1306SendCommand(uint8_t byte)
+{
+  uint8_t control = 0x00;   /* Co = 0, D/C = 0 */
+
+  /* Send the specified bytes */
+  I2CWriteLength = 3;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = SSD1306_I2C_ADDRESS;
+  I2CMasterBuffer[1] = control;
+  I2CMasterBuffer[2] = byte;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief Sends data via I2C
+
+    @param  data
+            The byte to send
+*/
+/**************************************************************************/
+err_t ssd1306SendData(uint8_t data)
+{
+  uint8_t control = 0x40;   /* Co = 0, D/C = 1 */
+
+  /* Send the specified bytes */
+  I2CWriteLength = 3;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = SSD1306_I2C_ADDRESS;
+  I2CMasterBuffer[1] = control;
+  I2CMasterBuffer[2] = data;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws a single graphic character using the supplied font
+*/
+/**************************************************************************/
+void ssd1306DrawChar(uint16_t x, uint16_t y, uint8_t c, struct FONT_DEF font)
+{
+  uint8_t col;
+  uint8_t column[font.u8Width];
+  uint16_t xoffset, yoffset;
+
+  /* Make sure we are not exceeding the display limits
+     This also gets checked in ssd1306DrawPixel, but if we start
+     outside the limits we can avoid some unecessary work at the outset */
+  if ((x > SSD1306_LCDWIDTH) || (y > SSD1306_LCDHEIGHT))
+    return;
+
+  /* Check if the requested character is available */
+  if ((c >= font.u8FirstChar) && (c <= font.u8LastChar))
+  {
+    /* Retrieve appropriate columns from font data */
+    for (col = 0; col < font.u8Width; col++)
+    {
+      column[col] = font.au8FontTable[((c - font.u8FirstChar) * font.u8Width) + col];    /* Get first column of appropriate character */
+    }
+  }
+  else
+  {
+    /* Requested character is not available in this font ... send a space instead */
+    for (col = 0; col < font.u8Width; col++)
+    {
+      column[col] = 0xFF;    /* Send solid space */
+    }
+  }
+
+  /* Render each column */
+  for (xoffset = 0; xoffset < font.u8Width; xoffset++)
+  {
+    for (yoffset = 0; yoffset < (font.u8Height + 1); yoffset++)
+    {
+      uint8_t bit = 0x00;
+      bit = (column[xoffset] << (8 - (yoffset + 1)));   /* Shift current row bit left */
+      bit = (bit >> 7);                                 /* Shift current row but right (results in 0x01 for black, and 0x00 for white) */
+      if (bit)
+      {
+        ssd1306DrawPixel(x + xoffset, y + yoffset);
+      }
+    }
+  }
+}
+
+/**************************************************************************/
+/* Public Methods                                                         */
+/**************************************************************************/
+
+/**************************************************************************/
+/*!
+    @brief Initialises the SSD1306 LCD display
+*/
+/**************************************************************************/
+err_t ssd1306Init(uint8_t vccstate)
+{
+  /* Make sure I2C is initialised */
+  i2cInit(I2CMASTER);
+
+  /* Ping the I2C device first to see if it exists! */
+  /* It seems we can't ping it */
+  // ASSERT(!(i2cCheckAddress(SSD1306_I2C_ADDRESS)), ERROR_I2C_DEVICENOTFOUND);
+
+  /* I2C Initialisation */
+  ssd1306SendCommand(SSD1306_DISPLAYOFF);
+  ssd1306SendCommand(SSD1306_SETDISPLAYCLOCKDIV);
+  ssd1306SendCommand(0x80);
+  ssd1306SendCommand(SSD1306_SETMULTIPLEX);
+  #if defined SSD1306_128_64
+    ssd1306SendCommand(0x3F);
+  #elif defined SSD1306_128_32
+    ssd1306SendCommand(0x1F);
+  #endif
+  ssd1306SendCommand(SSD1306_SETDISPLAYOFFSET);
+  ssd1306SendCommand(0x0);
+  ssd1306SendCommand(SSD1306_SETSTARTLINE | 0x0);
+  ssd1306SendCommand(SSD1306_CHARGEPUMP);
+  ssd1306SendCommand(vccstate == SSD1306_EXTERNALVCC ? 0x10 : 0x14);
+  ssd1306SendCommand(SSD1306_MEMORYMODE);
+  ssd1306SendCommand(0x00);
+  ssd1306SendCommand(SSD1306_SEGREMAP | 0x1);
+  ssd1306SendCommand(SSD1306_COMSCANDEC);
+  ssd1306SendCommand(SSD1306_SETCOMPINS);
+  #if defined SSD1306_128_64
+    ssd1306SendCommand(0x12);
+  #elif defined SSD1306_128_32
+    ssd1306SendCommand(0x02);
+  #endif
+  ssd1306SendCommand(SSD1306_SETCONTRAST);
+  ssd1306SendCommand(vccstate == SSD1306_EXTERNALVCC ? 0x9F : 0xCF);
+  ssd1306SendCommand(SSD1306_SETPRECHARGE);
+  ssd1306SendCommand(vccstate == SSD1306_EXTERNALVCC ? 0x22 : 0xF1);
+  ssd1306SendCommand(SSD1306_SETVCOMDETECT);
+  ssd1306SendCommand(0x40);
+  ssd1306SendCommand(SSD1306_DISPLAYALLON_RESUME);
+  ssd1306SendCommand(SSD1306_NORMALDISPLAY);
+
+  /* Enable the OLED panel */
+  ASSERT_STATUS(ssd1306SendCommand(SSD1306_DISPLAYON));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief Draws a single pixel in image buffer
+
+    @param[in]  x
+                The x position (0..127)
+    @param[in]  y
+                The y position (0..63)
+*/
+/**************************************************************************/
+void ssd1306DrawPixel(uint8_t x, uint8_t y)
+{
+  if ((x >= SSD1306_LCDWIDTH) || (y >= SSD1306_LCDHEIGHT))
+    return;
+
+  _ssd1306buffer[x+ (y/8)*SSD1306_LCDWIDTH] |= (1 << y%8);
+}
+
+/**************************************************************************/
+/*!
+    @brief Clears a single pixel in image buffer
+
+    @param[in]  x
+                The x position (0..127)
+    @param[in]  y
+                The y position (0..63)
+*/
+/**************************************************************************/
+void ssd1306ClearPixel(uint8_t x, uint8_t y)
+{
+  if ((x >= SSD1306_LCDWIDTH) || (y >= SSD1306_LCDHEIGHT))
+    return;
+
+  _ssd1306buffer[x+ (y/8)*SSD1306_LCDWIDTH] &= ~(1 << y%8);
+}
+
+/**************************************************************************/
+/*!
+    @brief Gets the value (1 or 0) of the specified pixel from the buffer
+
+    @param[in]  x
+                The x position (0..127)
+    @param[in]  y
+                The y position (0..63)
+
+    @return     1 if the pixel is enabled, 0 if disabled
+*/
+/**************************************************************************/
+uint8_t ssd1306GetPixel(uint8_t x, uint8_t y)
+{
+  if ((x >= SSD1306_LCDWIDTH) || (y >=SSD1306_LCDHEIGHT)) return 0;
+  return _ssd1306buffer[x+ (y/8)*SSD1306_LCDWIDTH] & (1 << y%8) ? 1 : 0;
+}
+
+/**************************************************************************/
+/*!
+    @brief Clears the screen
+*/
+/**************************************************************************/
+void ssd1306ClearScreen()
+{
+  memset(_ssd1306buffer, 0x00, sizeof(_ssd1306buffer));
+}
+
+/**************************************************************************/
+/*!
+    @brief Renders the contents of the pixel buffer on the LCD
+*/
+/**************************************************************************/
+void ssd1306Refresh(void)
+{
+  uint16_t i;
+
+  ssd1306SendCommand(SSD1306_SETLOWCOLUMN | 0x0);  // low col = 0
+  ssd1306SendCommand(SSD1306_SETHIGHCOLUMN | 0x0);  // hi col = 0
+  ssd1306SendCommand(SSD1306_SETSTARTLINE | 0x0); // line #0
+
+  for (i=0; i < sizeof(_ssd1306buffer); i++)
+  {
+    ssd1306SendData(_ssd1306buffer[i]);
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws a string using the supplied font data.
+
+    @param[in]  x
+                Starting x co-ordinate
+    @param[in]  y
+                Starting y co-ordinate
+    @param[in]  text
+                The string to render
+    @param[in]  font
+                Pointer to the FONT_DEF to use when drawing the string
+
+    @section Example
+
+    @code
+
+    #include "drivers/displays/bitmap/ssd1306/ssd1306_i2c.h"
+    #include "drivers/displays/smallfonts.h"
+
+    // Configure the pins and initialise the LCD screen
+    ssd1306Init(SSD1306_INTERNALVCC);
+
+    // Render some text on the screen
+    ssd1306DrawString(1, 10, "5x8 System", Font_System5x8);
+    ssd1306DrawString(1, 20, "7x8 System", Font_System7x8);
+
+    // Refresh the screen to see the results
+    ssd1306Refresh();
+
+    @endcode
+*/
+/**************************************************************************/
+void ssd1306DrawString(uint16_t x, uint16_t y, char* text, struct FONT_DEF font)
+{
+  volatile uint8_t l;
+  for (l = 0; l < strlen(text); l++)
+  {
+    ssd1306DrawChar(x + (l * (font.u8Width + 1)), y, text[l], font);
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Shifts the contents of the frame buffer up the specified
+            number of pixels
+
+    @param[in]  height
+                The number of pixels to shift the frame buffer up, leaving
+                a blank space at the bottom of the frame buffer x pixels
+                high
+
+    @section Example
+
+    @code
+
+    #include "drivers/displays/bitmap/ssd1306/ssd1306_i2c.h"
+    #include "drivers/displays/smallfonts.h"
+
+    // Configure the pins and initialise the LCD screen
+    ssd1306Init(SSD1306_INTERNALVCC);
+
+    // Continually write some text, scrolling upward one line each time
+    while (1)
+    {
+      // Shift the buffer up 8 pixels (adjust for font-height)
+      ssd1306ShiftFrameBuffer(8);
+      // Render some text on the screen with different fonts
+      ssd1306DrawString(1, 56, "INSERT TEXT HERE", Font_System5x8);
+      // Refresh the screen to see the results
+      ssd1306Refresh();
+      // Wait a bit before writing the next line
+      delay(1000);
+    }
+
+    @endcode
+*/
+/**************************************************************************/
+void ssd1306ShiftFrameBuffer( uint8_t height )
+{
+  uint8_t y, x;
+
+  if (height == 0) return;
+  if (height >= SSD1306_LCDHEIGHT)
+  {
+    /* Clear the entire frame buffer */
+    ssd1306ClearScreen();
+    return;
+  }
+
+  /* This is horribly inefficient, but at least easy to understand
+     In a production environment, this should be significantly optimised */
+
+  for (y = 0; y < SSD1306_LCDHEIGHT; y++)
+  {
+    for (x = 0; x < SSD1306_LCDWIDTH; x++)
+    {
+      if ((SSD1306_LCDHEIGHT - 1) - y > height)
+      {
+        /* Shift height from further ahead in the buffer */
+        ssd1306GetPixel(x, y + height) ? ssd1306DrawPixel(x, y) : ssd1306ClearPixel(x, y);
+      }
+      else
+      {
+        /* Clear the entire line */
+        ssd1306ClearPixel(x, y);
+      }
+    }
+  }
+}
diff --git a/reform2-lpc-fw/src/drivers/displays/bitmap/ssd1306/ssd1306_i2c.h b/reform2-lpc-fw/src/drivers/displays/bitmap/ssd1306/ssd1306_i2c.h
new file mode 100644
index 0000000000000000000000000000000000000000..1722ff52996e0d4425585b21bb7f99cffd1b5831
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/bitmap/ssd1306/ssd1306_i2c.h
@@ -0,0 +1,133 @@
+/**************************************************************************/
+/*!
+    @file     ssd1306_i2c.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012 K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __SSD1306_I2C_H__
+#define __SSD1306_I2C_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+#include "drivers/displays/smallfonts.h"
+
+/*=========================================================================
+    Display Size
+    -----------------------------------------------------------------------
+    The driver is used in multiple displays (128x64, 128x32, etc.).
+    Select the appropriate display below to create an appropriately
+    sized framebuffer, etc.
+
+    SSD1306_128_64  128x64 pixel display
+
+    SSD1306_128_32  128x32 pixel display
+
+    You also need to set the LCDWIDTH and LCDHEIGHT defines to an
+    appropriate size
+
+    -----------------------------------------------------------------------*/
+    #define SSD1306_128_64
+    // #define SSD1306_128_32
+
+    #if defined SSD1306_128_64 && defined SSD1306_128_32
+      #error "Only one SSD1306 display can be specified at once in ssd1306.h"
+    #endif
+    #if !defined SSD1306_128_64 && !defined SSD1306_128_32
+      #error "At least one SSD1306 display must be specified in ssd1306.h"
+    #endif
+
+    #if defined SSD1306_128_64
+      #define SSD1306_LCDWIDTH            (128)
+      #define SSD1306_LCDHEIGHT           (64)
+    #endif
+    #if defined SSD1306_128_32
+      #define SSD1306_LCDWIDTH            (128)
+      #define SSD1306_LCDHEIGHT           (32)
+    #endif
+/*=========================================================================*/
+
+
+/*=========================================================================
+    I2C Address - 011110+SA0 ... 0x3C for SA0 = 0, 0x3D for SA0 = 1
+    ---------------------------------------------------------------------*/
+    #define SSD1306_I2C_ADDRESS           (0x3D << 1)
+    #define SSD1306_I2C_READWRITE         (0x01)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    Commands
+    ---------------------------------------------------------------------*/
+    #define SSD1306_SETCONTRAST           0x81
+    #define SSD1306_DISPLAYALLON_RESUME   0xA4
+    #define SSD1306_DISPLAYALLON          0xA5
+    #define SSD1306_NORMALDISPLAY         0xA6
+    #define SSD1306_INVERTDISPLAY         0xA7
+    #define SSD1306_DISPLAYOFF            0xAE
+    #define SSD1306_DISPLAYON             0xAF
+    #define SSD1306_SETDISPLAYOFFSET      0xD3
+    #define SSD1306_SETCOMPINS            0xDA
+    #define SSD1306_SETVCOMDETECT         0xDB
+    #define SSD1306_SETDISPLAYCLOCKDIV    0xD5
+    #define SSD1306_SETPRECHARGE          0xD9
+    #define SSD1306_SETMULTIPLEX          0xA8
+    #define SSD1306_SETLOWCOLUMN          0x00
+    #define SSD1306_SETHIGHCOLUMN         0x10
+    #define SSD1306_SETSTARTLINE          0x40
+    #define SSD1306_MEMORYMODE            0x20
+    #define SSD1306_COMSCANINC            0xC0
+    #define SSD1306_COMSCANDEC            0xC8
+    #define SSD1306_SEGREMAP              0xA0
+    #define SSD1306_CHARGEPUMP            0x8D
+    #define SSD1306_EXTERNALVCC           0x01
+    #define SSD1306_INTERNALVCC           0x02
+    #define SSD1306_SWITCHCAPVCC          0x02
+/*=========================================================================*/
+
+err_t ssd1306Init ( uint8_t vccstate );
+void    ssd1306DrawPixel ( uint8_t x, uint8_t y );
+void    ssd1306ClearPixel ( uint8_t x, uint8_t y );
+uint8_t ssd1306GetPixel ( uint8_t x, uint8_t y );
+void    ssd1306ClearScreen ( void );
+void    ssd1306Refresh ( void );
+void    ssd1306DrawString( uint16_t x, uint16_t y, char* text, struct FONT_DEF font );
+void    ssd1306ShiftFrameBuffer( uint8_t height );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/Readme.md b/reform2-lpc-fw/src/drivers/displays/graphic/Readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..dca9822eff7c36ea094af6d7f1914c7141ae6903
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/Readme.md
@@ -0,0 +1,29 @@
+# TFT/OLED Graphics Sub-System
+
+The LPC11U37/LPC1347 Code Base includes a reasonably complete graphic
+sub-system that can be used with a variety of RGB565 TFT or OLED
+displays. 
+
+It includes all the basic drawing primitives you'd expect, as well
+as color conversion and alpha-blending, support for bitmap and
+anti-aliased fonts, loading and saving of bitmap images (from/to an
+SD card or elsewhere), and a few basic controls to help you get
+started developing your own custom look and feel in your application.
+
+The core drawing routines (/drivers/displays/graphic/drawing.c) are
+seperated from the actual HW (/drivers/displays/graphic/hw/*) so that
+the underlying display can be easily changed without having to
+significantly modify your project code.  
+
+A number of drivers are provided for common displays and controllers,
+and it's relatively straight-forward to extend the library to support
+new ones: you simply need to implement the set of functions defined 
+in lcd.h, and the graphics sub-system will call these functions
+directly when rendering any text, graphics, etc..
+
+## Documentation
+
+Complete documentation for the graphics sub-system is available
+online at microbuilder.eu:
+
+http://www.microbuilder.eu/Projects/LPC1343ReferenceDesign/TFTLCDAPI_v1_1_0.aspx
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts.c b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts.c
new file mode 100644
index 0000000000000000000000000000000000000000..67d1f6df6e2b2e4ef9248988f8545f8437a0eff8
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts.c
@@ -0,0 +1,382 @@
+/**************************************************************************/
+/*!  
+    @file     aafonts.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "aafonts.h"
+
+#include "drivers/displays/graphic/lcd.h"
+#include "drivers/displays/graphic/drawing.h"
+
+// Common color lookup tables for AA2 (4-color anti-aliased) fonts
+const uint16_t COLORTABLE_AA2_WHITEONBLACK[4] = { 0x0000, 0x52AA, 0xAD55, 0xFFFF};
+const uint16_t COLORTABLE_AA2_BLACKONWHITE[4] = { 0xFFFF, 0xAD55, 0x52AA, 0x0000};
+
+// Common color lookup tables for AA4 (16-color anti-aliased) fonts
+const uint16_t COLORTABLE_AA4_WHITEONBLACK[16] = { 0x0000, 0x1082, 0x2104, 0x3186, 0x4208, 0x528A, 0x630C, 0x738E, 0x8410, 0x9492, 0xA514, 0xB596, 0xC618, 0xD69A, 0xE71C, 0xFFFF};
+const uint16_t COLORTABLE_AA4_BLACKONWHITE[16] = { 0xFFFF, 0xE71C, 0xD69A, 0xC618, 0xB596, 0xA514, 0x9492, 0x8410, 0x738E, 0x630C, 0x528A, 0x4208, 0x3186, 0x2104, 0x1082, 0x0000};
+
+/**************************************************************************/
+/*                                                                        */
+/* ----------------------- Private Methods ------------------------------ */
+/*                                                                        */
+/**************************************************************************/
+
+/**************************************************************************/
+/*!
+    @brief Renders a single AA2 character on the screen
+
+    This text rendering method used a lookup table of pre-calculated
+    colors, and doesn't require any reads from the LCD (not all displays
+    support reading pixels back).  This offers the best performance and
+    high-quality text, but can only be used on solid backgrounds where
+    the bgcolor is known.
+
+    @param[in]  x
+                Top-left x position
+    @param[in]  y
+                Top-left y position
+    @param[in]  height
+                Font height in pixels
+    @param[in]  character
+                Pointer to the aafontsCharInfo_t array with the char data
+    @param[in]  colorTable
+                Pointer to the 4 element color lookup table
+*/
+/**************************************************************************/
+void aafontsDrawCharAA2( uint16_t x, uint16_t y, uint16_t height, aafontsCharInfo_t character, const uint16_t * colorTable)
+{
+  uint16_t w, h, pos;
+  uint8_t color;
+
+  for (h = 0; h < height; h++)
+  {
+    pos = 0;
+    for (w = 0; w < character.width; w++)
+    {
+      color = character.charData[h*character.bytesPerRow + w/4];
+      switch (pos)
+      {
+        case 0:
+          color = (color >> 6) & 0x03;
+          break;
+        case 1:
+          color = (color >> 4) & 0x03;
+          break;
+        case 2:
+          color = (color >> 2) & 0x03;
+          break;
+        case 3:
+          color = color & 0x03;
+          break;
+      }
+      if (color) lcdDrawPixel(x+w, y+h, colorTable[color & 0xF]);
+      pos++;
+      if (pos == 4) pos = 0;
+    }
+  }
+} 
+
+/**************************************************************************/
+/*!
+    @brief Renders a single AA4 character on the screen
+
+    This text rendering method used a lookup table of pre-calculated
+    colors, and doesn't require any reads from the LCD (not all displays
+    support reading pixels back).  This offers the best performance and
+    high-quality text, but can only be used on solid backgrounds where
+    the bgcolor is known.
+
+    @param[in]  x
+                Top-left x position
+    @param[in]  y
+                Top-left y position
+    @param[in]  height
+                Font height in pixels
+    @param[in]  character
+                Pointer to the aafontsCharInfo_t array with the char data
+    @param[in]  colorTable
+                Pointer to the 16 element color lookup table
+*/
+/**************************************************************************/
+void aafontsDrawCharAA4( uint16_t x, uint16_t y, uint16_t height, aafontsCharInfo_t character, const uint16_t * colorTable)
+{
+  uint16_t w, h;
+  uint8_t color;
+
+  for (h = 0; h < height; h++)
+  {
+    for (w = 0; w < character.width; w++)
+    {
+      color = character.charData[h*character.bytesPerRow + w/2];
+      if (!(w % 2)) color = (color >> 4);
+      if (color) lcdDrawPixel(x+w, y+h, colorTable[color & 0xF]);
+    }
+  }
+}
+
+/**************************************************************************/
+/*                                                                        */
+/* ----------------------- Public Methods ------------------------------- */
+/*                                                                        */
+/**************************************************************************/
+
+/**************************************************************************/
+/*!
+    @brief  Draws a string using the supplied anti-aliased font
+
+    @param[in]  x
+                Starting x co-ordinate
+    @param[in]  y
+                Starting y co-ordinate
+    @param[in]  colorTable
+                The color lookup table to use for the antialiased pixels
+    @param[in]  font
+                Pointer to the aafontsFont_t to use when drawing the string
+    @param[in]  str
+                The string to render
+
+    @section Example
+
+    @code 
+
+    #include "drivers/displays/graphic/aafonts.h"
+    #include "drivers/displays/graphic/aafonts/aa2/DejaVuSansCondensed14_AA2.h"
+    #include "drivers/displays/graphic/aafonts/aa2/DejaVuSansCondensedBold14_AA2.h"
+
+    // Fill screen with white (so that we can use the pre-defined color tables in aafonts.h)
+    lcdFillRGB(COLOR_WHITE);
+
+    aafontsDrawString(10, 100, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensed14_AA2, "1234567890");
+    aafontsDrawString(10, 120, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensed14_AA2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+    aafontsDrawString(10, 140, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensed14_AA2, "abcdefghijklmnopqrstuvwxyz");
+    aafontsDrawString(10, 160, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensed14_AA2, "!\"#$%&'()*+,-./  :;<=>?");
+    aafontsDrawString(10, 180, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensed14_AA2, "@  [\\]^_  {|}~");
+
+    aafontsDrawString(10, 215, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensedBold14_AA2, "1234567890");
+    aafontsDrawString(10, 235, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensedBold14_AA2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+    aafontsDrawString(10, 255, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensedBold14_AA2, "abcdefghijklmnopqrstuvwxyz");
+    aafontsDrawString(10, 275, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensedBold14_AA2, "!\"#$%&'()*+,-./  :;<=>?");
+    aafontsDrawString(10, 295, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensedBold14_AA2, "@  [\\]^_  {|}~");
+
+    @endcode
+*/
+/**************************************************************************/
+void aafontsDrawString(uint16_t x, uint16_t y, const uint16_t * colorTable, const aafontsFont_t *font, char *str)
+{
+  uint16_t currentX, charWidth, characterToOutput;
+  const aafontsCharInfo_t *charInfo;
+
+  // set current x, y to that of requested
+  currentX = x;
+
+  // while not NULL
+  while (*str != '\0')
+  {
+    // get character to output
+    characterToOutput = *str;
+
+    // Check if the character is within the font boundaries
+    if ((characterToOutput > font->lastChar) || (characterToOutput < font->firstChar))
+    {
+      // Character is out of bounds
+      // Insert space instead
+      charWidth = font->unknownCharWidth;
+    }
+    else
+    {
+      // get char info
+      charInfo = &(font->charTable[characterToOutput - font->firstChar]);    
+      // get width from char info
+      charWidth = charInfo->width;
+      // Send individual characters
+      switch (font->fontType)
+      {
+        case AAFONTS_FONTTYPE_AA2:
+          aafontsDrawCharAA2(currentX, y, font->fontHeight, *charInfo, &colorTable[0]);
+          break;
+        case AAFONTS_FONTTYPE_AA4:
+          aafontsDrawCharAA4(currentX, y, font->fontHeight, *charInfo, &colorTable[0]);
+          break;
+      }
+    }
+    
+    // Adjust x for the next character
+    currentX += charWidth;
+    
+    // next char in string
+    str++;
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws a string using the supplied anti-aliased font, centering
+            it on the specified X/Y co-ordinate
+
+    @param[in]  x
+                Center x co-ordinate
+    @param[in]  y
+                Center y co-ordinate
+    @param[in]  colorTable
+                The color lookup table to use for the antialiased pixels
+    @param[in]  font
+                Pointer to the aafontsFont_t to use when drawing the string
+    @param[in]  str
+                The string to render
+*/
+/**************************************************************************/
+void aafontsCenterString(uint16_t x, uint16_t y, const uint16_t * colorTable, const aafontsFont_t *font, char *str)
+{
+  uint32_t stringWidth;
+  stringWidth = aafontsGetStringWidth(font, str);
+  aafontsDrawString(x - stringWidth/2, y, colorTable, font, str);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Returns the width in pixels of a string when it is rendered
+
+    This method can be used to determine whether a string will fit
+    inside a specific area, or if it needs to be broken up into multiple
+    lines to be properly rendered on the screen.
+
+    @param[in]  font
+                Pointer to aafontsFont_t of the font that will be used
+    @param[in]  str
+                The string that will be rendered
+
+    @section Example
+
+    @code 
+
+    #include "drivers/displays/graphic/aafonts.h"
+    #include "drivers/displays/graphic/aafonts/aa2/DejaVuSansCondensed14_AA2.h"
+
+    uint32_t w = aafontsGetStringWidth(&DejaVuSansCondensed14_AA2, "This is a simple test 123!!! (AA2)");
+
+    @endcode
+*/
+/**************************************************************************/
+uint16_t aafontsGetStringWidth(const aafontsFont_t *font, char *str)
+{
+  uint16_t width = 0;
+  const aafontsCharInfo_t *charInfo;
+  uint32_t currChar;
+
+  // until termination
+  for (currChar = *str; currChar; currChar = *(++str))
+  {
+    // Check if the character is within the font boundaries
+    if ((currChar > font->lastChar) || (currChar < font->firstChar))
+    {
+      // Character is out of bounds
+      width += font->unknownCharWidth;
+    }
+    else
+    {
+      // get char info
+      charInfo = &(font->charTable[currChar - font->firstChar]);
+      // get width from char info
+      width += charInfo->width;
+    }
+  }
+
+  /* return the string width */
+  return width;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Calculates a 4 or 16 color lookup table between the specified
+	        bg and fore colors for use with anti-aliased fonts.
+
+    @note   This method can be used to place anti-aliased text on any color
+	        of background, as long as it's a single solid color.
+
+    @param[in]  bgColor
+                The RGB565 color of the background
+    @param[in]  foreColor
+                The RGB565 fore color for the anti-aliased text
+    @param[in]  colorTable
+                Pointer to the 4 or 16 element array that will be 
+                populated with the individual color values
+    @param[in]  tableSize
+                The number of elements in the colorTable array (acceptable
+                values are 4 for AA2 or 16 for AA4).
+
+    @section Example
+
+    @code 
+
+    #include "drivers/displays/graphic/colors.h"
+    #include "drivers/displays/graphic/drawing.h"
+    #include "drivers/displays/graphic/aafonts.h"
+    #include "drivers/displays/graphic/aafonts/aa2/DejaVuSansCondensed14_AA2.h"
+    #include "drivers/displays/graphic/aafonts/aa2/DejaVuSansCondensedBold14_AA2.h"
+
+    uint16_t bgColor = COLOR_RED;
+    uint16_t foreColor = COLOR_YELLOW;
+    uint16_t ctable[4];
+
+    // Calculate a 4 color lookup table using the fore and bg colors
+    aafontsCalculateColorTable(bgColor, foreColor, &ctable[0], 4);
+
+    // Render a solid rectangle for the background
+    drawRectangleFilled(10, 10, 200, 50, bgColor);
+
+    // Draw some AA2 anti-aliased text using the generated color table
+    aafontsDrawString(10, 13, ctable, &DejaVuSansCondensed14_AA2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+    aafontsDrawString(10, 33, ctable, &DejaVuSansCondensedBold14_AA2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+
+    @endcode
+*/
+/**************************************************************************/
+void aafontsCalculateColorTable(uint16_t bgColor, uint16_t foreColor, uint16_t *colorTable, size_t tableSize)
+{
+  uint16_t i, stepsize;
+
+  if ((tableSize != 4) && (tableSize != 16))
+    return;
+
+  colorTable[0] = bgColor;
+  colorTable[tableSize - 1] = foreColor;
+
+  stepsize = 100/(tableSize-1);
+
+  for (i = 1; i < tableSize - 1; i++)
+  {
+    // Gradually decrease the amount of alpha-blending from high to low
+    colorTable[i] = colorsAlphaBlend(bgColor, foreColor, 100-i*stepsize);
+  }
+}
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts.h b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts.h
new file mode 100644
index 0000000000000000000000000000000000000000..ba7b2c9dd39ec9d9849f20d229d08417e4137bf6
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts.h
@@ -0,0 +1,85 @@
+/**************************************************************************/
+/*! 
+    @file     aafonts.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __AAFONTS_H__
+#define __AAFONTS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+typedef enum
+{
+  AAFONTS_FONTTYPE_AA2 = 2,             /* AA2 Fonts (4 shades of gray) */
+  AAFONTS_FONTTYPE_AA4 = 4              /* AA4 Fonts (16 shades of gray) */
+} aafontsFontType_t;
+
+typedef struct 
+{
+  uint8_t width;                        /* Character width in pixels */
+  uint8_t bytesPerRow;                  /* Data width in bytes */
+  const uint8_t *charData;              /* Pointer to the character data array */
+} aafontsCharInfo_t;
+
+typedef struct aafontsFont_s
+{
+  aafontsFontType_t fontType;           /* Anti-aliasing level for the font */
+  uint16_t fontHeight;                  /* Font height in pixels */
+  uint16_t unknownCharWidth;            /* Width for unknown characters */
+  uint16_t heightUpperCase;             /* Height in pixels of upper case characters */
+  uint16_t heightLowerCase;             /* Height in pixels of lower case characters */
+  uint16_t baseline;                    /* Font baseline */
+  uint16_t firstChar;                   /* Unicode address of the first character in the char map */
+  uint16_t lastChar;                    /* Unicode address of the last character in the char map */
+  const aafontsCharInfo_t *charTable;   /* Pointer to the aafontsCharInfo_t array containing the char data */
+} aafontsFont_t;
+
+extern const uint16_t COLORTABLE_AA2_WHITEONBLACK[4];
+extern const uint16_t COLORTABLE_AA2_BLACKONWHITE[4];
+extern const uint16_t COLORTABLE_AA4_WHITEONBLACK[16];
+extern const uint16_t COLORTABLE_AA4_BLACKONWHITE[16];
+
+void      aafontsDrawString ( uint16_t x, uint16_t y, const uint16_t * colorTable, const aafontsFont_t *font, char *str );
+void      aafontsCenterString ( uint16_t x, uint16_t y, const uint16_t * colorTable, const aafontsFont_t *font, char *str );
+uint16_t  aafontsGetStringWidth ( const aafontsFont_t *font, char *str );
+void      aafontsCalculateColorTable ( uint16_t bgColor, uint16_t foreColor, uint16_t *colorTable, size_t tableSize );
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansCondensed14_AA2.c b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansCondensed14_AA2.c
new file mode 100644
index 0000000000000000000000000000000000000000..e5e17e9ea0cd0c49c2fac8903468801961ffd65f
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansCondensed14_AA2.c
@@ -0,0 +1,1764 @@
+/**************************************************************************/
+/*! 
+    @file     DejaVuSansCondensed14_AA2.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "DejaVuSansCondensed14_AA2.h"
+
+/* Start of unicode area <Basic Latin> */
+const uint8_t FontDejaVuSansCondensed14_AA2_0020[ 14] = { /* code 0020, SPACE */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0021[ 14] = { /* code 0021, EXCLAMATION MARK */
+  0x00,
+  0x00,
+  0x18,
+  0x18,
+  0x18,
+  0x18,
+  0x18,
+  0x18,
+  0x00,
+  0x00,
+  0x18,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0022[ 28] = { /* code 0022, QUOTATION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x22, 0x00,
+  0x22, 0x00,
+  0x22, 0x00,
+  0x22, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0023[ 42] = { /* code 0023, NUMBER SIGN */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x88, 0x00,
+  0x01, 0x48, 0x00,
+  0x02, 0x48, 0x00,
+  0x1F, 0xFF, 0x00,
+  0x02, 0x20, 0x00,
+  0x06, 0x20, 0x00,
+  0x3F, 0xFE, 0x00,
+  0x08, 0x50, 0x00,
+  0x08, 0x50, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0024[ 28] = { /* code 0024, DOLLAR SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x01, 0x00,
+  0x0F, 0xC0,
+  0x31, 0x00,
+  0x21, 0x00,
+  0x2E, 0x00,
+  0x02, 0xD0,
+  0x01, 0x20,
+  0x01, 0x20,
+  0x3F, 0xC0,
+  0x01, 0x00,
+  0x01, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0025[ 42] = { /* code 0025, PERCENT SIGN */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x2D, 0x02, 0x00,
+  0x62, 0x09, 0x00,
+  0x52, 0x08, 0x00,
+  0x62, 0x20, 0x00,
+  0x2D, 0x22, 0x40,
+  0x00, 0x89, 0x50,
+  0x01, 0x48, 0x20,
+  0x02, 0x08, 0x20,
+  0x09, 0x07, 0xC0,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0026[ 28] = { /* code 0026, AMPERSAND */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xD0,
+  0x18, 0x00,
+  0x18, 0x00,
+  0x0D, 0x00,
+  0x2B, 0x06,
+  0x21, 0xC5,
+  0x60, 0x78,
+  0x30, 0x28,
+  0x1F, 0xDB,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0027[ 14] = { /* code 0027, APOSTROPHE */
+  0x00,
+  0x00,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0028[ 14] = { /* code 0028, LEFT PARENTHESIS */
+  0x00,
+  0x00,
+  0x08,
+  0x18,
+  0x24,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x14,
+  0x08,
+  0x05,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0029[ 14] = { /* code 0029, RIGHT PARENTHESIS */
+  0x00,
+  0x00,
+  0x20,
+  0x14,
+  0x08,
+  0x08,
+  0x08,
+  0x08,
+  0x08,
+  0x08,
+  0x18,
+  0x24,
+  0x20,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_002A[ 28] = { /* code 002A, ASTERISK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x04, 0x00,
+  0x44, 0x80,
+  0x2F, 0x00,
+  0x2F, 0x40,
+  0x44, 0x40,
+  0x04, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_002B[ 42] = { /* code 002B, PLUS SIGN */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x80, 0x00,
+  0x00, 0x80, 0x00,
+  0x00, 0x80, 0x00,
+  0x00, 0x80, 0x00,
+  0x2F, 0xFE, 0x00,
+  0x00, 0x80, 0x00,
+  0x00, 0x80, 0x00,
+  0x00, 0x80, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_002C[ 14] = { /* code 002C, COMMA */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x24,
+  0x20,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_002D[ 14] = { /* code 002D, HYPHEN-MINUS */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x7D,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_002E[ 14] = { /* code 002E, FULL STOP */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x24,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_002F[ 14] = { /* code 002F, SOLIDUS */
+  0x00,
+  0x00,
+  0x05,
+  0x09,
+  0x08,
+  0x08,
+  0x14,
+  0x20,
+  0x20,
+  0x60,
+  0x50,
+  0x80,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0030[ 28] = { /* code 0030, DIGIT ZERO */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0x80,
+  0x24, 0x60,
+  0x20, 0x30,
+  0x20, 0x30,
+  0x60, 0x20,
+  0x60, 0x30,
+  0x30, 0x20,
+  0x24, 0x60,
+  0x0F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0031[ 28] = { /* code 0031, DIGIT ONE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0x00,
+  0x27, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x2F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0032[ 28] = { /* code 0032, DIGIT TWO */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0x80,
+  0x10, 0x90,
+  0x00, 0x60,
+  0x00, 0x60,
+  0x00, 0xC0,
+  0x03, 0x40,
+  0x09, 0x00,
+  0x24, 0x00,
+  0x3F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0033[ 28] = { /* code 0033, DIGIT THREE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0x80,
+  0x00, 0xA0,
+  0x00, 0x20,
+  0x00, 0x90,
+  0x0B, 0xC0,
+  0x00, 0x60,
+  0x00, 0x20,
+  0x00, 0x60,
+  0x3F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0034[ 28] = { /* code 0034, DIGIT FOUR */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x01, 0xC0,
+  0x03, 0xC0,
+  0x05, 0xC0,
+  0x08, 0xC0,
+  0x20, 0xC0,
+  0x60, 0xC0,
+  0x7F, 0xF4,
+  0x00, 0xC0,
+  0x00, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0035[ 28] = { /* code 0035, DIGIT FIVE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0xD0,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x2F, 0x40,
+  0x00, 0xD0,
+  0x00, 0x20,
+  0x00, 0x30,
+  0x00, 0x60,
+  0x3F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0036[ 28] = { /* code 0036, DIGIT SIX */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xE0,
+  0x18, 0x00,
+  0x30, 0x00,
+  0x27, 0x80,
+  0x38, 0x60,
+  0x30, 0x30,
+  0x30, 0x20,
+  0x24, 0x30,
+  0x0F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0037[ 28] = { /* code 0037, DIGIT SEVEN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xF0,
+  0x00, 0x60,
+  0x00, 0x90,
+  0x00, 0xC0,
+  0x01, 0x80,
+  0x02, 0x40,
+  0x03, 0x00,
+  0x06, 0x00,
+  0x09, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0038[ 28] = { /* code 0038, DIGIT EIGHT */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xC0,
+  0x34, 0x60,
+  0x20, 0x30,
+  0x24, 0x60,
+  0x0F, 0xC0,
+  0x20, 0x30,
+  0x60, 0x30,
+  0x30, 0x30,
+  0x1F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0039[ 28] = { /* code 0039, DIGIT NINE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0x80,
+  0x30, 0x90,
+  0x60, 0x20,
+  0x60, 0x30,
+  0x30, 0x70,
+  0x1F, 0xA0,
+  0x00, 0x20,
+  0x00, 0x90,
+  0x2F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_003A[ 14] = { /* code 003A, COLON */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x24,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x24,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_003B[ 14] = { /* code 003B, SEMICOLON */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x24,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x24,
+  0x20,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_003C[ 42] = { /* code 003C, LESS-THAN SIGN */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x06, 0x00,
+  0x00, 0xB8, 0x00,
+  0x0F, 0x40, 0x00,
+  0x2C, 0x00, 0x00,
+  0x03, 0xE0, 0x00,
+  0x00, 0x1E, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_003D[ 42] = { /* code 003D, EQUALS SIGN */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x2F, 0xFE, 0x00,
+  0x00, 0x00, 0x00,
+  0x2F, 0xFE, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_003E[ 42] = { /* code 003E, GREATER-THAN SIGN */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x24, 0x00, 0x00,
+  0x0B, 0x80, 0x00,
+  0x00, 0x7D, 0x00,
+  0x00, 0x0E, 0x00,
+  0x02, 0xF0, 0x00,
+  0x2D, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_003F[ 28] = { /* code 003F, QUESTION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0x00,
+  0x01, 0x80,
+  0x00, 0xC0,
+  0x02, 0x40,
+  0x0A, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x00, 0x00,
+  0x0C, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0040[ 42] = { /* code 0040, COMMERCIAL AT */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x07, 0xFF, 0x40,
+  0x0C, 0x00, 0x80,
+  0x20, 0xB6, 0x20,
+  0x21, 0x4A, 0x20,
+  0x22, 0x02, 0x10,
+  0x22, 0x06, 0x20,
+  0x21, 0x8E, 0x90,
+  0x20, 0xA0, 0x00,
+  0x0C, 0x00, 0x00,
+  0x02, 0xBE, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0041[ 28] = { /* code 0041, LATIN CAPITAL LETTER A */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0x40,
+  0x07, 0x80,
+  0x09, 0x80,
+  0x08, 0x90,
+  0x18, 0x60,
+  0x24, 0x30,
+  0x3F, 0xF4,
+  0x60, 0x18,
+  0x90, 0x0C,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0042[ 28] = { /* code 0042, LATIN CAPITAL LETTER B */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xC0,
+  0x30, 0x30,
+  0x30, 0x24,
+  0x30, 0x30,
+  0x3F, 0xD0,
+  0x30, 0x24,
+  0x30, 0x18,
+  0x30, 0x24,
+  0x3F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0043[ 28] = { /* code 0043, LATIN CAPITAL LETTER C */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xF4,
+  0x1C, 0x08,
+  0x30, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x30, 0x00,
+  0x28, 0x04,
+  0x0B, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0044[ 28] = { /* code 0044, LATIN CAPITAL LETTER D */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xC0,
+  0x30, 0x38,
+  0x30, 0x09,
+  0x30, 0x06,
+  0x30, 0x06,
+  0x30, 0x06,
+  0x30, 0x09,
+  0x30, 0x1C,
+  0x3F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0045[ 28] = { /* code 0045, LATIN CAPITAL LETTER E */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xF0,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x3F, 0xE0,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x3F, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0046[ 28] = { /* code 0046, LATIN CAPITAL LETTER F */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xD0,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x3F, 0xD0,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0047[ 28] = { /* code 0047, LATIN CAPITAL LETTER G */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xF4,
+  0x1C, 0x09,
+  0x30, 0x00,
+  0x60, 0x00,
+  0x60, 0x7D,
+  0x60, 0x05,
+  0x30, 0x05,
+  0x28, 0x05,
+  0x0B, 0xFC,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0048[ 28] = { /* code 0048, LATIN CAPITAL LETTER H */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x30, 0x08,
+  0x30, 0x08,
+  0x30, 0x08,
+  0x30, 0x08,
+  0x3F, 0xFC,
+  0x30, 0x08,
+  0x30, 0x08,
+  0x30, 0x08,
+  0x30, 0x08,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0049[ 14] = { /* code 0049, LATIN CAPITAL LETTER I */
+  0x00,
+  0x00,
+  0x30,
+  0x30,
+  0x30,
+  0x30,
+  0x30,
+  0x30,
+  0x30,
+  0x30,
+  0x30,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_004A[ 14] = { /* code 004A, LATIN CAPITAL LETTER J */
+  0x00,
+  0x00,
+  0x30,
+  0x30,
+  0x30,
+  0x30,
+  0x30,
+  0x30,
+  0x30,
+  0x30,
+  0x30,
+  0x20,
+  0xE0,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_004B[ 28] = { /* code 004B, LATIN CAPITAL LETTER K */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x30, 0x18,
+  0x30, 0x60,
+  0x31, 0x80,
+  0x3B, 0x00,
+  0x3D, 0x00,
+  0x37, 0x00,
+  0x31, 0xC0,
+  0x30, 0x70,
+  0x30, 0x1C,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_004C[ 28] = { /* code 004C, LATIN CAPITAL LETTER L */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x3F, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_004D[ 42] = { /* code 004D, LATIN CAPITAL LETTER M */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x38, 0x07, 0x40,
+  0x3C, 0x0B, 0x40,
+  0x39, 0x0B, 0x40,
+  0x36, 0x16, 0x40,
+  0x32, 0x22, 0x40,
+  0x31, 0xA2, 0x40,
+  0x30, 0xD2, 0x40,
+  0x30, 0x02, 0x40,
+  0x30, 0x02, 0x40,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_004E[ 28] = { /* code 004E, LATIN CAPITAL LETTER N */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x38, 0x08,
+  0x3C, 0x08,
+  0x39, 0x08,
+  0x36, 0x08,
+  0x31, 0x48,
+  0x30, 0xC8,
+  0x30, 0xA8,
+  0x30, 0x3C,
+  0x30, 0x2C,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_004F[ 42] = { /* code 004F, LATIN CAPITAL LETTER O */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x07, 0xF0, 0x00,
+  0x18, 0x1C, 0x00,
+  0x30, 0x09, 0x00,
+  0x60, 0x06, 0x00,
+  0x60, 0x02, 0x00,
+  0x60, 0x06, 0x00,
+  0x30, 0x06, 0x00,
+  0x28, 0x0C, 0x00,
+  0x0B, 0xF4, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0050[ 28] = { /* code 0050, LATIN CAPITAL LETTER P */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0x80,
+  0x30, 0x60,
+  0x30, 0x30,
+  0x30, 0x30,
+  0x30, 0x60,
+  0x3F, 0x80,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0051[ 42] = { /* code 0051, LATIN CAPITAL LETTER Q */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x07, 0xF0, 0x00,
+  0x18, 0x1C, 0x00,
+  0x30, 0x09, 0x00,
+  0x60, 0x06, 0x00,
+  0x60, 0x02, 0x00,
+  0x60, 0x06, 0x00,
+  0x30, 0x06, 0x00,
+  0x28, 0x0C, 0x00,
+  0x0B, 0xF4, 0x00,
+  0x00, 0x34, 0x00,
+  0x00, 0x0C, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0052[ 28] = { /* code 0052, LATIN CAPITAL LETTER R */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0x80,
+  0x30, 0x60,
+  0x30, 0x30,
+  0x30, 0x30,
+  0x3F, 0xD0,
+  0x30, 0x90,
+  0x30, 0x20,
+  0x30, 0x24,
+  0x30, 0x0C,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0053[ 28] = { /* code 0053, LATIN CAPITAL LETTER S */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xE0,
+  0x30, 0x10,
+  0x60, 0x00,
+  0x34, 0x00,
+  0x1F, 0xC0,
+  0x00, 0x70,
+  0x00, 0x20,
+  0x00, 0x30,
+  0x7F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0054[ 28] = { /* code 0054, LATIN CAPITAL LETTER T */
+  0x00, 0x00,
+  0x00, 0x00,
+  0xFF, 0xF8,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0055[ 28] = { /* code 0055, LATIN CAPITAL LETTER U */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x20, 0x0C,
+  0x20, 0x0C,
+  0x20, 0x0C,
+  0x20, 0x0C,
+  0x20, 0x0C,
+  0x20, 0x0C,
+  0x20, 0x0C,
+  0x24, 0x18,
+  0x0F, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0056[ 28] = { /* code 0056, LATIN CAPITAL LETTER V */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x90, 0x08,
+  0x60, 0x08,
+  0x30, 0x14,
+  0x24, 0x20,
+  0x18, 0x60,
+  0x0C, 0x90,
+  0x09, 0xC0,
+  0x07, 0x80,
+  0x03, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0057[ 42] = { /* code 0057, LATIN CAPITAL LETTER W */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x90, 0x70, 0x24,
+  0x60, 0x70, 0x20,
+  0x30, 0x94, 0x60,
+  0x20, 0x88, 0x60,
+  0x24, 0x88, 0x90,
+  0x19, 0x49, 0xC0,
+  0x0A, 0x05, 0x80,
+  0x0E, 0x07, 0x80,
+  0x0A, 0x03, 0x40,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0058[ 28] = { /* code 0058, LATIN CAPITAL LETTER X */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x30, 0x18,
+  0x14, 0x30,
+  0x0C, 0x90,
+  0x07, 0xC0,
+  0x03, 0x40,
+  0x06, 0xC0,
+  0x0C, 0x50,
+  0x24, 0x30,
+  0x60, 0x18,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0059[ 28] = { /* code 0059, LATIN CAPITAL LETTER Y */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x90, 0x24,
+  0x60, 0x60,
+  0x24, 0x90,
+  0x0E, 0x80,
+  0x07, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_005A[ 28] = { /* code 005A, LATIN CAPITAL LETTER Z */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xF8,
+  0x00, 0x24,
+  0x00, 0x60,
+  0x00, 0xC0,
+  0x02, 0x40,
+  0x0A, 0x00,
+  0x18, 0x00,
+  0x30, 0x00,
+  0x7F, 0xFC,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_005B[ 14] = { /* code 005B, LEFT SQUARE BRACKET */
+  0x00,
+  0x00,
+  0x3C,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x3C,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_005C[ 14] = { /* code 005C, REVERSE SOLIDUS */
+  0x00,
+  0x00,
+  0x80,
+  0x80,
+  0x50,
+  0x20,
+  0x20,
+  0x14,
+  0x18,
+  0x08,
+  0x08,
+  0x05,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_005D[ 14] = { /* code 005D, RIGHT SQUARE BRACKET */
+  0x00,
+  0x00,
+  0x3D,
+  0x09,
+  0x09,
+  0x09,
+  0x09,
+  0x09,
+  0x09,
+  0x09,
+  0x09,
+  0x09,
+  0x3D,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_005E[ 42] = { /* code 005E, CIRCUMFLEX ACCENT */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0xD0, 0x00,
+  0x03, 0x70, 0x00,
+  0x0C, 0x0C, 0x00,
+  0x20, 0x02, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_005F[ 28] = { /* code 005F, LOW LINE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xFF, 0xC0
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0060[ 28] = { /* code 0060, GRAVE ACCENT */
+  0x00, 0x00,
+  0x20, 0x00,
+  0x18, 0x00,
+  0x05, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0061[ 28] = { /* code 0061, LATIN SMALL LETTER A */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0x40,
+  0x10, 0x90,
+  0x00, 0x60,
+  0x2F, 0xE0,
+  0x60, 0x60,
+  0x60, 0xA0,
+  0x2F, 0xA0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0062[ 28] = { /* code 0062, LATIN SMALL LETTER B */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x27, 0x80,
+  0x38, 0x60,
+  0x30, 0x20,
+  0x20, 0x24,
+  0x20, 0x20,
+  0x34, 0x30,
+  0x2B, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0063[ 28] = { /* code 0063, LATIN SMALL LETTER C */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0x80,
+  0x24, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x20, 0x00,
+  0x1F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0064[ 28] = { /* code 0064, LATIN SMALL LETTER D */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x20,
+  0x00, 0x20,
+  0x0F, 0x60,
+  0x24, 0xE0,
+  0x60, 0x20,
+  0x60, 0x20,
+  0x60, 0x20,
+  0x30, 0x60,
+  0x1F, 0xA0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0065[ 28] = { /* code 0065, LATIN SMALL LETTER E */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0x40,
+  0x24, 0x60,
+  0x60, 0x20,
+  0x7F, 0xF0,
+  0x60, 0x00,
+  0x20, 0x00,
+  0x1F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0066[ 14] = { /* code 0066, LATIN SMALL LETTER F */
+  0x00,
+  0x00,
+  0x1F,
+  0x20,
+  0xBE,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0067[ 28] = { /* code 0067, LATIN SMALL LETTER G */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0x60,
+  0x34, 0xE0,
+  0x60, 0x20,
+  0x60, 0x20,
+  0x60, 0x20,
+  0x20, 0x60,
+  0x1F, 0xA0,
+  0x00, 0x60,
+  0x21, 0xD0,
+  0x0A, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0068[ 28] = { /* code 0068, LATIN SMALL LETTER H */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x27, 0x80,
+  0x38, 0x60,
+  0x20, 0x20,
+  0x20, 0x20,
+  0x20, 0x20,
+  0x20, 0x20,
+  0x20, 0x20,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0069[ 14] = { /* code 0069, LATIN SMALL LETTER I */
+  0x00,
+  0x00,
+  0x20,
+  0x00,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_006A[ 14] = { /* code 006A, LATIN SMALL LETTER J */
+  0x00,
+  0x00,
+  0x20,
+  0x00,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x60,
+  0x40
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_006B[ 28] = { /* code 006B, LATIN SMALL LETTER K */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x20, 0x30,
+  0x20, 0xC0,
+  0x27, 0x00,
+  0x3C, 0x00,
+  0x26, 0x00,
+  0x21, 0x80,
+  0x20, 0x70,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_006C[ 14] = { /* code 006C, LATIN SMALL LETTER L */
+  0x00,
+  0x00,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_006D[ 42] = { /* code 006D, LATIN SMALL LETTER M */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x27, 0x87, 0x40,
+  0x38, 0xB8, 0x90,
+  0x20, 0x20, 0x60,
+  0x20, 0x20, 0x60,
+  0x20, 0x20, 0x60,
+  0x20, 0x20, 0x60,
+  0x20, 0x20, 0x60,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_006E[ 28] = { /* code 006E, LATIN SMALL LETTER N */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x27, 0x80,
+  0x38, 0x60,
+  0x20, 0x20,
+  0x20, 0x20,
+  0x20, 0x20,
+  0x20, 0x20,
+  0x20, 0x20,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_006F[ 28] = { /* code 006F, LATIN SMALL LETTER O */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0x40,
+  0x24, 0x90,
+  0x60, 0x20,
+  0x60, 0x20,
+  0x60, 0x20,
+  0x30, 0x60,
+  0x1F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0070[ 28] = { /* code 0070, LATIN SMALL LETTER P */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x27, 0x80,
+  0x38, 0x60,
+  0x30, 0x20,
+  0x20, 0x24,
+  0x20, 0x20,
+  0x34, 0x30,
+  0x2B, 0xD0,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x20, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0071[ 28] = { /* code 0071, LATIN SMALL LETTER Q */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0x60,
+  0x24, 0xE0,
+  0x60, 0x20,
+  0x60, 0x20,
+  0x60, 0x20,
+  0x30, 0x60,
+  0x1F, 0xA0,
+  0x00, 0x20,
+  0x00, 0x20,
+  0x00, 0x20
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0072[ 14] = { /* code 0072, LATIN SMALL LETTER R */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x27,
+  0x38,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0073[ 28] = { /* code 0073, LATIN SMALL LETTER S */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0x40,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x2F, 0x00,
+  0x01, 0xC0,
+  0x00, 0x80,
+  0x7F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0074[ 14] = { /* code 0074, LATIN SMALL LETTER T */
+  0x00,
+  0x00,
+  0x00,
+  0x20,
+  0xBF,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x2F,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0075[ 28] = { /* code 0075, LATIN SMALL LETTER U */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x20, 0x20,
+  0x20, 0x20,
+  0x20, 0x20,
+  0x20, 0x20,
+  0x20, 0x20,
+  0x20, 0x60,
+  0x1F, 0xA0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0076[ 28] = { /* code 0076, LATIN SMALL LETTER V */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x90, 0x20,
+  0x60, 0x60,
+  0x20, 0x90,
+  0x24, 0x80,
+  0x19, 0x80,
+  0x0A, 0x40,
+  0x0B, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0077[ 42] = { /* code 0077, LATIN SMALL LETTER W */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x50, 0xC2, 0x40,
+  0x61, 0xC2, 0x00,
+  0x22, 0x52, 0x00,
+  0x22, 0x66, 0x00,
+  0x26, 0x29, 0x00,
+  0x1D, 0x2C, 0x00,
+  0x0D, 0x1C, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0078[ 28] = { /* code 0078, LATIN SMALL LETTER X */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x60, 0x60,
+  0x24, 0xC0,
+  0x0E, 0x40,
+  0x06, 0x00,
+  0x0F, 0x40,
+  0x24, 0xC0,
+  0x60, 0x60,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_0079[ 28] = { /* code 0079, LATIN SMALL LETTER Y */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x90, 0x20,
+  0x60, 0x60,
+  0x20, 0x90,
+  0x14, 0x80,
+  0x09, 0x80,
+  0x0B, 0x00,
+  0x06, 0x00,
+  0x05, 0x00,
+  0x0C, 0x00,
+  0x20, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_007A[ 28] = { /* code 007A, LATIN SMALL LETTER Z */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xC0,
+  0x00, 0xC0,
+  0x02, 0x40,
+  0x0A, 0x00,
+  0x18, 0x00,
+  0x30, 0x00,
+  0x7F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_007B[ 28] = { /* code 007B, LEFT CURLY BRACKET */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x02, 0xD0,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x2C, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0xD0,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_007C[ 14] = { /* code 007C, VERTICAL LINE */
+  0x00,
+  0x00,
+  0x24,
+  0x24,
+  0x24,
+  0x24,
+  0x24,
+  0x24,
+  0x24,
+  0x24,
+  0x24,
+  0x24,
+  0x24,
+  0x24
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_007D[ 28] = { /* code 007D, RIGHT CURLY BRACKET */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2D, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x01, 0xD0,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x2D, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensed14_AA2_007E[ 42] = { /* code 007E, TILDE */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x0B, 0x07, 0x00,
+  0x24, 0xF8, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const aafontsCharInfo_t charTable_DejaVuSansCondensed14_AA2[95] = 
+{
+  {   3,   1, FontDejaVuSansCondensed14_AA2_0020 }, /* code 0020 */
+  {   4,   1, FontDejaVuSansCondensed14_AA2_0021 }, /* code 0021 */
+  {   5,   2, FontDejaVuSansCondensed14_AA2_0022 }, /* code 0022 */
+  {   9,   3, FontDejaVuSansCondensed14_AA2_0023 }, /* code 0023 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0024 }, /* code 0024 */
+  {  10,   3, FontDejaVuSansCondensed14_AA2_0025 }, /* code 0025 */
+  {   8,   2, FontDejaVuSansCondensed14_AA2_0026 }, /* code 0026 */
+  {   3,   1, FontDejaVuSansCondensed14_AA2_0027 }, /* code 0027 */
+  {   4,   1, FontDejaVuSansCondensed14_AA2_0028 }, /* code 0028 */
+  {   4,   1, FontDejaVuSansCondensed14_AA2_0029 }, /* code 0029 */
+  {   5,   2, FontDejaVuSansCondensed14_AA2_002A }, /* code 002A */
+  {   9,   3, FontDejaVuSansCondensed14_AA2_002B }, /* code 002B */
+  {   3,   1, FontDejaVuSansCondensed14_AA2_002C }, /* code 002C */
+  {   4,   1, FontDejaVuSansCondensed14_AA2_002D }, /* code 002D */
+  {   3,   1, FontDejaVuSansCondensed14_AA2_002E }, /* code 002E */
+  {   4,   1, FontDejaVuSansCondensed14_AA2_002F }, /* code 002F */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0030 }, /* code 0030 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0031 }, /* code 0031 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0032 }, /* code 0032 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0033 }, /* code 0033 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0034 }, /* code 0034 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0035 }, /* code 0035 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0036 }, /* code 0036 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0037 }, /* code 0037 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0038 }, /* code 0038 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0039 }, /* code 0039 */
+  {   4,   1, FontDejaVuSansCondensed14_AA2_003A }, /* code 003A */
+  {   4,   1, FontDejaVuSansCondensed14_AA2_003B }, /* code 003B */
+  {   9,   3, FontDejaVuSansCondensed14_AA2_003C }, /* code 003C */
+  {   9,   3, FontDejaVuSansCondensed14_AA2_003D }, /* code 003D */
+  {   9,   3, FontDejaVuSansCondensed14_AA2_003E }, /* code 003E */
+  {   6,   2, FontDejaVuSansCondensed14_AA2_003F }, /* code 003F */
+  {  11,   3, FontDejaVuSansCondensed14_AA2_0040 }, /* code 0040 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0041 }, /* code 0041 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0042 }, /* code 0042 */
+  {   8,   2, FontDejaVuSansCondensed14_AA2_0043 }, /* code 0043 */
+  {   8,   2, FontDejaVuSansCondensed14_AA2_0044 }, /* code 0044 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0045 }, /* code 0045 */
+  {   6,   2, FontDejaVuSansCondensed14_AA2_0046 }, /* code 0046 */
+  {   8,   2, FontDejaVuSansCondensed14_AA2_0047 }, /* code 0047 */
+  {   8,   2, FontDejaVuSansCondensed14_AA2_0048 }, /* code 0048 */
+  {   3,   1, FontDejaVuSansCondensed14_AA2_0049 }, /* code 0049 */
+  {   3,   1, FontDejaVuSansCondensed14_AA2_004A }, /* code 004A */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_004B }, /* code 004B */
+  {   6,   2, FontDejaVuSansCondensed14_AA2_004C }, /* code 004C */
+  {   9,   3, FontDejaVuSansCondensed14_AA2_004D }, /* code 004D */
+  {   8,   2, FontDejaVuSansCondensed14_AA2_004E }, /* code 004E */
+  {   9,   3, FontDejaVuSansCondensed14_AA2_004F }, /* code 004F */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0050 }, /* code 0050 */
+  {   9,   3, FontDejaVuSansCondensed14_AA2_0051 }, /* code 0051 */
+  {   8,   2, FontDejaVuSansCondensed14_AA2_0052 }, /* code 0052 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0053 }, /* code 0053 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0054 }, /* code 0054 */
+  {   8,   2, FontDejaVuSansCondensed14_AA2_0055 }, /* code 0055 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0056 }, /* code 0056 */
+  {  11,   3, FontDejaVuSansCondensed14_AA2_0057 }, /* code 0057 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0058 }, /* code 0058 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0059 }, /* code 0059 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_005A }, /* code 005A */
+  {   4,   1, FontDejaVuSansCondensed14_AA2_005B }, /* code 005B */
+  {   4,   1, FontDejaVuSansCondensed14_AA2_005C }, /* code 005C */
+  {   4,   1, FontDejaVuSansCondensed14_AA2_005D }, /* code 005D */
+  {   9,   3, FontDejaVuSansCondensed14_AA2_005E }, /* code 005E */
+  {   5,   2, FontDejaVuSansCondensed14_AA2_005F }, /* code 005F */
+  {   5,   2, FontDejaVuSansCondensed14_AA2_0060 }, /* code 0060 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0061 }, /* code 0061 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0062 }, /* code 0062 */
+  {   6,   2, FontDejaVuSansCondensed14_AA2_0063 }, /* code 0063 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0064 }, /* code 0064 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0065 }, /* code 0065 */
+  {   4,   1, FontDejaVuSansCondensed14_AA2_0066 }, /* code 0066 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0067 }, /* code 0067 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0068 }, /* code 0068 */
+  {   3,   1, FontDejaVuSansCondensed14_AA2_0069 }, /* code 0069 */
+  {   3,   1, FontDejaVuSansCondensed14_AA2_006A }, /* code 006A */
+  {   6,   2, FontDejaVuSansCondensed14_AA2_006B }, /* code 006B */
+  {   3,   1, FontDejaVuSansCondensed14_AA2_006C }, /* code 006C */
+  {  11,   3, FontDejaVuSansCondensed14_AA2_006D }, /* code 006D */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_006E }, /* code 006E */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_006F }, /* code 006F */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0070 }, /* code 0070 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0071 }, /* code 0071 */
+  {   4,   1, FontDejaVuSansCondensed14_AA2_0072 }, /* code 0072 */
+  {   6,   2, FontDejaVuSansCondensed14_AA2_0073 }, /* code 0073 */
+  {   4,   1, FontDejaVuSansCondensed14_AA2_0074 }, /* code 0074 */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_0075 }, /* code 0075 */
+  {   6,   2, FontDejaVuSansCondensed14_AA2_0076 }, /* code 0076 */
+  {   9,   3, FontDejaVuSansCondensed14_AA2_0077 }, /* code 0077 */
+  {   6,   2, FontDejaVuSansCondensed14_AA2_0078 }, /* code 0078 */
+  {   6,   2, FontDejaVuSansCondensed14_AA2_0079 }, /* code 0079 */
+  {   6,   2, FontDejaVuSansCondensed14_AA2_007A }, /* code 007A */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_007B }, /* code 007B */
+  {   4,   1, FontDejaVuSansCondensed14_AA2_007C }, /* code 007C */
+  {   7,   2, FontDejaVuSansCondensed14_AA2_007D }, /* code 007D */
+  {   9,   3, FontDejaVuSansCondensed14_AA2_007E }  /* code 007E */  
+};
+
+aafontsFont_t DejaVuSansCondensed14_AA2 = 
+{
+  AAFONTS_FONTTYPE_AA2,                         /* Font type (anti-aliasing level) */
+  14,                                           /* Font height in pixels */
+  3,                                            /* Width to insert for unknown characters */
+  9,                                            /* Height of upper-case characters */
+  7,                                            /* Height of lower-case characters */
+  11,                                           /* Font baseline */
+  0x0020,                                       /* Unicode address of first character */
+  0x007E,                                       /* Unicode address of last character */
+  &charTable_DejaVuSansCondensed14_AA2[0]  	    /* Font char data */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansCondensed14_AA2.h b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansCondensed14_AA2.h
new file mode 100644
index 0000000000000000000000000000000000000000..fda5ba57dad043367d07bb4eb618a91aa7b27b74
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansCondensed14_AA2.h
@@ -0,0 +1,52 @@
+/**************************************************************************/
+/*! 
+    @file     DejaVuSansCondensed14_AA2.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __DEJAVUSANSCONDENSED14_AA2_H__
+#define __DEJAVUSANSCONDENSED14_AA2_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "drivers/displays/graphic/aafonts.h"
+
+extern aafontsFont_t DejaVuSansCondensed14_AA2;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansCondensedBold14_AA2.c b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansCondensedBold14_AA2.c
new file mode 100644
index 0000000000000000000000000000000000000000..25745043d5a0c9044f942516b46ffdd432701629
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansCondensedBold14_AA2.c
@@ -0,0 +1,1764 @@
+/**************************************************************************/
+/*! 
+    @file     DejaVuSansCondensedBold14_AA2.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "DejaVuSansCondensedBold14_AA2.h"
+
+/* Start of unicode area <Basic Latin> */
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0020[ 14] = { /* code 0020, SPACE */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0021[ 28] = { /* code 0021, EXCLAMATION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1D, 0x00,
+  0x1D, 0x00,
+  0x1D, 0x00,
+  0x1D, 0x00,
+  0x1D, 0x00,
+  0x1C, 0x00,
+  0x00, 0x00,
+  0x1D, 0x00,
+  0x1D, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0022[ 28] = { /* code 0022, QUOTATION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x36, 0x80,
+  0x36, 0x80,
+  0x36, 0x80,
+  0x36, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0023[ 42] = { /* code 0023, NUMBER SIGN */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x01, 0x89, 0x00,
+  0x02, 0x4C, 0x00,
+  0x02, 0x58, 0x00,
+  0x2F, 0xFF, 0x40,
+  0x06, 0x24, 0x00,
+  0x7F, 0xFF, 0x00,
+  0x5E, 0x65, 0x00,
+  0x0C, 0x60, 0x00,
+  0x0C, 0x90, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0024[ 28] = { /* code 0024, DOLLAR SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x02, 0x00,
+  0x0F, 0xE0,
+  0x3A, 0xB4,
+  0x36, 0x00,
+  0x3F, 0xD0,
+  0x0A, 0xF4,
+  0x02, 0x78,
+  0x32, 0x78,
+  0x3F, 0xF0,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0025[ 42] = { /* code 0025, PERCENT SIGN */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x2E, 0x03, 0x40,
+  0x63, 0x46, 0x00,
+  0xA2, 0x4C, 0x00,
+  0x63, 0x58, 0x00,
+  0x2E, 0x31, 0xC0,
+  0x00, 0x97, 0x70,
+  0x00, 0xCA, 0x24,
+  0x02, 0x4A, 0x34,
+  0x06, 0x03, 0xF0,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0026[ 42] = { /* code 0026, AMPERSAND */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x07, 0xF4, 0x00,
+  0x0F, 0xF4, 0x00,
+  0x0E, 0x00, 0x00,
+  0x0B, 0x40, 0x00,
+  0x2F, 0xD3, 0x40,
+  0x74, 0xFB, 0x40,
+  0x74, 0x7E, 0x00,
+  0x3D, 0x7E, 0x00,
+  0x1F, 0xFB, 0x80,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0027[ 14] = { /* code 0027, APOSTROPHE */
+  0x00,
+  0x00,
+  0x34,
+  0x34,
+  0x34,
+  0x34,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0028[ 28] = { /* code 0028, LEFT PARENTHESIS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0A, 0x00,
+  0x1D, 0x00,
+  0x2C, 0x00,
+  0x28, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x2C, 0x00,
+  0x1C, 0x00,
+  0x0E, 0x00,
+  0x07, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0029[ 28] = { /* code 0029, RIGHT PARENTHESIS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x38, 0x00,
+  0x1C, 0x00,
+  0x0D, 0x00,
+  0x0E, 0x00,
+  0x0B, 0x00,
+  0x0B, 0x00,
+  0x0B, 0x00,
+  0x0E, 0x00,
+  0x1D, 0x00,
+  0x2C, 0x00,
+  0x34, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_002A[ 28] = { /* code 002A, ASTERISK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x09, 0x00,
+  0x99, 0x90,
+  0x2F, 0x40,
+  0x3F, 0x80,
+  0x49, 0x50,
+  0x09, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_002B[ 42] = { /* code 002B, PLUS SIGN */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0xC0, 0x00,
+  0x00, 0xC0, 0x00,
+  0x00, 0xC0, 0x00,
+  0x00, 0xC0, 0x00,
+  0x2F, 0xFE, 0x00,
+  0x00, 0xC0, 0x00,
+  0x00, 0xC0, 0x00,
+  0x00, 0xC0, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_002C[ 14] = { /* code 002C, COMMA */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x2C,
+  0x2C,
+  0x34,
+  0x60,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_002D[ 14] = { /* code 002D, HYPHEN-MINUS */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x7E,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_002E[ 14] = { /* code 002E, FULL STOP */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x2C,
+  0x2C,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_002F[ 14] = { /* code 002F, SOLIDUS */
+  0x00,
+  0x00,
+  0x06,
+  0x0A,
+  0x09,
+  0x0C,
+  0x18,
+  0x24,
+  0x30,
+  0x60,
+  0x60,
+  0x90,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0030[ 28] = { /* code 0030, DIGIT ZERO */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xD0,
+  0x2F, 0xF4,
+  0x38, 0x38,
+  0x78, 0x3C,
+  0x74, 0x3C,
+  0x74, 0x3C,
+  0x78, 0x38,
+  0x3C, 0xB4,
+  0x0F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0031[ 28] = { /* code 0031, DIGIT ONE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xC0,
+  0x2F, 0xC0,
+  0x03, 0xC0,
+  0x03, 0xC0,
+  0x03, 0xC0,
+  0x03, 0xC0,
+  0x03, 0xC0,
+  0x2F, 0xF8,
+  0x2F, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0032[ 28] = { /* code 0032, DIGIT TWO */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0xD0,
+  0x3F, 0xF4,
+  0x00, 0xB4,
+  0x00, 0xB4,
+  0x01, 0xE0,
+  0x07, 0xC0,
+  0x1F, 0x00,
+  0x3F, 0xF4,
+  0x3F, 0xF4,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0033[ 28] = { /* code 0033, DIGIT THREE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xD0,
+  0x2A, 0xB4,
+  0x00, 0x74,
+  0x00, 0xF0,
+  0x0F, 0xD0,
+  0x00, 0xB4,
+  0x00, 0x78,
+  0x7A, 0xF4,
+  0x2F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0034[ 28] = { /* code 0034, DIGIT FOUR */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x01, 0xE0,
+  0x03, 0xE0,
+  0x0A, 0xE0,
+  0x1D, 0xE0,
+  0x34, 0xE0,
+  0x60, 0xE0,
+  0x7F, 0xFC,
+  0x00, 0xE0,
+  0x00, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0035[ 28] = { /* code 0035, DIGIT FIVE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0xF0,
+  0x2F, 0xF0,
+  0x28, 0x00,
+  0x2F, 0xD0,
+  0x2F, 0xF4,
+  0x00, 0x78,
+  0x00, 0x78,
+  0x3A, 0xF4,
+  0x3F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0036[ 28] = { /* code 0036, DIGIT SIX */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xF4,
+  0x1F, 0xA4,
+  0x3C, 0x00,
+  0x3B, 0xD0,
+  0x7F, 0xF4,
+  0x7C, 0x38,
+  0x38, 0x38,
+  0x2F, 0x78,
+  0x0F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0037[ 28] = { /* code 0037, DIGIT SEVEN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xF8,
+  0x7F, 0xF8,
+  0x00, 0xB4,
+  0x00, 0xE0,
+  0x01, 0xD0,
+  0x03, 0xC0,
+  0x07, 0x80,
+  0x0B, 0x00,
+  0x0E, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0038[ 28] = { /* code 0038, DIGIT EIGHT */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xE0,
+  0x3F, 0xF4,
+  0x38, 0x78,
+  0x2C, 0xB4,
+  0x0F, 0xE0,
+  0x38, 0x78,
+  0x74, 0x38,
+  0x3C, 0x78,
+  0x1F, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0039[ 28] = { /* code 0039, DIGIT NINE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xC0,
+  0x3F, 0xF0,
+  0x74, 0x74,
+  0x74, 0x78,
+  0x3D, 0xF8,
+  0x1F, 0xF8,
+  0x00, 0x74,
+  0x20, 0xF0,
+  0x3F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_003A[ 14] = { /* code 003A, COLON */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x2C,
+  0x2C,
+  0x00,
+  0x00,
+  0x00,
+  0x2C,
+  0x2C,
+  0x00,
+  0x00,
+  0x00
+	};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_003B[ 14] = { /* code 003B, SEMICOLON */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x00,
+  0x00,
+  0x2C,
+  0x2C,
+  0x34,
+  0x70,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_003C[ 42] = { /* code 003C, LESS-THAN SIGN */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x0A, 0x00,
+  0x01, 0xFD, 0x00,
+  0x2F, 0x80, 0x00,
+  0x2D, 0x00, 0x00,
+  0x07, 0xF0, 0x00,
+  0x00, 0x3E, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_003D[ 42] = { /* code 003D, EQUALS SIGN */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x2F, 0xFE, 0x00,
+  0x00, 0x00, 0x00,
+  0x2F, 0xFE, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_003E[ 42] = { /* code 003E, GREATER-THAN SIGN */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x28, 0x00, 0x00,
+  0x1F, 0xD0, 0x00,
+  0x00, 0xBE, 0x00,
+  0x00, 0x1E, 0x00,
+  0x03, 0xF4, 0x00,
+  0x2F, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_003F[ 28] = { /* code 003F, QUESTION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0x80,
+  0x7F, 0xD0,
+  0x01, 0xD0,
+  0x02, 0xD0,
+  0x0B, 0x40,
+  0x0E, 0x00,
+  0x00, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0040[ 42] = { /* code 0040, COMMERCIAL AT */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x07, 0xFF, 0x40,
+  0x0C, 0x00, 0xC0,
+  0x24, 0xBA, 0x60,
+  0x21, 0x8E, 0x20,
+  0x62, 0x46, 0x20,
+  0x22, 0x4A, 0x20,
+  0x21, 0xFF, 0xD0,
+  0x24, 0x00, 0x00,
+  0x0E, 0x02, 0x00,
+  0x02, 0xFE, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0041[ 28] = { /* code 0041, LATIN CAPITAL LETTER A */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0xD0,
+  0x07, 0xE0,
+  0x0B, 0xF0,
+  0x0E, 0x74,
+  0x1D, 0x38,
+  0x2C, 0x2C,
+  0x3F, 0xFD,
+  0x74, 0x0E,
+  0xB4, 0x0B,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0042[ 28] = { /* code 0042, LATIN CAPITAL LETTER B */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xE0,
+  0x3F, 0xFC,
+  0x3C, 0x2C,
+  0x3C, 0x3C,
+  0x3F, 0xF4,
+  0x3C, 0x2D,
+  0x3C, 0x1D,
+  0x3F, 0xFD,
+  0x3F, 0xF4,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0043[ 28] = { /* code 0043, LATIN CAPITAL LETTER C */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0xF8,
+  0x1F, 0xFC,
+  0x3D, 0x00,
+  0x78, 0x00,
+  0x78, 0x00,
+  0x78, 0x00,
+  0x3C, 0x00,
+  0x2F, 0x5C,
+  0x0B, 0xFC,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0044[ 42] = { /* code 0044, LATIN CAPITAL LETTER D */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x3F, 0xE0, 0x00,
+  0x3F, 0xFD, 0x00,
+  0x3C, 0x1F, 0x00,
+  0x3C, 0x0B, 0x40,
+  0x3C, 0x0B, 0x40,
+  0x3C, 0x0B, 0x40,
+  0x3C, 0x0F, 0x00,
+  0x3F, 0xFD, 0x00,
+  0x3F, 0xF4, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0045[ 28] = { /* code 0045, LATIN CAPITAL LETTER E */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xF4,
+  0x3F, 0xF4,
+  0x3C, 0x00,
+  0x3C, 0x00,
+  0x3F, 0xF4,
+  0x3C, 0x00,
+  0x3C, 0x00,
+  0x3F, 0xF8,
+  0x3F, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0046[ 28] = { /* code 0046, LATIN CAPITAL LETTER F */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xF4,
+  0x3F, 0xF4,
+  0x3C, 0x00,
+  0x3C, 0x00,
+  0x3F, 0xF4,
+  0x3C, 0x00,
+  0x3C, 0x00,
+  0x3C, 0x00,
+  0x3C, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0047[ 42] = { /* code 0047, LATIN CAPITAL LETTER G */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x03, 0xFC, 0x00,
+  0x1F, 0xFE, 0x00,
+  0x3D, 0x00, 0x00,
+  0x78, 0x00, 0x00,
+  0x78, 0x3F, 0x00,
+  0x78, 0x3F, 0x00,
+  0x3C, 0x0B, 0x00,
+  0x2F, 0x9F, 0x00,
+  0x0B, 0xFE, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0048[ 42] = { /* code 0048, LATIN CAPITAL LETTER H */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x3C, 0x0F, 0x00,
+  0x3C, 0x0F, 0x00,
+  0x3C, 0x0F, 0x00,
+  0x3C, 0x0F, 0x00,
+  0x3F, 0xFF, 0x00,
+  0x3C, 0x0F, 0x00,
+  0x3C, 0x0F, 0x00,
+  0x3C, 0x0F, 0x00,
+  0x3C, 0x0F, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0049[ 14] = { /* code 0049, LATIN CAPITAL LETTER I */
+  0x00,
+  0x00,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_004A[ 14] = { /* code 004A, LATIN CAPITAL LETTER J */
+  0x00,
+  0x00,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x78,
+  0xF4,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_004B[ 28] = { /* code 004B, LATIN CAPITAL LETTER K */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3C, 0x1F,
+  0x3C, 0x3C,
+  0x3D, 0xF0,
+  0x3F, 0xD0,
+  0x3F, 0x80,
+  0x3F, 0xD0,
+  0x3D, 0xF4,
+  0x3C, 0x3D,
+  0x3C, 0x1F,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_004C[ 28] = { /* code 004C, LATIN CAPITAL LETTER L */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3C, 0x00,
+  0x3C, 0x00,
+  0x3C, 0x00,
+  0x3C, 0x00,
+  0x3C, 0x00,
+  0x3C, 0x00,
+  0x3C, 0x00,
+  0x3F, 0xF8,
+  0x3F, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_004D[ 42] = { /* code 004D, LATIN CAPITAL LETTER M */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x3E, 0x03, 0xE0,
+  0x3F, 0x07, 0xE0,
+  0x3F, 0x4B, 0xE0,
+  0x3E, 0x8E, 0xE0,
+  0x3D, 0xED, 0xE0,
+  0x3C, 0xF8, 0xE0,
+  0x3C, 0x74, 0xE0,
+  0x3C, 0x00, 0xE0,
+  0x3C, 0x00, 0xE0,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_004E[ 42] = { /* code 004E, LATIN CAPITAL LETTER N */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x3D, 0x0B, 0x00,
+  0x3E, 0x0B, 0x00,
+  0x3F, 0x4B, 0x00,
+  0x3F, 0x8B, 0x00,
+  0x3D, 0xDB, 0x00,
+  0x3C, 0xBF, 0x00,
+  0x3C, 0x7F, 0x00,
+  0x3C, 0x3F, 0x00,
+  0x3C, 0x1F, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_004F[ 42] = { /* code 004F, LATIN CAPITAL LETTER O */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x07, 0xF4, 0x00,
+  0x1F, 0xFE, 0x00,
+  0x3C, 0x0F, 0x40,
+  0x78, 0x07, 0x40,
+  0x78, 0x07, 0x80,
+  0x78, 0x07, 0x80,
+  0x3C, 0x0B, 0x40,
+  0x2F, 0x7E, 0x00,
+  0x0B, 0xFC, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0050[ 28] = { /* code 0050, LATIN CAPITAL LETTER P */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xE0,
+  0x3F, 0xFC,
+  0x3C, 0x2D,
+  0x3C, 0x2D,
+  0x3F, 0xFC,
+  0x3F, 0xF4,
+  0x3C, 0x00,
+  0x3C, 0x00,
+  0x3C, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0051[ 42] = { /* code 0051, LATIN CAPITAL LETTER Q */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x07, 0xF4, 0x00,
+  0x1F, 0xFE, 0x00,
+  0x3C, 0x0F, 0x40,
+  0x78, 0x07, 0x40,
+  0x78, 0x07, 0x80,
+  0x78, 0x07, 0x80,
+  0x3C, 0x0B, 0x40,
+  0x2F, 0x7E, 0x00,
+  0x0B, 0xF8, 0x00,
+  0x00, 0x2C, 0x00,
+  0x00, 0x0E, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0052[ 28] = { /* code 0052, LATIN CAPITAL LETTER R */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xE0,
+  0x3F, 0xF8,
+  0x3C, 0x3C,
+  0x3C, 0x3C,
+  0x3F, 0xF4,
+  0x3F, 0xF4,
+  0x3C, 0x3C,
+  0x3C, 0x2D,
+  0x3C, 0x1F,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0053[ 28] = { /* code 0053, LATIN CAPITAL LETTER S */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xF4,
+  0x3F, 0xF4,
+  0x38, 0x00,
+  0x3D, 0x00,
+  0x2F, 0xF4,
+  0x01, 0xB8,
+  0x00, 0x3C,
+  0x3F, 0xF8,
+  0x3F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0054[ 28] = { /* code 0054, LATIN CAPITAL LETTER T */
+  0x00, 0x00,
+  0x00, 0x00,
+  0xFF, 0xFC,
+  0xFF, 0xFC,
+  0x07, 0x80,
+  0x07, 0x80,
+  0x07, 0x80,
+  0x07, 0x80,
+  0x07, 0x80,
+  0x07, 0x80,
+  0x07, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0055[ 42] = { /* code 0055, LATIN CAPITAL LETTER U */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x3C, 0x1E, 0x00,
+  0x3C, 0x1E, 0x00,
+  0x3C, 0x1E, 0x00,
+  0x3C, 0x1E, 0x00,
+  0x3C, 0x1E, 0x00,
+  0x3C, 0x1E, 0x00,
+  0x3C, 0x1E, 0x00,
+  0x2F, 0x7D, 0x00,
+  0x0F, 0xF8, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0056[ 28] = { /* code 0056, LATIN CAPITAL LETTER V */
+  0x00, 0x00,
+  0x00, 0x00,
+  0xB0, 0x0B,
+  0x74, 0x0E,
+  0x38, 0x1D,
+  0x2C, 0x2C,
+  0x1D, 0x38,
+  0x0E, 0x74,
+  0x0B, 0xF0,
+  0x07, 0xE0,
+  0x03, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0057[ 42] = { /* code 0057, LATIN CAPITAL LETTER W */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0xB4, 0x3C, 0x1D,
+  0x74, 0x7C, 0x2D,
+  0x38, 0x7D, 0x2C,
+  0x3C, 0xAA, 0x38,
+  0x2D, 0xDA, 0x78,
+  0x1D, 0xD7, 0xB4,
+  0x1F, 0xC3, 0xF4,
+  0x0F, 0x83, 0xF0,
+  0x0F, 0x82, 0xE0,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0058[ 28] = { /* code 0058, LATIN CAPITAL LETTER X */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x78, 0x1E,
+  0x3C, 0x2C,
+  0x1E, 0x78,
+  0x0B, 0xF0,
+  0x03, 0xD0,
+  0x0B, 0xF0,
+  0x1E, 0x74,
+  0x2C, 0x3C,
+  0xB8, 0x1F,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0059[ 28] = { /* code 0059, LATIN CAPITAL LETTER Y */
+  0x00, 0x00,
+  0x00, 0x00,
+  0xF4, 0x1E,
+  0x78, 0x3C,
+  0x2D, 0xB8,
+  0x0F, 0xF0,
+  0x0B, 0xD0,
+  0x03, 0xC0,
+  0x03, 0xC0,
+  0x03, 0xC0,
+  0x03, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_005A[ 28] = { /* code 005A, LATIN CAPITAL LETTER Z */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xFC,
+  0x7F, 0xFC,
+  0x00, 0xB4,
+  0x01, 0xE0,
+  0x03, 0xC0,
+  0x0F, 0x40,
+  0x2E, 0x00,
+  0x7F, 0xFD,
+  0x7F, 0xFD,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_005B[ 28] = { /* code 005B, LEFT SQUARE BRACKET */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x3F, 0x00,
+  0x3F, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_005C[ 14] = { /* code 005C, REVERSE SOLIDUS */
+  0x00,
+  0x00,
+  0xC0,
+  0x90,
+  0x60,
+  0x30,
+  0x24,
+  0x18,
+  0x0C,
+  0x0C,
+  0x09,
+  0x06,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_005D[ 28] = { /* code 005D, RIGHT SQUARE BRACKET */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0x00,
+  0x0B, 0x00,
+  0x0B, 0x00,
+  0x0B, 0x00,
+  0x0B, 0x00,
+  0x0B, 0x00,
+  0x0B, 0x00,
+  0x0B, 0x00,
+  0x0B, 0x00,
+  0x7F, 0x00,
+  0x7F, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_005E[ 42] = { /* code 005E, CIRCUMFLEX ACCENT */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x01, 0xD0, 0x00,
+  0x03, 0xF0, 0x00,
+  0x0E, 0x1C, 0x00,
+  0x24, 0x07, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_005F[ 28] = { /* code 005F, LOW LINE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xFF, 0xC0
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0060[ 28] = { /* code 0060, GRAVE ACCENT */
+  0x00, 0x00,
+  0x70, 0x00,
+  0x18, 0x00,
+  0x09, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0061[ 28] = { /* code 0061, LATIN SMALL LETTER A */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xC0,
+  0x3A, 0xB0,
+  0x00, 0x74,
+  0x3F, 0xF4,
+  0x74, 0x74,
+  0x74, 0xF4,
+  0x3F, 0xB4,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0062[ 28] = { /* code 0062, LATIN SMALL LETTER B */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x3B, 0xE0,
+  0x3F, 0xF8,
+  0x3C, 0x2C,
+  0x38, 0x2C,
+  0x38, 0x2C,
+  0x3D, 0x7C,
+  0x3F, 0xF4,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0063[ 28] = { /* code 0063, LATIN SMALL LETTER C */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xD0,
+  0x2F, 0xE0,
+  0x78, 0x00,
+  0x74, 0x00,
+  0x74, 0x00,
+  0x3D, 0x10,
+  0x1F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0064[ 28] = { /* code 0064, LATIN SMALL LETTER D */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x38,
+  0x00, 0x38,
+  0x0F, 0x38,
+  0x3F, 0xF8,
+  0x78, 0x78,
+  0x74, 0x38,
+  0x74, 0x38,
+  0x3C, 0xB8,
+  0x1F, 0xB8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0065[ 28] = { /* code 0065, LATIN SMALL LETTER E */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xC0,
+  0x2E, 0xB0,
+  0x74, 0x38,
+  0x7F, 0xF8,
+  0x74, 0x00,
+  0x3C, 0x14,
+  0x1F, 0xF4,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0066[ 28] = { /* code 0066, LATIN SMALL LETTER F */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0x80,
+  0x2C, 0x00,
+  0xBF, 0x80,
+  0x6E, 0x40,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0067[ 28] = { /* code 0067, LATIN SMALL LETTER G */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0x38,
+  0x3F, 0xF8,
+  0x78, 0x78,
+  0x74, 0x38,
+  0x74, 0x38,
+  0x3F, 0xF8,
+  0x1F, 0x78,
+  0x00, 0x78,
+  0x2F, 0xF0,
+  0x05, 0x40
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0068[ 28] = { /* code 0068, LATIN SMALL LETTER H */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0xE0,
+  0x3F, 0xF8,
+  0x3C, 0x38,
+  0x38, 0x38,
+  0x38, 0x38,
+  0x38, 0x38,
+  0x38, 0x38,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0069[ 14] = { /* code 0069, LATIN SMALL LETTER I */
+  0x00,
+  0x00,
+  0x38,
+  0x00,
+  0x38,
+  0x38,
+  0x38,
+  0x38,
+  0x38,
+  0x38,
+  0x38,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_006A[ 14] = { /* code 006A, LATIN SMALL LETTER J */
+  0x00,
+  0x00,
+  0x38,
+  0x00,
+  0x38,
+  0x38,
+  0x38,
+  0x38,
+  0x38,
+  0x38,
+  0x38,
+  0x38,
+  0xF4,
+  0xD0
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_006B[ 28] = { /* code 006B, LATIN SMALL LETTER K */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x3C,
+  0x38, 0xF0,
+  0x3F, 0xC0,
+  0x3F, 0x40,
+  0x3F, 0xC0,
+  0x38, 0xF0,
+  0x38, 0x7C,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_006C[ 14] = { /* code 006C, LATIN SMALL LETTER L */
+  0x00,
+  0x00,
+  0x38,
+  0x38,
+  0x38,
+  0x38,
+  0x38,
+  0x38,
+  0x38,
+  0x38,
+  0x38,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_006D[ 42] = { /* code 006D, LATIN SMALL LETTER M */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x39, 0xD2, 0xD0,
+  0x3F, 0xFF, 0xF0,
+  0x3C, 0x78, 0x74,
+  0x38, 0x78, 0x74,
+  0x38, 0x78, 0x74,
+  0x38, 0x78, 0x74,
+  0x38, 0x78, 0x74,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_006E[ 28] = { /* code 006E, LATIN SMALL LETTER N */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x38, 0xE0,
+  0x3F, 0xF8,
+  0x3C, 0x38,
+  0x38, 0x38,
+  0x38, 0x38,
+  0x38, 0x38,
+  0x38, 0x38,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_006F[ 28] = { /* code 006F, LATIN SMALL LETTER O */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xC0,
+  0x3F, 0xF4,
+  0x78, 0x38,
+  0x74, 0x3C,
+  0x74, 0x38,
+  0x3C, 0xB8,
+  0x1F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0070[ 28] = { /* code 0070, LATIN SMALL LETTER P */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x38, 0xE0,
+  0x3F, 0xF8,
+  0x3C, 0x2C,
+  0x38, 0x2C,
+  0x38, 0x2C,
+  0x3D, 0x7C,
+  0x3F, 0xF4,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0071[ 28] = { /* code 0071, LATIN SMALL LETTER Q */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0x38,
+  0x3F, 0xF8,
+  0x78, 0x78,
+  0x74, 0x38,
+  0x74, 0x38,
+  0x3C, 0xB8,
+  0x1F, 0xB8,
+  0x00, 0x38,
+  0x00, 0x38,
+  0x00, 0x38
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0072[ 28] = { /* code 0072, LATIN SMALL LETTER R */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x38, 0xC0,
+  0x3F, 0xC0,
+  0x3C, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0073[ 28] = { /* code 0073, LATIN SMALL LETTER S */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0xC0,
+  0x7A, 0x90,
+  0x74, 0x00,
+  0x3F, 0x90,
+  0x02, 0xE0,
+  0x74, 0xE0,
+  0x3F, 0xD0,
+  0x05, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0074[ 28] = { /* code 0074, LATIN SMALL LETTER T */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3C, 0x00,
+  0xBF, 0xC0,
+  0xBF, 0xC0,
+  0x3C, 0x00,
+  0x3C, 0x00,
+  0x3C, 0x00,
+  0x2F, 0x80,
+  0x1F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0075[ 28] = { /* code 0075, LATIN SMALL LETTER U */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x38, 0x38,
+  0x38, 0x38,
+  0x38, 0x38,
+  0x38, 0x38,
+  0x38, 0x38,
+  0x3D, 0xB8,
+  0x1F, 0xB8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0076[ 28] = { /* code 0076, LATIN SMALL LETTER V */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xB0, 0x38,
+  0x74, 0x74,
+  0x38, 0xB0,
+  0x2C, 0xE0,
+  0x1E, 0xD0,
+  0x0F, 0xC0,
+  0x0B, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0077[ 42] = { /* code 0077, LATIN SMALL LETTER W */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0xB0, 0xA0, 0xE0,
+  0x74, 0xF1, 0xD0,
+  0x39, 0xF2, 0xC0,
+  0x29, 0xF6, 0x80,
+  0x2F, 0x5F, 0x80,
+  0x1F, 0x5F, 0x40,
+  0x0F, 0x0F, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0078[ 28] = { /* code 0078, LATIN SMALL LETTER X */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xB4, 0x78,
+  0x3C, 0xF0,
+  0x1F, 0xD0,
+  0x0B, 0x80,
+  0x0F, 0xC0,
+  0x2D, 0xE0,
+  0xB4, 0x78,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_0079[ 28] = { /* code 0079, LATIN SMALL LETTER Y */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xB0, 0x38,
+  0x74, 0x74,
+  0x38, 0xB0,
+  0x2D, 0xE0,
+  0x1F, 0xD0,
+  0x0B, 0xC0,
+  0x07, 0x80,
+  0x07, 0x40,
+  0x3F, 0x00,
+  0x38, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_007A[ 28] = { /* code 007A, LATIN SMALL LETTER Z */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xE0,
+  0x6A, 0xE0,
+  0x02, 0xD0,
+  0x0B, 0x40,
+  0x2D, 0x00,
+  0x7A, 0xA0,
+  0x7F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_007B[ 28] = { /* code 007B, LEFT CURLY BRACKET */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x02, 0xF4,
+  0x03, 0xC0,
+  0x03, 0x80,
+  0x03, 0x80,
+  0x07, 0x80,
+  0x2F, 0x00,
+  0x07, 0x80,
+  0x03, 0x80,
+  0x03, 0x80,
+  0x03, 0xC0,
+  0x01, 0xF4,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_007C[ 14] = { /* code 007C, VERTICAL LINE */
+  0x00,
+  0x00,
+  0x24,
+  0x24,
+  0x24,
+  0x24,
+  0x24,
+  0x24,
+  0x24,
+  0x24,
+  0x24,
+  0x24,
+  0x24,
+  0x24
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_007D[ 28] = { /* code 007D, RIGHT CURLY BRACKET */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0x40,
+  0x07, 0x80,
+  0x03, 0x80,
+  0x03, 0x80,
+  0x03, 0xC0,
+  0x01, 0xF4,
+  0x03, 0xC0,
+  0x03, 0x80,
+  0x03, 0x80,
+  0x07, 0x80,
+  0x2F, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansCondensedBold14_AA2_007E[ 42] = { /* code 007E, TILDE */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x0F, 0x43, 0x00,
+  0x25, 0xFE, 0x00,
+  0x00, 0x14, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const aafontsCharInfo_t charTable_DejaVuSansCondensedBold14_AA2[95] = 
+{
+  {   4,   1, FontDejaVuSansCondensedBold14_AA2_0020 }, /* code 0020 */
+  {   5,   2, FontDejaVuSansCondensedBold14_AA2_0021 }, /* code 0021 */
+  {   6,   2, FontDejaVuSansCondensedBold14_AA2_0022 }, /* code 0022 */
+  {   9,   3, FontDejaVuSansCondensedBold14_AA2_0023 }, /* code 0023 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0024 }, /* code 0024 */
+  {  11,   3, FontDejaVuSansCondensedBold14_AA2_0025 }, /* code 0025 */
+  {   9,   3, FontDejaVuSansCondensedBold14_AA2_0026 }, /* code 0026 */
+  {   3,   1, FontDejaVuSansCondensedBold14_AA2_0027 }, /* code 0027 */
+  {   5,   2, FontDejaVuSansCondensedBold14_AA2_0028 }, /* code 0028 */
+  {   5,   2, FontDejaVuSansCondensedBold14_AA2_0029 }, /* code 0029 */
+  {   6,   2, FontDejaVuSansCondensedBold14_AA2_002A }, /* code 002A */
+  {   9,   3, FontDejaVuSansCondensedBold14_AA2_002B }, /* code 002B */
+  {   4,   1, FontDejaVuSansCondensedBold14_AA2_002C }, /* code 002C */
+  {   4,   1, FontDejaVuSansCondensedBold14_AA2_002D }, /* code 002D */
+  {   4,   1, FontDejaVuSansCondensedBold14_AA2_002E }, /* code 002E */
+  {   4,   1, FontDejaVuSansCondensedBold14_AA2_002F }, /* code 002F */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0030 }, /* code 0030 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0031 }, /* code 0031 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0032 }, /* code 0032 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0033 }, /* code 0033 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0034 }, /* code 0034 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0035 }, /* code 0035 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0036 }, /* code 0036 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0037 }, /* code 0037 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0038 }, /* code 0038 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0039 }, /* code 0039 */
+  {   4,   1, FontDejaVuSansCondensedBold14_AA2_003A }, /* code 003A */
+  {   4,   1, FontDejaVuSansCondensedBold14_AA2_003B }, /* code 003B */
+  {   9,   3, FontDejaVuSansCondensedBold14_AA2_003C }, /* code 003C */
+  {   9,   3, FontDejaVuSansCondensedBold14_AA2_003D }, /* code 003D */
+  {   9,   3, FontDejaVuSansCondensedBold14_AA2_003E }, /* code 003E */
+  {   6,   2, FontDejaVuSansCondensedBold14_AA2_003F }, /* code 003F */
+  {  11,   3, FontDejaVuSansCondensedBold14_AA2_0040 }, /* code 0040 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0041 }, /* code 0041 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0042 }, /* code 0042 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0043 }, /* code 0043 */
+  {   9,   3, FontDejaVuSansCondensedBold14_AA2_0044 }, /* code 0044 */
+  {   7,   2, FontDejaVuSansCondensedBold14_AA2_0045 }, /* code 0045 */
+  {   7,   2, FontDejaVuSansCondensedBold14_AA2_0046 }, /* code 0046 */
+  {   9,   3, FontDejaVuSansCondensedBold14_AA2_0047 }, /* code 0047 */
+  {   9,   3, FontDejaVuSansCondensedBold14_AA2_0048 }, /* code 0048 */
+  {   4,   1, FontDejaVuSansCondensedBold14_AA2_0049 }, /* code 0049 */
+  {   4,   1, FontDejaVuSansCondensedBold14_AA2_004A }, /* code 004A */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_004B }, /* code 004B */
+  {   7,   2, FontDejaVuSansCondensedBold14_AA2_004C }, /* code 004C */
+  {  11,   3, FontDejaVuSansCondensedBold14_AA2_004D }, /* code 004D */
+  {   9,   3, FontDejaVuSansCondensedBold14_AA2_004E }, /* code 004E */
+  {   9,   3, FontDejaVuSansCondensedBold14_AA2_004F }, /* code 004F */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0050 }, /* code 0050 */
+  {   9,   3, FontDejaVuSansCondensedBold14_AA2_0051 }, /* code 0051 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0052 }, /* code 0052 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0053 }, /* code 0053 */
+  {   7,   2, FontDejaVuSansCondensedBold14_AA2_0054 }, /* code 0054 */
+  {   9,   3, FontDejaVuSansCondensedBold14_AA2_0055 }, /* code 0055 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0056 }, /* code 0056 */
+  {  12,   3, FontDejaVuSansCondensedBold14_AA2_0057 }, /* code 0057 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0058 }, /* code 0058 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0059 }, /* code 0059 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_005A }, /* code 005A */
+  {   5,   2, FontDejaVuSansCondensedBold14_AA2_005B }, /* code 005B */
+  {   4,   1, FontDejaVuSansCondensedBold14_AA2_005C }, /* code 005C */
+  {   5,   2, FontDejaVuSansCondensedBold14_AA2_005D }, /* code 005D */
+  {   9,   3, FontDejaVuSansCondensedBold14_AA2_005E }, /* code 005E */
+  {   5,   2, FontDejaVuSansCondensedBold14_AA2_005F }, /* code 005F */
+  {   5,   2, FontDejaVuSansCondensedBold14_AA2_0060 }, /* code 0060 */
+  {   7,   2, FontDejaVuSansCondensedBold14_AA2_0061 }, /* code 0061 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0062 }, /* code 0062 */
+  {   6,   2, FontDejaVuSansCondensedBold14_AA2_0063 }, /* code 0063 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0064 }, /* code 0064 */
+  {   7,   2, FontDejaVuSansCondensedBold14_AA2_0065 }, /* code 0065 */
+  {   5,   2, FontDejaVuSansCondensedBold14_AA2_0066 }, /* code 0066 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0067 }, /* code 0067 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0068 }, /* code 0068 */
+  {   4,   1, FontDejaVuSansCondensedBold14_AA2_0069 }, /* code 0069 */
+  {   4,   1, FontDejaVuSansCondensedBold14_AA2_006A }, /* code 006A */
+  {   7,   2, FontDejaVuSansCondensedBold14_AA2_006B }, /* code 006B */
+  {   4,   1, FontDejaVuSansCondensedBold14_AA2_006C }, /* code 006C */
+  {  11,   3, FontDejaVuSansCondensedBold14_AA2_006D }, /* code 006D */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_006E }, /* code 006E */
+  {   7,   2, FontDejaVuSansCondensedBold14_AA2_006F }, /* code 006F */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0070 }, /* code 0070 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0071 }, /* code 0071 */
+  {   5,   2, FontDejaVuSansCondensedBold14_AA2_0072 }, /* code 0072 */
+  {   6,   2, FontDejaVuSansCondensedBold14_AA2_0073 }, /* code 0073 */
+  {   5,   2, FontDejaVuSansCondensedBold14_AA2_0074 }, /* code 0074 */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_0075 }, /* code 0075 */
+  {   7,   2, FontDejaVuSansCondensedBold14_AA2_0076 }, /* code 0076 */
+  {  10,   3, FontDejaVuSansCondensedBold14_AA2_0077 }, /* code 0077 */
+  {   7,   2, FontDejaVuSansCondensedBold14_AA2_0078 }, /* code 0078 */
+  {   7,   2, FontDejaVuSansCondensedBold14_AA2_0079 }, /* code 0079 */
+  {   6,   2, FontDejaVuSansCondensedBold14_AA2_007A }, /* code 007A */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_007B }, /* code 007B */
+  {   4,   1, FontDejaVuSansCondensedBold14_AA2_007C }, /* code 007C */
+  {   8,   2, FontDejaVuSansCondensedBold14_AA2_007D }, /* code 007D */
+  {   9,   3, FontDejaVuSansCondensedBold14_AA2_007E }  /* code 007E */
+};
+
+aafontsFont_t DejaVuSansCondensedBold14_AA2 = 
+{
+  AAFONTS_FONTTYPE_AA2,                         /* Font type (anti-aliasing level) */
+  14,                                           /* Font height in pixels */
+  3,                                            /* Width to insert for unknown characters */
+  9,                                            /* Height of upper-case characters */
+  7,                                            /* Height of lower-case characters */
+  11,                                           /* Font baseline */
+  0x0020,                                       /* Unicode address of first character */
+  0x007E,                                       /* Unicode address of last character */
+  &charTable_DejaVuSansCondensedBold14_AA2[0]  	    /* Font char data */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansCondensedBold14_AA2.h b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansCondensedBold14_AA2.h
new file mode 100644
index 0000000000000000000000000000000000000000..f03fc55c59abafbb0d2058a7a76fa90251000882
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansCondensedBold14_AA2.h
@@ -0,0 +1,51 @@
+/**************************************************************************/
+/*! 
+    @file     DejaVuSansCondensedBold14_AA2.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __DEJAVUSANSCONDENSEDBOLD14_AA2_H__
+#define __DEJAVUSANSCONDENSEDBOLD14_AA2_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "drivers/displays/graphic/aafonts.h"
+
+extern aafontsFont_t DejaVuSansCondensedBold14_AA2;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansMono10_AA2.c b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansMono10_AA2.c
new file mode 100644
index 0000000000000000000000000000000000000000..a1525d0456ba14c97f54b4623d262e1b22a2c873
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansMono10_AA2.c
@@ -0,0 +1,1384 @@
+/**************************************************************************/
+/*! 
+    @file     DejaVuSansMono10_AA2.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "DejaVuSansMono10_AA2.h"
+
+/* Start of unicode area <Basic Latin> */
+const uint8_t FontDejaVuSansMono10_AA2_0020[ 20] = { /* code 0020, SPACE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0021[ 20] = { /* code 0021, EXCLAMATION MARK */
+  0x00, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x04, 0x00,
+  0x00, 0x00,
+  0x08, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0022[ 20] = { /* code 0022, QUOTATION MARK */
+  0x00, 0x00,
+  0x22, 0x00,
+  0x22, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0023[ 20] = { /* code 0023, NUMBER SIGN */
+  0x00, 0x00,
+  0x04, 0x40,
+  0x05, 0x40,
+  0x7F, 0xC0,
+  0x11, 0x00,
+  0xFF, 0x80,
+  0x11, 0x00,
+  0x15, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0024[ 20] = { /* code 0024, DOLLAR SIGN */
+  0x00, 0x00,
+  0x08, 0x00,
+  0x2F, 0x80,
+  0x20, 0x00,
+  0x38, 0x00,
+  0x0B, 0x80,
+  0x01, 0x80,
+  0x3F, 0x40,
+  0x08, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0025[ 20] = { /* code 0025, PERCENT SIGN */
+  0x00, 0x00,
+  0x78, 0x00,
+  0x88, 0x00,
+  0x78, 0xC0,
+  0x0A, 0x00,
+  0x77, 0xC0,
+  0x05, 0x40,
+  0x03, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0026[ 20] = { /* code 0026, AMPERSAND */
+  0x00, 0x00,
+  0x1F, 0x00,
+  0x20, 0x00,
+  0x14, 0x00,
+  0x2C, 0x00,
+  0x52, 0x40,
+  0x51, 0xC0,
+  0x2E, 0x80,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0027[ 20] = { /* code 0027, APOSTROPHE */
+  0x00, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0028[ 20] = { /* code 0028, LEFT PARENTHESIS */
+  0x02, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0029[ 20] = { /* code 0029, RIGHT PARENTHESIS */
+  0x14, 0x00,
+  0x08, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x08, 0x00,
+  0x14, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_002A[ 20] = { /* code 002A, ASTERISK */
+  0x00, 0x00,
+  0x15, 0x80,
+  0x1E, 0x00,
+  0x1E, 0x00,
+  0x25, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_002B[ 20] = { /* code 002B, PLUS SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x7F, 0xC0,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_002C[ 20] = { /* code 002C, COMMA */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0C, 0x00,
+  0x08, 0x00,
+  0x14, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_002D[ 20] = { /* code 002D, HYPHEN-MINUS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1E, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_002E[ 20] = { /* code 002E, FULL STOP */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0C, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_002F[ 20] = { /* code 002F, SOLIDUS */
+  0x00, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x14, 0x00,
+  0x20, 0x00,
+  0x50, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0030[ 20] = { /* code 0030, DIGIT ZERO */
+  0x00, 0x00,
+  0x2E, 0x00,
+  0x22, 0x40,
+  0x51, 0x40,
+  0x59, 0x40,
+  0x51, 0x40,
+  0x22, 0x40,
+  0x2E, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0031[ 20] = { /* code 0031, DIGIT ONE */
+  0x00, 0x00,
+  0x3D, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x2F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0032[ 20] = { /* code 0032, DIGIT TWO */
+  0x00, 0x00,
+  0x2F, 0x00,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x02, 0x00,
+  0x08, 0x00,
+  0x30, 0x00,
+  0x7F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0033[ 20] = { /* code 0033, DIGIT THREE */
+  0x00, 0x00,
+  0x2E, 0x00,
+  0x51, 0x40,
+  0x01, 0x40,
+  0x1D, 0x00,
+  0x01, 0x40,
+  0x41, 0x40,
+  0x3F, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0034[ 20] = { /* code 0034, DIGIT FOUR */
+  0x00, 0x00,
+  0x06, 0x00,
+  0x0A, 0x00,
+  0x16, 0x00,
+  0x26, 0x00,
+  0x12, 0x00,
+  0x7F, 0x40,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0035[ 20] = { /* code 0035, DIGIT FIVE */
+  0x00, 0x00,
+  0x3F, 0x00,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x3F, 0x00,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x7E, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0036[ 20] = { /* code 0036, DIGIT SIX */
+  0x00, 0x00,
+  0x1F, 0x40,
+  0x30, 0x00,
+  0x50, 0x00,
+  0x6F, 0x00,
+  0x61, 0x40,
+  0x11, 0x40,
+  0x2F, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0037[ 20] = { /* code 0037, DIGIT SEVEN */
+  0x00, 0x00,
+  0xBF, 0x40,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x05, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x24, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0038[ 20] = { /* code 0038, DIGIT EIGHT */
+  0x00, 0x00,
+  0x2E, 0x00,
+  0x21, 0x40,
+  0x21, 0x40,
+  0x1D, 0x00,
+  0x61, 0x40,
+  0x51, 0x40,
+  0x3F, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0039[ 20] = { /* code 0039, DIGIT NINE */
+  0x00, 0x00,
+  0x3E, 0x00,
+  0x51, 0x40,
+  0x51, 0x40,
+  0x3F, 0x40,
+  0x01, 0x40,
+  0x03, 0x00,
+  0x7D, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_003A[ 20] = { /* code 003A, COLON */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0C, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0C, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_003B[ 20] = { /* code 003B, SEMICOLON */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0C, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0C, 0x00,
+  0x08, 0x00,
+  0x14, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_003C[ 20] = { /* code 003C, LESS-THAN SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x01, 0xC0,
+  0x3E, 0x00,
+  0x78, 0x00,
+  0x03, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_003D[ 20] = { /* code 003D, EQUALS SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xBF, 0xC0,
+  0x00, 0x00,
+  0xBF, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_003E[ 20] = { /* code 003E, GREATER-THAN SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x60, 0x00,
+  0x0F, 0x80,
+  0x07, 0xC0,
+  0x78, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_003F[ 20] = { /* code 003F, QUESTION MARK */
+  0x00, 0x00,
+  0x3F, 0x00,
+  0x01, 0x40,
+  0x03, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x00, 0x00,
+  0x04, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0040[ 20] = { /* code 0040, COMMERCIAL AT */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0x40,
+  0x30, 0x80,
+  0x57, 0xC0,
+  0x58, 0x80,
+  0x57, 0xC0,
+  0x30, 0x00,
+  0x0F, 0x40,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0041[ 20] = { /* code 0041, LATIN CAPITAL LETTER A */
+  0x00, 0x00,
+  0x0A, 0x00,
+  0x0A, 0x00,
+  0x09, 0x40,
+  0x14, 0x80,
+  0x20, 0x80,
+  0x3F, 0xC0,
+  0x50, 0x40,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0042[ 20] = { /* code 0042, LATIN CAPITAL LETTER B */
+  0x00, 0x00,
+  0x7E, 0x00,
+  0x52, 0x00,
+  0x52, 0x00,
+  0x7D, 0x00,
+  0x52, 0x40,
+  0x51, 0x40,
+  0x7F, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0043[ 20] = { /* code 0043, LATIN CAPITAL LETTER C */
+  0x00, 0x00,
+  0x1F, 0x40,
+  0x20, 0x00,
+  0x50, 0x00,
+  0x50, 0x00,
+  0x50, 0x00,
+  0x20, 0x00,
+  0x1F, 0x40,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0044[ 20] = { /* code 0044, LATIN CAPITAL LETTER D */
+  0x00, 0x00,
+  0x7D, 0x00,
+  0x52, 0x00,
+  0x51, 0x40,
+  0x51, 0x40,
+  0x51, 0x40,
+  0x52, 0x00,
+  0x7D, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0045[ 20] = { /* code 0045, LATIN CAPITAL LETTER E */
+  0x00, 0x00,
+  0x7F, 0x40,
+  0x50, 0x00,
+  0x50, 0x00,
+  0x7F, 0x40,
+  0x50, 0x00,
+  0x50, 0x00,
+  0x7F, 0x40,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0046[ 20] = { /* code 0046, LATIN CAPITAL LETTER F */
+  0x00, 0x00,
+  0xBF, 0x40,
+  0x80, 0x00,
+  0x80, 0x00,
+  0xBF, 0x00,
+  0x80, 0x00,
+  0x80, 0x00,
+  0x80, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0047[ 20] = { /* code 0047, LATIN CAPITAL LETTER G */
+  0x00, 0x00,
+  0x1F, 0x40,
+  0x20, 0x00,
+  0x50, 0x00,
+  0x57, 0x40,
+  0x51, 0x40,
+  0x21, 0x40,
+  0x1F, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0048[ 20] = { /* code 0048, LATIN CAPITAL LETTER H */
+  0x00, 0x00,
+  0x41, 0x40,
+  0x41, 0x40,
+  0x41, 0x40,
+  0x7F, 0x40,
+  0x41, 0x40,
+  0x41, 0x40,
+  0x41, 0x40,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0049[ 20] = { /* code 0049, LATIN CAPITAL LETTER I */
+  0x00, 0x00,
+  0x3F, 0x40,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x3F, 0x40,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_004A[ 20] = { /* code 004A, LATIN CAPITAL LETTER J */
+  0x00, 0x00,
+  0x1F, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x02, 0x00,
+  0x7E, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_004B[ 20] = { /* code 004B, LATIN CAPITAL LETTER K */
+  0x00, 0x00,
+  0x41, 0x80,
+  0x46, 0x00,
+  0x58, 0x00,
+  0x78, 0x00,
+  0x45, 0x00,
+  0x42, 0x00,
+  0x41, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_004C[ 20] = { /* code 004C, LATIN CAPITAL LETTER L */
+  0x00, 0x00,
+  0x40, 0x00,
+  0x40, 0x00,
+  0x40, 0x00,
+  0x40, 0x00,
+  0x40, 0x00,
+  0x40, 0x00,
+  0x7F, 0x40,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_004D[ 20] = { /* code 004D, LATIN CAPITAL LETTER M */
+  0x00, 0x00,
+  0x60, 0xC0,
+  0x61, 0xC0,
+  0x55, 0x80,
+  0x55, 0x80,
+  0x59, 0x80,
+  0x50, 0x80,
+  0x50, 0x80,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_004E[ 20] = { /* code 004E, LATIN CAPITAL LETTER N */
+  0x00, 0x00,
+  0x61, 0x40,
+  0x71, 0x40,
+  0x55, 0x40,
+  0x55, 0x40,
+  0x55, 0x40,
+  0x53, 0x40,
+  0x52, 0x40,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_004F[ 20] = { /* code 004F, LATIN CAPITAL LETTER O */
+  0x00, 0x00,
+  0x2E, 0x00,
+  0x62, 0x40,
+  0x51, 0x40,
+  0x51, 0x40,
+  0x51, 0x40,
+  0x62, 0x40,
+  0x2E, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0050[ 20] = { /* code 0050, LATIN CAPITAL LETTER P */
+  0x00, 0x00,
+  0x7F, 0x00,
+  0x51, 0x40,
+  0x51, 0x40,
+  0x7F, 0x00,
+  0x50, 0x00,
+  0x50, 0x00,
+  0x50, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0051[ 20] = { /* code 0051, LATIN CAPITAL LETTER Q */
+  0x00, 0x00,
+  0x2E, 0x00,
+  0x62, 0x40,
+  0x51, 0x40,
+  0x51, 0x40,
+  0x51, 0x40,
+  0x62, 0x40,
+  0x2E, 0x00,
+  0x02, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0052[ 20] = { /* code 0052, LATIN CAPITAL LETTER R */
+  0x00, 0x00,
+  0x7F, 0x00,
+  0x51, 0x40,
+  0x51, 0x40,
+  0x7D, 0x00,
+  0x52, 0x00,
+  0x51, 0x40,
+  0x50, 0x80,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0053[ 20] = { /* code 0053, LATIN CAPITAL LETTER S */
+  0x00, 0x00,
+  0x2F, 0x00,
+  0x50, 0x40,
+  0x50, 0x00,
+  0x1F, 0x00,
+  0x01, 0x40,
+  0x41, 0x40,
+  0x2F, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0054[ 20] = { /* code 0054, LATIN CAPITAL LETTER T */
+  0x00, 0x00,
+  0xBF, 0xC0,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0055[ 20] = { /* code 0055, LATIN CAPITAL LETTER U */
+  0x00, 0x00,
+  0x51, 0x40,
+  0x51, 0x40,
+  0x51, 0x40,
+  0x51, 0x40,
+  0x51, 0x40,
+  0x51, 0x40,
+  0x2E, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0056[ 20] = { /* code 0056, LATIN CAPITAL LETTER V */
+  0x00, 0x00,
+  0x50, 0x80,
+  0x20, 0x80,
+  0x20, 0x80,
+  0x15, 0x40,
+  0x16, 0x00,
+  0x0A, 0x00,
+  0x0A, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0057[ 20] = { /* code 0057, LATIN CAPITAL LETTER W */
+  0x00, 0x00,
+  0x80, 0x40,
+  0x80, 0x80,
+  0x89, 0x80,
+  0x59, 0x80,
+  0x66, 0x80,
+  0x31, 0x80,
+  0x31, 0x40,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0058[ 20] = { /* code 0058, LATIN CAPITAL LETTER X */
+  0x00, 0x00,
+  0x20, 0x80,
+  0x14, 0x80,
+  0x0A, 0x00,
+  0x06, 0x00,
+  0x0A, 0x40,
+  0x20, 0x80,
+  0x60, 0x40,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0059[ 20] = { /* code 0059, LATIN CAPITAL LETTER Y */
+  0x00, 0x00,
+  0x90, 0x80,
+  0x21, 0x40,
+  0x16, 0x00,
+  0x0D, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_005A[ 20] = { /* code 005A, LATIN CAPITAL LETTER Z */
+  0x00, 0x00,
+  0x7F, 0x40,
+  0x02, 0x00,
+  0x05, 0x00,
+  0x08, 0x00,
+  0x14, 0x00,
+  0x20, 0x00,
+  0x7F, 0x40,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_005B[ 20] = { /* code 005B, LEFT SQUARE BRACKET */
+  0x0F, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x0F, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_005C[ 20] = { /* code 005C, REVERSE SOLIDUS */
+  0x00, 0x00,
+  0x50, 0x00,
+  0x20, 0x00,
+  0x14, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_005D[ 20] = { /* code 005D, RIGHT SQUARE BRACKET */
+  0x1D, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x1D, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_005E[ 20] = { /* code 005E, CIRCUMFLEX ACCENT */
+  0x00, 0x00,
+  0x0E, 0x00,
+  0x61, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_005F[ 20] = { /* code 005F, LOW LINE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xFF, 0xC0
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0060[ 20] = { /* code 0060, GRAVE ACCENT */
+  0x24, 0x00,
+  0x08, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0061[ 20] = { /* code 0061, LATIN SMALL LETTER A */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0x00,
+  0x00, 0x40,
+  0x3F, 0x80,
+  0x51, 0x80,
+  0x3F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0062[ 20] = { /* code 0062, LATIN SMALL LETTER B */
+  0x50, 0x00,
+  0x50, 0x00,
+  0x50, 0x00,
+  0x7F, 0x00,
+  0x61, 0x40,
+  0x50, 0x80,
+  0x61, 0x40,
+  0x7F, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0063[ 20] = { /* code 0063, LATIN SMALL LETTER C */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0x40,
+  0x20, 0x00,
+  0x50, 0x00,
+  0x20, 0x00,
+  0x1F, 0x40,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0064[ 20] = { /* code 0064, LATIN SMALL LETTER D */
+  0x00, 0x80,
+  0x00, 0x80,
+  0x00, 0x80,
+  0x2E, 0x80,
+  0x61, 0x80,
+  0x50, 0x80,
+  0x61, 0x80,
+  0x2F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0065[ 20] = { /* code 0065, LATIN SMALL LETTER E */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0x00,
+  0x21, 0x40,
+  0x7F, 0x80,
+  0x20, 0x00,
+  0x2F, 0x40,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0066[ 20] = { /* code 0066, LATIN SMALL LETTER F */
+  0x07, 0x80,
+  0x04, 0x00,
+  0x08, 0x00,
+  0x3F, 0x80,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0067[ 20] = { /* code 0067, LATIN SMALL LETTER G */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2E, 0x80,
+  0x61, 0x80,
+  0x50, 0x80,
+  0x61, 0x80,
+  0x2F, 0x80,
+  0x01, 0x40,
+  0x2F, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0068[ 20] = { /* code 0068, LATIN SMALL LETTER H */
+  0x50, 0x00,
+  0x50, 0x00,
+  0x50, 0x00,
+  0x6F, 0x00,
+  0x61, 0x40,
+  0x50, 0x80,
+  0x50, 0x80,
+  0x50, 0x80,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0069[ 20] = { /* code 0069, LATIN SMALL LETTER I */
+  0x08, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2C, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x7F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_006A[ 20] = { /* code 006A, LATIN SMALL LETTER J */
+  0x05, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2D, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x3C, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_006B[ 20] = { /* code 006B, LATIN SMALL LETTER K */
+  0x50, 0x00,
+  0x50, 0x00,
+  0x50, 0x00,
+  0x53, 0x00,
+  0x5C, 0x00,
+  0x78, 0x00,
+  0x55, 0x00,
+  0x52, 0x40,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_006C[ 20] = { /* code 006C, LATIN SMALL LETTER L */
+  0xB8, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x07, 0x40,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_006D[ 20] = { /* code 006D, LATIN SMALL LETTER M */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7E, 0xC0,
+  0x55, 0x80,
+  0x55, 0x80,
+  0x55, 0x80,
+  0x55, 0x80,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_006E[ 20] = { /* code 006E, LATIN SMALL LETTER N */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x6F, 0x00,
+  0x61, 0x40,
+  0x50, 0x80,
+  0x50, 0x80,
+  0x50, 0x80,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_006F[ 20] = { /* code 006F, LATIN SMALL LETTER O */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0x00,
+  0x61, 0x40,
+  0x50, 0x80,
+  0x61, 0x40,
+  0x2F, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0070[ 20] = { /* code 0070, LATIN SMALL LETTER P */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0x00,
+  0x61, 0x40,
+  0x50, 0x80,
+  0x61, 0x40,
+  0x7F, 0x00,
+  0x50, 0x00,
+  0x50, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0071[ 20] = { /* code 0071, LATIN SMALL LETTER Q */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2E, 0x80,
+  0x61, 0x80,
+  0x50, 0x80,
+  0x61, 0x80,
+  0x2F, 0x80,
+  0x00, 0x80,
+  0x00, 0x80
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0072[ 20] = { /* code 0072, LATIN SMALL LETTER R */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1B, 0xC0,
+  0x18, 0x00,
+  0x14, 0x00,
+  0x14, 0x00,
+  0x14, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0073[ 20] = { /* code 0073, LATIN SMALL LETTER S */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0x80,
+  0x50, 0x00,
+  0x2F, 0x00,
+  0x00, 0x80,
+  0x7F, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0074[ 20] = { /* code 0074, LATIN SMALL LETTER T */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x08, 0x00,
+  0x7F, 0x40,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x0B, 0x40,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0075[ 20] = { /* code 0075, LATIN SMALL LETTER U */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x50, 0x80,
+  0x50, 0x80,
+  0x50, 0x80,
+  0x51, 0x80,
+  0x3E, 0x80,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0076[ 20] = { /* code 0076, LATIN SMALL LETTER V */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x21, 0x40,
+  0x12, 0x00,
+  0x26, 0x00,
+  0x1D, 0x00,
+  0x0C, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0077[ 20] = { /* code 0077, LATIN SMALL LETTER W */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x80, 0x40,
+  0x88, 0x80,
+  0x59, 0x40,
+  0x26, 0x80,
+  0x22, 0x40,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0078[ 20] = { /* code 0078, LATIN SMALL LETTER X */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x20, 0xC0,
+  0x0A, 0x00,
+  0x05, 0x00,
+  0x1A, 0x40,
+  0x20, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_0079[ 20] = { /* code 0079, LATIN SMALL LETTER Y */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x21, 0x40,
+  0x22, 0x00,
+  0x16, 0x00,
+  0x0D, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x34, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_007A[ 20] = { /* code 007A, LATIN SMALL LETTER Z */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0x80,
+  0x02, 0x00,
+  0x08, 0x00,
+  0x24, 0x00,
+  0x7F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_007B[ 20] = { /* code 007B, LEFT CURLY BRACKET */
+  0x07, 0x40,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x34, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x07, 0x40,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_007C[ 20] = { /* code 007C, VERTICAL LINE */
+  0x04, 0x00,
+  0x04, 0x00,
+  0x04, 0x00,
+  0x04, 0x00,
+  0x04, 0x00,
+  0x04, 0x00,
+  0x04, 0x00,
+  0x04, 0x00,
+  0x04, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_007D[ 20] = { /* code 007D, RIGHT CURLY BRACKET */
+  0x38, 0x00,
+  0x08, 0x00,
+  0x04, 0x00,
+  0x03, 0x40,
+  0x09, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x38, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono10_AA2_007E[ 20] = { /* code 007E, TILDE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3C, 0x00,
+  0x03, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const aafontsCharInfo_t charTable_DejaVuSansMono10_AA2[95] = 
+{
+  {   5,   2, FontDejaVuSansMono10_AA2_0020 }, /* code 0020 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0021 }, /* code 0021 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0022 }, /* code 0022 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0023 }, /* code 0023 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0024 }, /* code 0024 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0025 }, /* code 0025 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0026 }, /* code 0026 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0027 }, /* code 0027 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0028 }, /* code 0028 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0029 }, /* code 0029 */
+  {   5,   2, FontDejaVuSansMono10_AA2_002A }, /* code 002A */
+  {   5,   2, FontDejaVuSansMono10_AA2_002B }, /* code 002B */
+  {   5,   2, FontDejaVuSansMono10_AA2_002C }, /* code 002C */
+  {   5,   2, FontDejaVuSansMono10_AA2_002D }, /* code 002D */
+  {   5,   2, FontDejaVuSansMono10_AA2_002E }, /* code 002E */
+  {   5,   2, FontDejaVuSansMono10_AA2_002F }, /* code 002F */
+  {   5,   2, FontDejaVuSansMono10_AA2_0030 }, /* code 0030 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0031 }, /* code 0031 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0032 }, /* code 0032 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0033 }, /* code 0033 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0034 }, /* code 0034 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0035 }, /* code 0035 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0036 }, /* code 0036 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0037 }, /* code 0037 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0038 }, /* code 0038 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0039 }, /* code 0039 */
+  {   5,   2, FontDejaVuSansMono10_AA2_003A }, /* code 003A */
+  {   5,   2, FontDejaVuSansMono10_AA2_003B }, /* code 003B */
+  {   5,   2, FontDejaVuSansMono10_AA2_003C }, /* code 003C */
+  {   5,   2, FontDejaVuSansMono10_AA2_003D }, /* code 003D */
+  {   5,   2, FontDejaVuSansMono10_AA2_003E }, /* code 003E */
+  {   5,   2, FontDejaVuSansMono10_AA2_003F }, /* code 003F */
+  {   5,   2, FontDejaVuSansMono10_AA2_0040 }, /* code 0040 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0041 }, /* code 0041 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0042 }, /* code 0042 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0043 }, /* code 0043 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0044 }, /* code 0044 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0045 }, /* code 0045 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0046 }, /* code 0046 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0047 }, /* code 0047 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0048 }, /* code 0048 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0049 }, /* code 0049 */
+  {   5,   2, FontDejaVuSansMono10_AA2_004A }, /* code 004A */
+  {   5,   2, FontDejaVuSansMono10_AA2_004B }, /* code 004B */
+  {   5,   2, FontDejaVuSansMono10_AA2_004C }, /* code 004C */
+  {   5,   2, FontDejaVuSansMono10_AA2_004D }, /* code 004D */
+  {   5,   2, FontDejaVuSansMono10_AA2_004E }, /* code 004E */
+  {   5,   2, FontDejaVuSansMono10_AA2_004F }, /* code 004F */
+  {   5,   2, FontDejaVuSansMono10_AA2_0050 }, /* code 0050 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0051 }, /* code 0051 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0052 }, /* code 0052 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0053 }, /* code 0053 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0054 }, /* code 0054 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0055 }, /* code 0055 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0056 }, /* code 0056 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0057 }, /* code 0057 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0058 }, /* code 0058 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0059 }, /* code 0059 */
+  {   5,   2, FontDejaVuSansMono10_AA2_005A }, /* code 005A */
+  {   5,   2, FontDejaVuSansMono10_AA2_005B }, /* code 005B */
+  {   5,   2, FontDejaVuSansMono10_AA2_005C }, /* code 005C */
+  {   5,   2, FontDejaVuSansMono10_AA2_005D }, /* code 005D */
+  {   5,   2, FontDejaVuSansMono10_AA2_005E }, /* code 005E */
+  {   5,   2, FontDejaVuSansMono10_AA2_005F }, /* code 005F */
+  {   5,   2, FontDejaVuSansMono10_AA2_0060 }, /* code 0060 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0061 }, /* code 0061 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0062 }, /* code 0062 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0063 }, /* code 0063 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0064 }, /* code 0064 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0065 }, /* code 0065 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0066 }, /* code 0066 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0067 }, /* code 0067 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0068 }, /* code 0068 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0069 }, /* code 0069 */
+  {   5,   2, FontDejaVuSansMono10_AA2_006A }, /* code 006A */
+  {   5,   2, FontDejaVuSansMono10_AA2_006B }, /* code 006B */
+  {   5,   2, FontDejaVuSansMono10_AA2_006C }, /* code 006C */
+  {   5,   2, FontDejaVuSansMono10_AA2_006D }, /* code 006D */
+  {   5,   2, FontDejaVuSansMono10_AA2_006E }, /* code 006E */
+  {   5,   2, FontDejaVuSansMono10_AA2_006F }, /* code 006F */
+  {   5,   2, FontDejaVuSansMono10_AA2_0070 }, /* code 0070 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0071 }, /* code 0071 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0072 }, /* code 0072 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0073 }, /* code 0073 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0074 }, /* code 0074 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0075 }, /* code 0075 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0076 }, /* code 0076 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0077 }, /* code 0077 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0078 }, /* code 0078 */
+  {   5,   2, FontDejaVuSansMono10_AA2_0079 }, /* code 0079 */
+  {   5,   2, FontDejaVuSansMono10_AA2_007A }, /* code 007A */
+  {   5,   2, FontDejaVuSansMono10_AA2_007B }, /* code 007B */
+  {   5,   2, FontDejaVuSansMono10_AA2_007C }, /* code 007C */
+  {   5,   2, FontDejaVuSansMono10_AA2_007D }, /* code 007D */
+  {   5,   2, FontDejaVuSansMono10_AA2_007E }  /* code 007E */
+};
+
+aafontsFont_t DejaVuSansMono10_AA2 = 
+{
+  AAFONTS_FONTTYPE_AA2,                         /* Font type (anti-aliasing level) */
+  10,                                           /* Font height in pixels */
+  5,                                            /* Width to insert for unknown characters */
+  7,                                            /* Height of upper-case characters */
+  5,                                            /* Height of lower-case characters */
+  8,                                            /* Font baseline */
+  0x0020,                                       /* Unicode address of first character */
+  0x007E,                                       /* Unicode address of last character */
+  &charTable_DejaVuSansMono10_AA2[0]  	    /* Font char data */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansMono10_AA2.h b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansMono10_AA2.h
new file mode 100644
index 0000000000000000000000000000000000000000..d5b04677393405f141a8561d31e385d67ea10bac
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansMono10_AA2.h
@@ -0,0 +1,52 @@
+/**************************************************************************/
+/*! 
+    @file     DejaVuSansMono10_AA2.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __DejaVuSansMono10_AA2_H__
+#define __DejaVuSansMono10_AA2_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "drivers/displays/graphic/aafonts.h"
+
+extern aafontsFont_t DejaVuSansMono10_AA2;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansMono13_AA2.c b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansMono13_AA2.c
new file mode 100644
index 0000000000000000000000000000000000000000..dae81636572d876571a08bb2089a38b9f41afdaf
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansMono13_AA2.c
@@ -0,0 +1,1669 @@
+/**************************************************************************/
+/*! 
+    @file     DejaVuSansMono13_AA2.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "DejaVuSansMono13_AA2.h"
+
+/* Start of unicode area <Basic Latin> */
+const uint8_t FontDejaVuSansMono13_AA2_0020[ 26] = { /* code 0020, SPACE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0021[ 26] = { /* code 0021, EXCLAMATION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0022[ 26] = { /* code 0022, QUOTATION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x08, 0x80,
+  0x08, 0x80,
+  0x08, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0023[ 26] = { /* code 0023, NUMBER SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x05, 0x20,
+  0x09, 0x50,
+  0x7F, 0xF8,
+  0x08, 0x80,
+  0x14, 0x80,
+  0xFF, 0xF0,
+  0x21, 0x40,
+  0x22, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0024[ 26] = { /* code 0024, DOLLAR SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x01, 0x00,
+  0x1F, 0xF0,
+  0x31, 0x00,
+  0x31, 0x00,
+  0x0F, 0xC0,
+  0x01, 0x20,
+  0x01, 0x20,
+  0x3F, 0xC0,
+  0x01, 0x00,
+  0x01, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0025[ 26] = { /* code 0025, PERCENT SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7C, 0x00,
+  0x86, 0x00,
+  0x7C, 0x20,
+  0x01, 0xC0,
+  0x09, 0x00,
+  0x71, 0xF0,
+  0x02, 0x14,
+  0x01, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0026[ 26] = { /* code 0026, AMPERSAND */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xC0,
+  0x14, 0x00,
+  0x18, 0x00,
+  0x1D, 0x00,
+  0x63, 0x24,
+  0x51, 0xA0,
+  0x70, 0x90,
+  0x1F, 0xB4,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0027[ 26] = { /* code 0027, APOSTROPHE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0028[ 26] = { /* code 0028, LEFT PARENTHESIS */
+  0x00, 0x00,
+  0x01, 0x80,
+  0x02, 0x00,
+  0x06, 0x00,
+  0x05, 0x00,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x05, 0x00,
+  0x06, 0x00,
+  0x02, 0x00,
+  0x01, 0x80,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0029[ 26] = { /* code 0029, RIGHT PARENTHESIS */
+  0x00, 0x00,
+  0x08, 0x00,
+  0x05, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x05, 0x00,
+  0x08, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_002A[ 26] = { /* code 002A, ASTERISK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x01, 0x00,
+  0x21, 0x20,
+  0x0F, 0x80,
+  0x0F, 0x40,
+  0x21, 0x60,
+  0x01, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_002B[ 26] = { /* code 002B, PLUS SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x7F, 0xF4,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_002C[ 26] = { /* code 002C, COMMA */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0x40,
+  0x07, 0x00,
+  0x05, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_002D[ 26] = { /* code 002D, HYPHEN-MINUS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_002E[ 26] = { /* code 002E, FULL STOP */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_002F[ 26] = { /* code 002F, SOLIDUS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x30,
+  0x00, 0x90,
+  0x00, 0x80,
+  0x02, 0x40,
+  0x02, 0x00,
+  0x09, 0x00,
+  0x08, 0x00,
+  0x24, 0x00,
+  0x20, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0030[ 26] = { /* code 0030, DIGIT ZERO */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0x80,
+  0x20, 0x90,
+  0x24, 0x60,
+  0x29, 0x60,
+  0x22, 0x60,
+  0x20, 0xA0,
+  0x20, 0x90,
+  0x0F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0031[ 26] = { /* code 0031, DIGIT ONE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x1F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0032[ 26] = { /* code 0032, DIGIT TWO */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0x80,
+  0x50, 0x90,
+  0x00, 0x50,
+  0x00, 0x80,
+  0x02, 0x40,
+  0x09, 0x00,
+  0x24, 0x00,
+  0x7F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0033[ 26] = { /* code 0033, DIGIT THREE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0x80,
+  0x10, 0x90,
+  0x00, 0x90,
+  0x0F, 0x40,
+  0x00, 0x90,
+  0x00, 0x60,
+  0x50, 0xA0,
+  0x2F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0034[ 26] = { /* code 0034, DIGIT FOUR */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0xE0,
+  0x02, 0x60,
+  0x05, 0x60,
+  0x18, 0x60,
+  0x20, 0x60,
+  0x7F, 0xF8,
+  0x00, 0x60,
+  0x00, 0x60,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0035[ 26] = { /* code 0035, DIGIT FIVE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xC0,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x3F, 0x80,
+  0x00, 0x90,
+  0x00, 0x60,
+  0x00, 0x90,
+  0x7F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0036[ 26] = { /* code 0036, DIGIT SIX */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xE0,
+  0x28, 0x00,
+  0x30, 0x00,
+  0x6B, 0xC0,
+  0x70, 0x60,
+  0x20, 0x20,
+  0x20, 0x60,
+  0x0F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0037[ 26] = { /* code 0037, DIGIT SEVEN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xF0,
+  0x00, 0x50,
+  0x00, 0x80,
+  0x01, 0x80,
+  0x02, 0x40,
+  0x03, 0x00,
+  0x06, 0x00,
+  0x09, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0038[ 26] = { /* code 0038, DIGIT EIGHT */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xC0,
+  0x30, 0x60,
+  0x20, 0x60,
+  0x0F, 0x80,
+  0x20, 0x60,
+  0x60, 0x20,
+  0x30, 0x60,
+  0x1F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0039[ 26] = { /* code 0039, DIGIT NINE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0x80,
+  0x30, 0x50,
+  0x60, 0x20,
+  0x30, 0x60,
+  0x1F, 0xA0,
+  0x00, 0x60,
+  0x00, 0xD0,
+  0x7F, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_003A[ 26] = { /* code 003A, COLON */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_003B[ 26] = { /* code 003B, SEMICOLON */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0x40,
+  0x07, 0x00,
+  0x05, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_003C[ 26] = { /* code 003C, LESS-THAN SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x30,
+  0x0F, 0x80,
+  0x70, 0x00,
+  0x0F, 0x40,
+  0x00, 0x70,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_003D[ 26] = { /* code 003D, EQUALS SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xF0,
+  0x00, 0x00,
+  0x7F, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_003E[ 26] = { /* code 003E, GREATER-THAN SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x60, 0x00,
+  0x0F, 0x80,
+  0x00, 0x70,
+  0x0B, 0x80,
+  0x70, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_003F[ 26] = { /* code 003F, QUESTION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xD0,
+  0x00, 0x20,
+  0x00, 0x90,
+  0x02, 0x80,
+  0x03, 0x00,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0040[ 26] = { /* code 0040, COMMERCIAL AT */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xE0,
+  0x18, 0x24,
+  0x30, 0x18,
+  0x62, 0xF8,
+  0x52, 0x18,
+  0x52, 0x18,
+  0x62, 0xF8,
+  0x20, 0x00,
+  0x1C, 0x00,
+  0x07, 0xE0,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0041[ 26] = { /* code 0041, LATIN CAPITAL LETTER A */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0x40,
+  0x06, 0x40,
+  0x09, 0x80,
+  0x08, 0x80,
+  0x18, 0x90,
+  0x2F, 0xE0,
+  0x20, 0x20,
+  0x60, 0x24,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0042[ 26] = { /* code 0042, LATIN CAPITAL LETTER B */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xC0,
+  0x60, 0x50,
+  0x60, 0x50,
+  0x7F, 0x40,
+  0x60, 0x60,
+  0x60, 0x20,
+  0x60, 0x60,
+  0x7F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0043[ 26] = { /* code 0043, LATIN CAPITAL LETTER C */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xC0,
+  0x24, 0x10,
+  0x20, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x20, 0x00,
+  0x24, 0x10,
+  0x0F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0044[ 26] = { /* code 0044, LATIN CAPITAL LETTER D */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0x40,
+  0x60, 0x90,
+  0x60, 0x60,
+  0x60, 0x20,
+  0x60, 0x20,
+  0x60, 0x60,
+  0x60, 0xD0,
+  0x7F, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0045[ 26] = { /* code 0045, LATIN CAPITAL LETTER E */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xD0,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x7F, 0xD0,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x7F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0046[ 26] = { /* code 0046, LATIN CAPITAL LETTER F */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xD0,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x3F, 0xC0,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0047[ 26] = { /* code 0047, LATIN CAPITAL LETTER G */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xE0,
+  0x24, 0x14,
+  0x20, 0x00,
+  0x60, 0x00,
+  0x60, 0x78,
+  0x20, 0x18,
+  0x24, 0x18,
+  0x0B, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0048[ 26] = { /* code 0048, LATIN CAPITAL LETTER H */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x20, 0x20,
+  0x20, 0x20,
+  0x20, 0x20,
+  0x3F, 0xE0,
+  0x20, 0x20,
+  0x20, 0x20,
+  0x20, 0x20,
+  0x20, 0x20,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0049[ 26] = { /* code 0049, LATIN CAPITAL LETTER I */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xD0,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x3F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_004A[ 26] = { /* code 004A, LATIN CAPITAL LETTER J */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xC0,
+  0x00, 0x80,
+  0x00, 0x80,
+  0x00, 0x80,
+  0x00, 0x80,
+  0x00, 0x80,
+  0x00, 0x80,
+  0x2F, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_004B[ 26] = { /* code 004B, LATIN CAPITAL LETTER K */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x60, 0x70,
+  0x61, 0x80,
+  0x67, 0x00,
+  0x7D, 0x00,
+  0x77, 0x00,
+  0x61, 0x80,
+  0x60, 0x90,
+  0x60, 0x34,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_004C[ 26] = { /* code 004C, LATIN CAPITAL LETTER L */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x7F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_004D[ 26] = { /* code 004D, LATIN CAPITAL LETTER M */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x74, 0x38,
+  0x78, 0x68,
+  0x64, 0x98,
+  0x66, 0x98,
+  0x63, 0x18,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_004E[ 26] = { /* code 004E, LATIN CAPITAL LETTER N */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x70, 0x60,
+  0x78, 0x60,
+  0x68, 0x60,
+  0x65, 0x60,
+  0x62, 0x60,
+  0x62, 0xA0,
+  0x60, 0xE0,
+  0x60, 0xA0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_004F[ 26] = { /* code 004F, LATIN CAPITAL LETTER O */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0x80,
+  0x30, 0x60,
+  0x60, 0x20,
+  0x60, 0x20,
+  0x60, 0x20,
+  0x60, 0x20,
+  0x30, 0x60,
+  0x1F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0050[ 26] = { /* code 0050, LATIN CAPITAL LETTER P */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0x80,
+  0x60, 0x90,
+  0x60, 0x60,
+  0x60, 0x90,
+  0x7F, 0x80,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0051[ 26] = { /* code 0051, LATIN CAPITAL LETTER Q */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0x80,
+  0x30, 0x60,
+  0x60, 0x20,
+  0x60, 0x20,
+  0x60, 0x20,
+  0x60, 0x20,
+  0x30, 0x60,
+  0x1F, 0xC0,
+  0x00, 0x90,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0052[ 26] = { /* code 0052, LATIN CAPITAL LETTER R */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0x80,
+  0x60, 0x90,
+  0x60, 0x60,
+  0x60, 0x90,
+  0x7F, 0x40,
+  0x60, 0xC0,
+  0x60, 0x60,
+  0x60, 0x34,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0053[ 26] = { /* code 0053, LATIN CAPITAL LETTER S */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xC0,
+  0x30, 0x20,
+  0x60, 0x00,
+  0x3F, 0x00,
+  0x01, 0xD0,
+  0x00, 0x60,
+  0x50, 0x60,
+  0x2F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0054[ 26] = { /* code 0054, LATIN CAPITAL LETTER T */
+  0x00, 0x00,
+  0x00, 0x00,
+  0xBF, 0xF4,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0055[ 26] = { /* code 0055, LATIN CAPITAL LETTER U */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x60, 0x60,
+  0x60, 0x60,
+  0x60, 0x60,
+  0x60, 0x60,
+  0x60, 0x60,
+  0x60, 0x60,
+  0x20, 0x50,
+  0x1F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0056[ 26] = { /* code 0056, LATIN CAPITAL LETTER V */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x20, 0x24,
+  0x30, 0x20,
+  0x24, 0x20,
+  0x18, 0x60,
+  0x08, 0x90,
+  0x09, 0x80,
+  0x06, 0x80,
+  0x03, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0057[ 26] = { /* code 0057, LATIN CAPITAL LETTER W */
+  0x00, 0x00,
+  0x00, 0x00,
+  0xC0, 0x14,
+  0x90, 0x24,
+  0x97, 0x20,
+  0x57, 0x20,
+  0x69, 0x60,
+  0x28, 0xE0,
+  0x34, 0xE0,
+  0x24, 0x90,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0058[ 26] = { /* code 0058, LATIN CAPITAL LETTER X */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x34, 0x34,
+  0x18, 0x50,
+  0x09, 0x80,
+  0x03, 0x40,
+  0x07, 0x40,
+  0x0C, 0x80,
+  0x18, 0x60,
+  0x30, 0x24,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0059[ 26] = { /* code 0059, LATIN CAPITAL LETTER Y */
+  0x00, 0x00,
+  0x00, 0x00,
+  0xA0, 0x30,
+  0x30, 0x90,
+  0x18, 0x80,
+  0x0B, 0x40,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_005A[ 26] = { /* code 005A, LATIN CAPITAL LETTER Z */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xF4,
+  0x00, 0x30,
+  0x00, 0xC0,
+  0x02, 0x40,
+  0x06, 0x00,
+  0x0C, 0x00,
+  0x20, 0x00,
+  0x7F, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_005B[ 26] = { /* code 005B, LEFT SQUARE BRACKET */
+  0x00, 0x00,
+  0x07, 0x80,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x07, 0x80,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_005C[ 26] = { /* code 005C, REVERSE SOLIDUS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x20, 0x00,
+  0x24, 0x00,
+  0x08, 0x00,
+  0x09, 0x00,
+  0x02, 0x00,
+  0x02, 0x40,
+  0x00, 0x80,
+  0x00, 0x90,
+  0x00, 0x30,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_005D[ 26] = { /* code 005D, RIGHT SQUARE BRACKET */
+  0x00, 0x00,
+  0x0F, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x0F, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_005E[ 26] = { /* code 005E, CIRCUMFLEX ACCENT */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0x00,
+  0x18, 0xC0,
+  0x60, 0x30,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_005F[ 26] = { /* code 005F, LOW LINE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xFF, 0xF8
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0060[ 26] = { /* code 0060, GRAVE ACCENT */
+  0x00, 0x00,
+  0x1C, 0x00,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0061[ 26] = { /* code 0061, LATIN SMALL LETTER A */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0xC0,
+  0x00, 0x60,
+  0x1F, 0xE0,
+  0x20, 0x60,
+  0x20, 0xA0,
+  0x2F, 0xA0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0062[ 26] = { /* code 0062, LATIN SMALL LETTER B */
+  0x00, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x7F, 0x80,
+  0x70, 0x90,
+  0x60, 0x60,
+  0x60, 0x60,
+  0x70, 0x90,
+  0x7F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0063[ 26] = { /* code 0063, LATIN SMALL LETTER C */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xD0,
+  0x34, 0x00,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x34, 0x00,
+  0x0F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0064[ 26] = { /* code 0064, LATIN SMALL LETTER D */
+  0x00, 0x00,
+  0x00, 0x60,
+  0x00, 0x60,
+  0x00, 0x60,
+  0x1F, 0xA0,
+  0x30, 0xA0,
+  0x20, 0x60,
+  0x20, 0x60,
+  0x30, 0xA0,
+  0x1F, 0xA0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0065[ 26] = { /* code 0065, LATIN SMALL LETTER E */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xC0,
+  0x20, 0x60,
+  0x3F, 0xE0,
+  0x20, 0x00,
+  0x30, 0x00,
+  0x0F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0066[ 26] = { /* code 0066, LATIN SMALL LETTER F */
+  0x00, 0x00,
+  0x02, 0xE0,
+  0x02, 0x00,
+  0x06, 0x00,
+  0x3F, 0xE0,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0067[ 26] = { /* code 0067, LATIN SMALL LETTER G */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xA0,
+  0x30, 0xA0,
+  0x20, 0x60,
+  0x20, 0x60,
+  0x30, 0xA0,
+  0x1F, 0xA0,
+  0x00, 0x60,
+  0x1F, 0xC0,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0068[ 26] = { /* code 0068, LATIN SMALL LETTER H */
+  0x00, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x6B, 0xC0,
+  0x74, 0x60,
+  0x60, 0x60,
+  0x60, 0x60,
+  0x60, 0x60,
+  0x60, 0x60,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0069[ 26] = { /* code 0069, LATIN SMALL LETTER I */
+  0x00, 0x00,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x3F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_006A[ 26] = { /* code 006A, LATIN SMALL LETTER J */
+  0x00, 0x00,
+  0x02, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0x40,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x02, 0x00,
+  0x3E, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_006B[ 26] = { /* code 006B, LATIN SMALL LETTER K */
+  0x00, 0x00,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x20, 0xD0,
+  0x23, 0x00,
+  0x3D, 0x00,
+  0x37, 0x00,
+  0x21, 0x80,
+  0x20, 0xA0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_006C[ 26] = { /* code 006C, LATIN SMALL LETTER L */
+  0x00, 0x00,
+  0x7D, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x06, 0x00,
+  0x03, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_006D[ 26] = { /* code 006D, LATIN SMALL LETTER M */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7E, 0xB0,
+  0x63, 0x24,
+  0x62, 0x24,
+  0x62, 0x24,
+  0x62, 0x24,
+  0x62, 0x24,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_006E[ 26] = { /* code 006E, LATIN SMALL LETTER N */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x6B, 0xC0,
+  0x74, 0x60,
+  0x60, 0x60,
+  0x60, 0x60,
+  0x60, 0x60,
+  0x60, 0x60,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_006F[ 26] = { /* code 006F, LATIN SMALL LETTER O */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0x80,
+  0x30, 0x90,
+  0x20, 0x60,
+  0x20, 0x60,
+  0x30, 0x90,
+  0x1F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0070[ 26] = { /* code 0070, LATIN SMALL LETTER P */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0x80,
+  0x70, 0x90,
+  0x60, 0x60,
+  0x60, 0x60,
+  0x70, 0x90,
+  0x7F, 0x80,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0071[ 26] = { /* code 0071, LATIN SMALL LETTER Q */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xA0,
+  0x30, 0xA0,
+  0x20, 0x60,
+  0x20, 0x60,
+  0x30, 0xA0,
+  0x1F, 0xA0,
+  0x00, 0x60,
+  0x00, 0x60,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0072[ 26] = { /* code 0072, LATIN SMALL LETTER R */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0A, 0xF0,
+  0x0D, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0073[ 26] = { /* code 0073, LATIN SMALL LETTER S */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0xC0,
+  0x20, 0x00,
+  0x38, 0x00,
+  0x03, 0xC0,
+  0x00, 0xC0,
+  0x7F, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0074[ 26] = { /* code 0074, LATIN SMALL LETTER T */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x7F, 0xD0,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x07, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0075[ 26] = { /* code 0075, LATIN SMALL LETTER U */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x60, 0x60,
+  0x60, 0x60,
+  0x60, 0x60,
+  0x60, 0x60,
+  0x30, 0xA0,
+  0x2F, 0xA0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0076[ 26] = { /* code 0076, LATIN SMALL LETTER V */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x30, 0x60,
+  0x24, 0x90,
+  0x14, 0x80,
+  0x09, 0x80,
+  0x0B, 0x40,
+  0x07, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0077[ 26] = { /* code 0077, LATIN SMALL LETTER W */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x80, 0x14,
+  0x90, 0x24,
+  0x56, 0x20,
+  0x26, 0x60,
+  0x38, 0x90,
+  0x24, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0078[ 26] = { /* code 0078, LATIN SMALL LETTER X */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x24, 0x30,
+  0x0C, 0x80,
+  0x03, 0x40,
+  0x07, 0x80,
+  0x0C, 0x90,
+  0x34, 0x34,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_0079[ 26] = { /* code 0079, LATIN SMALL LETTER Y */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x30, 0x60,
+  0x24, 0x80,
+  0x18, 0x80,
+  0x0E, 0x40,
+  0x07, 0x00,
+  0x06, 0x00,
+  0x09, 0x00,
+  0x2C, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_007A[ 26] = { /* code 007A, LATIN SMALL LETTER Z */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xE0,
+  0x00, 0xC0,
+  0x02, 0x00,
+  0x09, 0x00,
+  0x24, 0x00,
+  0x7F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_007B[ 26] = { /* code 007B, LEFT CURLY BRACKET */
+  0x00, 0x00,
+  0x02, 0xD0,
+  0x03, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x28, 0x00,
+  0x06, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x03, 0x00,
+  0x02, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_007C[ 26] = { /* code 007C, VERTICAL LINE */
+  0x00, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_007D[ 26] = { /* code 007D, RIGHT CURLY BRACKET */
+  0x00, 0x00,
+  0x2D, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x02, 0x00,
+  0x00, 0xD0,
+  0x03, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x2D, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono13_AA2_007E[ 26] = { /* code 007E, TILDE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3D, 0x00,
+  0x42, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const aafontsCharInfo_t charTable_DejaVuSansMono13_AA2[95] = 
+{
+  {   7,   2, FontDejaVuSansMono13_AA2_0020 }, /* code 0020 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0021 }, /* code 0021 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0022 }, /* code 0022 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0023 }, /* code 0023 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0024 }, /* code 0024 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0025 }, /* code 0025 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0026 }, /* code 0026 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0027 }, /* code 0027 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0028 }, /* code 0028 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0029 }, /* code 0029 */
+  {   7,   2, FontDejaVuSansMono13_AA2_002A }, /* code 002A */
+  {   7,   2, FontDejaVuSansMono13_AA2_002B }, /* code 002B */
+  {   7,   2, FontDejaVuSansMono13_AA2_002C }, /* code 002C */
+  {   7,   2, FontDejaVuSansMono13_AA2_002D }, /* code 002D */
+  {   7,   2, FontDejaVuSansMono13_AA2_002E }, /* code 002E */
+  {   7,   2, FontDejaVuSansMono13_AA2_002F }, /* code 002F */
+  {   7,   2, FontDejaVuSansMono13_AA2_0030 }, /* code 0030 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0031 }, /* code 0031 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0032 }, /* code 0032 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0033 }, /* code 0033 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0034 }, /* code 0034 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0035 }, /* code 0035 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0036 }, /* code 0036 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0037 }, /* code 0037 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0038 }, /* code 0038 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0039 }, /* code 0039 */
+  {   7,   2, FontDejaVuSansMono13_AA2_003A }, /* code 003A */
+  {   7,   2, FontDejaVuSansMono13_AA2_003B }, /* code 003B */
+  {   7,   2, FontDejaVuSansMono13_AA2_003C }, /* code 003C */
+  {   7,   2, FontDejaVuSansMono13_AA2_003D }, /* code 003D */
+  {   7,   2, FontDejaVuSansMono13_AA2_003E }, /* code 003E */
+  {   7,   2, FontDejaVuSansMono13_AA2_003F }, /* code 003F */
+  {   7,   2, FontDejaVuSansMono13_AA2_0040 }, /* code 0040 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0041 }, /* code 0041 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0042 }, /* code 0042 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0043 }, /* code 0043 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0044 }, /* code 0044 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0045 }, /* code 0045 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0046 }, /* code 0046 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0047 }, /* code 0047 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0048 }, /* code 0048 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0049 }, /* code 0049 */
+  {   7,   2, FontDejaVuSansMono13_AA2_004A }, /* code 004A */
+  {   7,   2, FontDejaVuSansMono13_AA2_004B }, /* code 004B */
+  {   7,   2, FontDejaVuSansMono13_AA2_004C }, /* code 004C */
+  {   7,   2, FontDejaVuSansMono13_AA2_004D }, /* code 004D */
+  {   7,   2, FontDejaVuSansMono13_AA2_004E }, /* code 004E */
+  {   7,   2, FontDejaVuSansMono13_AA2_004F }, /* code 004F */
+  {   7,   2, FontDejaVuSansMono13_AA2_0050 }, /* code 0050 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0051 }, /* code 0051 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0052 }, /* code 0052 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0053 }, /* code 0053 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0054 }, /* code 0054 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0055 }, /* code 0055 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0056 }, /* code 0056 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0057 }, /* code 0057 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0058 }, /* code 0058 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0059 }, /* code 0059 */
+  {   7,   2, FontDejaVuSansMono13_AA2_005A }, /* code 005A */
+  {   7,   2, FontDejaVuSansMono13_AA2_005B }, /* code 005B */
+  {   7,   2, FontDejaVuSansMono13_AA2_005C }, /* code 005C */
+  {   7,   2, FontDejaVuSansMono13_AA2_005D }, /* code 005D */
+  {   7,   2, FontDejaVuSansMono13_AA2_005E }, /* code 005E */
+  {   7,   2, FontDejaVuSansMono13_AA2_005F }, /* code 005F */
+  {   7,   2, FontDejaVuSansMono13_AA2_0060 }, /* code 0060 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0061 }, /* code 0061 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0062 }, /* code 0062 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0063 }, /* code 0063 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0064 }, /* code 0064 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0065 }, /* code 0065 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0066 }, /* code 0066 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0067 }, /* code 0067 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0068 }, /* code 0068 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0069 }, /* code 0069 */
+  {   7,   2, FontDejaVuSansMono13_AA2_006A }, /* code 006A */
+  {   7,   2, FontDejaVuSansMono13_AA2_006B }, /* code 006B */
+  {   7,   2, FontDejaVuSansMono13_AA2_006C }, /* code 006C */
+  {   7,   2, FontDejaVuSansMono13_AA2_006D }, /* code 006D */
+  {   7,   2, FontDejaVuSansMono13_AA2_006E }, /* code 006E */
+  {   7,   2, FontDejaVuSansMono13_AA2_006F }, /* code 006F */
+  {   7,   2, FontDejaVuSansMono13_AA2_0070 }, /* code 0070 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0071 }, /* code 0071 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0072 }, /* code 0072 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0073 }, /* code 0073 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0074 }, /* code 0074 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0075 }, /* code 0075 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0076 }, /* code 0076 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0077 }, /* code 0077 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0078 }, /* code 0078 */
+  {   7,   2, FontDejaVuSansMono13_AA2_0079 }, /* code 0079 */
+  {   7,   2, FontDejaVuSansMono13_AA2_007A }, /* code 007A */
+  {   7,   2, FontDejaVuSansMono13_AA2_007B }, /* code 007B */
+  {   7,   2, FontDejaVuSansMono13_AA2_007C }, /* code 007C */
+  {   7,   2, FontDejaVuSansMono13_AA2_007D }, /* code 007D */
+  {   7,   2, FontDejaVuSansMono13_AA2_007E }  /* code 007E */
+};
+
+aafontsFont_t DejaVuSansMono13_AA2 = 
+{
+  AAFONTS_FONTTYPE_AA2,                         /* Font type (anti-aliasing level) */
+  13,                                           /* Font height in pixels */
+  7,                                            /* Width to insert for unknown characters */
+  8,                                            /* Height of upper-case characters */
+  6,                                            /* Height of lower-case characters */
+  10,                                           /* Font baseline */
+  0x0020,                                       /* Unicode address of first character */
+  0x007E,                                       /* Unicode address of last character */
+  &charTable_DejaVuSansMono13_AA2[0]  	    /* Font char data */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansMono13_AA2.h b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansMono13_AA2.h
new file mode 100644
index 0000000000000000000000000000000000000000..3969ec2e74b6b76e415b48814778e7774ef77373
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansMono13_AA2.h
@@ -0,0 +1,52 @@
+/**************************************************************************/
+/*! 
+    @file     DejaVuSansMono13_AA2.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __DejaVuSansMono13_AA2_H__
+#define __DejaVuSansMono13_AA2_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "drivers/displays/graphic/aafonts.h"
+
+extern aafontsFont_t DejaVuSansMono13_AA2;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansMono14_AA2.c b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansMono14_AA2.c
new file mode 100644
index 0000000000000000000000000000000000000000..ddedc3b15e81a4c6e59c917b977752459fe30d03
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansMono14_AA2.c
@@ -0,0 +1,1764 @@
+/**************************************************************************/
+/*! 
+    @file     DejaVuSansMono14_AA2.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "DejaVuSansMono14_AA2.h"
+
+/* Start of unicode area <Basic Latin> */
+const uint8_t FontDejaVuSansMono14_AA2_0020[ 28] = { /* code 0020, SPACE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0021[ 28] = { /* code 0021, EXCLAMATION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0022[ 28] = { /* code 0022, QUOTATION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x08, 0x90,
+  0x08, 0x90,
+  0x08, 0x90,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0023[ 28] = { /* code 0023, NUMBER SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x02, 0x20,
+  0x05, 0x20,
+  0x7F, 0xFC,
+  0x08, 0x50,
+  0x08, 0x80,
+  0xFF, 0xF4,
+  0x25, 0x80,
+  0x21, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0024[ 28] = { /* code 0024, DOLLAR SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x01, 0x00,
+  0x0F, 0xE0,
+  0x25, 0x14,
+  0x21, 0x00,
+  0x1E, 0x00,
+  0x02, 0xF0,
+  0x01, 0x14,
+  0x11, 0x24,
+  0x0F, 0xE0,
+  0x01, 0x00,
+  0x01, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0025[ 28] = { /* code 0025, PERCENT SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3D, 0x00,
+  0x92, 0x00,
+  0x92, 0x00,
+  0x3D, 0x38,
+  0x03, 0x80,
+  0x38, 0xF4,
+  0x02, 0x4C,
+  0x02, 0x4C,
+  0x00, 0xF4,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0026[ 28] = { /* code 0026, AMPERSAND */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xD0,
+  0x18, 0x00,
+  0x18, 0x00,
+  0x0C, 0x00,
+  0x2E, 0x00,
+  0x62, 0x88,
+  0x50, 0x98,
+  0x70, 0x30,
+  0x1F, 0xDC,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0027[ 28] = { /* code 0027, APOSTROPHE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0028[ 28] = { /* code 0028, LEFT PARENTHESIS */
+  0x00, 0x00,
+  0x00, 0xC0,
+  0x02, 0x40,
+  0x02, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x05, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x02, 0x00,
+  0x02, 0x40,
+  0x00, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0029[ 28] = { /* code 0029, RIGHT PARENTHESIS */
+  0x00, 0x00,
+  0x09, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x40,
+  0x01, 0x80,
+  0x01, 0x80,
+  0x01, 0x80,
+  0x02, 0x40,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x09, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_002A[ 28] = { /* code 002A, ASTERISK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x01, 0x00,
+  0x21, 0x20,
+  0x0F, 0xD0,
+  0x0B, 0xC0,
+  0x25, 0x30,
+  0x01, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_002B[ 28] = { /* code 002B, PLUS SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x7F, 0xF8,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_002C[ 28] = { /* code 002C, COMMA */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0x40,
+  0x07, 0x00,
+  0x09, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_002D[ 28] = { /* code 002D, HYPHEN-MINUS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_002E[ 28] = { /* code 002E, FULL STOP */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0x40,
+  0x03, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_002F[ 28] = { /* code 002F, SOLIDUS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x30,
+  0x00, 0x90,
+  0x00, 0x80,
+  0x01, 0x40,
+  0x03, 0x00,
+  0x06, 0x00,
+  0x08, 0x00,
+  0x18, 0x00,
+  0x24, 0x00,
+  0x20, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0030[ 28] = { /* code 0030, DIGIT ZERO */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xD0,
+  0x24, 0x30,
+  0x20, 0x14,
+  0x20, 0x18,
+  0x63, 0x58,
+  0x20, 0x18,
+  0x20, 0x14,
+  0x24, 0x30,
+  0x0B, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0031[ 28] = { /* code 0031, DIGIT ONE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x1F, 0xF4,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0032[ 28] = { /* code 0032, DIGIT TWO */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xC0,
+  0x20, 0x60,
+  0x00, 0x20,
+  0x00, 0x60,
+  0x00, 0xD0,
+  0x02, 0x40,
+  0x09, 0x00,
+  0x24, 0x00,
+  0x7F, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0033[ 28] = { /* code 0033, DIGIT THREE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xD0,
+  0x20, 0x24,
+  0x00, 0x14,
+  0x00, 0x34,
+  0x0B, 0xC0,
+  0x00, 0x34,
+  0x00, 0x18,
+  0x50, 0x24,
+  0x1F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0034[ 28] = { /* code 0034, DIGIT FOUR */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0xD0,
+  0x02, 0x90,
+  0x06, 0x50,
+  0x08, 0x50,
+  0x14, 0x50,
+  0x20, 0x50,
+  0x7F, 0xF8,
+  0x00, 0x50,
+  0x00, 0x50,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0035[ 28] = { /* code 0035, DIGIT FIVE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0xF0,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x2F, 0xD0,
+  0x00, 0x34,
+  0x00, 0x18,
+  0x00, 0x18,
+  0x50, 0x34,
+  0x2F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0036[ 28] = { /* code 0036, DIGIT SIX */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xE0,
+  0x18, 0x00,
+  0x20, 0x00,
+  0x2B, 0xE0,
+  0x74, 0x24,
+  0x20, 0x18,
+  0x20, 0x18,
+  0x24, 0x24,
+  0x0F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0037[ 28] = { /* code 0037, DIGIT SEVEN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xF8,
+  0x00, 0x20,
+  0x00, 0x60,
+  0x00, 0x90,
+  0x00, 0xC0,
+  0x02, 0x40,
+  0x03, 0x00,
+  0x06, 0x00,
+  0x0C, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0038[ 28] = { /* code 0038, DIGIT EIGHT */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xE0,
+  0x24, 0x24,
+  0x20, 0x14,
+  0x24, 0x24,
+  0x0B, 0xC0,
+  0x34, 0x24,
+  0x20, 0x18,
+  0x30, 0x28,
+  0x1F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0039[ 28] = { /* code 0039, DIGIT NINE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xD0,
+  0x34, 0x20,
+  0x20, 0x14,
+  0x20, 0x18,
+  0x34, 0x28,
+  0x0F, 0xD8,
+  0x00, 0x14,
+  0x10, 0x70,
+  0x0F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_003A[ 28] = { /* code 003A, COLON */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0x40,
+  0x03, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0x40,
+  0x03, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_003B[ 28] = { /* code 003B, SEMICOLON */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0x40,
+  0x03, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0x40,
+  0x07, 0x00,
+  0x09, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_003C[ 28] = { /* code 003C, LESS-THAN SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x18,
+  0x03, 0xE0,
+  0x7C, 0x00,
+  0x7C, 0x00,
+  0x03, 0xE0,
+  0x00, 0x18,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_003D[ 28] = { /* code 003D, EQUALS SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xF8,
+  0x00, 0x00,
+  0x7F, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_003E[ 28] = { /* code 003E, GREATER-THAN SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x60, 0x00,
+  0x1F, 0x00,
+  0x00, 0xB8,
+  0x00, 0xB8,
+  0x1F, 0x00,
+  0x60, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_003F[ 28] = { /* code 003F, QUESTION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xD0,
+  0x10, 0x30,
+  0x00, 0x30,
+  0x00, 0xD0,
+  0x03, 0x00,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0040[ 28] = { /* code 0040, COMMERCIAL AT */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xF0,
+  0x18, 0x28,
+  0x30, 0x0C,
+  0x61, 0xFC,
+  0x53, 0x0C,
+  0x53, 0x08,
+  0x61, 0xFC,
+  0x30, 0x00,
+  0x1C, 0x00,
+  0x07, 0xF0,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0041[ 28] = { /* code 0041, LATIN CAPITAL LETTER A */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0x80,
+  0x07, 0xC0,
+  0x05, 0x90,
+  0x09, 0x60,
+  0x0C, 0x30,
+  0x18, 0x24,
+  0x2F, 0xF4,
+  0x30, 0x18,
+  0x60, 0x0C,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0042[ 28] = { /* code 0042, LATIN CAPITAL LETTER B */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xD0,
+  0x60, 0x30,
+  0x60, 0x24,
+  0x60, 0x30,
+  0x7F, 0xC0,
+  0x60, 0x34,
+  0x60, 0x18,
+  0x60, 0x24,
+  0x7F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0043[ 28] = { /* code 0043, LATIN CAPITAL LETTER C */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xF0,
+  0x18, 0x04,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x20, 0x00,
+  0x18, 0x04,
+  0x07, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0044[ 28] = { /* code 0044, LATIN CAPITAL LETTER D */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0x80,
+  0x60, 0x70,
+  0x60, 0x24,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x60, 0x24,
+  0x60, 0x70,
+  0x7F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0045[ 28] = { /* code 0045, LATIN CAPITAL LETTER E */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xE0,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x7F, 0xE0,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x7F, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0046[ 28] = { /* code 0046, LATIN CAPITAL LETTER F */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0xF4,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x2F, 0xF0,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0047[ 28] = { /* code 0047, LATIN CAPITAL LETTER G */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xE0,
+  0x28, 0x00,
+  0x20, 0x00,
+  0x60, 0x00,
+  0x60, 0xB8,
+  0x60, 0x18,
+  0x20, 0x18,
+  0x28, 0x18,
+  0x0B, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0048[ 28] = { /* code 0048, LATIN CAPITAL LETTER H */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x7F, 0xF8,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0049[ 28] = { /* code 0049, LATIN CAPITAL LETTER I */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0xE0,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x2F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_004A[ 28] = { /* code 004A, LATIN CAPITAL LETTER J */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xE0,
+  0x00, 0x60,
+  0x00, 0x60,
+  0x00, 0x60,
+  0x00, 0x60,
+  0x00, 0x60,
+  0x00, 0x60,
+  0x50, 0x90,
+  0x2F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_004B[ 28] = { /* code 004B, LATIN CAPITAL LETTER K */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x60, 0x38,
+  0x60, 0xD0,
+  0x62, 0x40,
+  0x69, 0x00,
+  0x7F, 0x00,
+  0x62, 0x80,
+  0x60, 0xD0,
+  0x60, 0x70,
+  0x60, 0x28,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_004C[ 28] = { /* code 004C, LATIN CAPITAL LETTER L */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x7F, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_004D[ 28] = { /* code 004D, LATIN CAPITAL LETTER M */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x74, 0x38,
+  0x78, 0x78,
+  0x78, 0x98,
+  0x65, 0x98,
+  0x63, 0x58,
+  0x62, 0x58,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_004E[ 28] = { /* code 004E, LATIN CAPITAL LETTER N */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x74, 0x18,
+  0x78, 0x18,
+  0x7D, 0x18,
+  0x66, 0x18,
+  0x62, 0x18,
+  0x61, 0x98,
+  0x60, 0xD8,
+  0x60, 0x78,
+  0x60, 0x38,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_004F[ 28] = { /* code 004F, LATIN CAPITAL LETTER O */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xD0,
+  0x24, 0x30,
+  0x30, 0x14,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x30, 0x14,
+  0x24, 0x30,
+  0x0F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0050[ 28] = { /* code 0050, LATIN CAPITAL LETTER P */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xE0,
+  0x60, 0x24,
+  0x60, 0x18,
+  0x60, 0x24,
+  0x7F, 0xE0,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x60, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0051[ 28] = { /* code 0051, LATIN CAPITAL LETTER Q */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xD0,
+  0x24, 0x30,
+  0x30, 0x14,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x30, 0x14,
+  0x24, 0x30,
+  0x0F, 0xD0,
+  0x00, 0xA0,
+  0x00, 0x20,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0052[ 28] = { /* code 0052, LATIN CAPITAL LETTER R */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xE0,
+  0x60, 0x24,
+  0x60, 0x18,
+  0x60, 0x24,
+  0x7F, 0xC0,
+  0x60, 0x70,
+  0x60, 0x24,
+  0x60, 0x1C,
+  0x60, 0x08,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0053[ 28] = { /* code 0053, LATIN CAPITAL LETTER S */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xE0,
+  0x30, 0x08,
+  0x60, 0x00,
+  0x34, 0x00,
+  0x0F, 0xE0,
+  0x00, 0x24,
+  0x00, 0x18,
+  0x20, 0x24,
+  0x1F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0054[ 28] = { /* code 0054, LATIN CAPITAL LETTER T */
+  0x00, 0x00,
+  0x00, 0x00,
+  0xBF, 0xF8,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0055[ 28] = { /* code 0055, LATIN CAPITAL LETTER U */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x60, 0x18,
+  0x30, 0x24,
+  0x0F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0056[ 28] = { /* code 0056, LATIN CAPITAL LETTER V */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x30, 0x24,
+  0x30, 0x24,
+  0x24, 0x30,
+  0x18, 0x60,
+  0x0C, 0x50,
+  0x08, 0x90,
+  0x09, 0x80,
+  0x07, 0x80,
+  0x03, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0057[ 28] = { /* code 0057, LATIN CAPITAL LETTER W */
+  0x00, 0x00,
+  0x00, 0x00,
+  0xC0, 0x0C,
+  0x90, 0x08,
+  0x93, 0x48,
+  0x57, 0x58,
+  0x65, 0x98,
+  0x28, 0x98,
+  0x28, 0x64,
+  0x28, 0x70,
+  0x24, 0x70,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0058[ 28] = { /* code 0058, LATIN CAPITAL LETTER X */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x34, 0x0C,
+  0x0C, 0x24,
+  0x0A, 0x20,
+  0x03, 0xD0,
+  0x02, 0xC0,
+  0x06, 0x90,
+  0x09, 0x30,
+  0x18, 0x18,
+  0x34, 0x08,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0059[ 28] = { /* code 0059, LATIN CAPITAL LETTER Y */
+  0x00, 0x00,
+  0x00, 0x00,
+  0xA0, 0x28,
+  0x34, 0x30,
+  0x18, 0x90,
+  0x0A, 0x80,
+  0x07, 0x40,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_005A[ 28] = { /* code 005A, LATIN CAPITAL LETTER Z */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xF4,
+  0x00, 0x30,
+  0x00, 0x90,
+  0x01, 0x80,
+  0x03, 0x00,
+  0x09, 0x00,
+  0x18, 0x00,
+  0x34, 0x00,
+  0x7F, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_005B[ 28] = { /* code 005B, LEFT SQUARE BRACKET */
+  0x00, 0x00,
+  0x07, 0xD0,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x07, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_005C[ 28] = { /* code 005C, REVERSE SOLIDUS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x20, 0x00,
+  0x24, 0x00,
+  0x18, 0x00,
+  0x08, 0x00,
+  0x06, 0x00,
+  0x03, 0x00,
+  0x01, 0x40,
+  0x00, 0x80,
+  0x00, 0x90,
+  0x00, 0x30,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_005D[ 28] = { /* code 005D, RIGHT SQUARE BRACKET */
+  0x00, 0x00,
+  0x0F, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x0F, 0x40,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_005E[ 28] = { /* code 005E, CIRCUMFLEX ACCENT */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0x80,
+  0x0C, 0x90,
+  0x70, 0x28,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_005F[ 28] = { /* code 005F, LOW LINE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xFF, 0xFC
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0060[ 28] = { /* code 0060, GRAVE ACCENT */
+  0x00, 0x00,
+  0x0C, 0x00,
+  0x03, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0061[ 28] = { /* code 0061, LATIN SMALL LETTER A */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0x80,
+  0x00, 0x60,
+  0x00, 0x60,
+  0x1F, 0xE0,
+  0x30, 0x60,
+  0x30, 0xA0,
+  0x2F, 0xA0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0062[ 28] = { /* code 0062, LATIN SMALL LETTER B */
+  0x00, 0x00,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x2B, 0x80,
+  0x34, 0x90,
+  0x30, 0x60,
+  0x20, 0x60,
+  0x30, 0x60,
+  0x34, 0x90,
+  0x2B, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0063[ 28] = { /* code 0063, LATIN SMALL LETTER C */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xD0,
+  0x24, 0x10,
+  0x30, 0x00,
+  0x20, 0x00,
+  0x30, 0x00,
+  0x24, 0x10,
+  0x0B, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0064[ 28] = { /* code 0064, LATIN SMALL LETTER D */
+  0x00, 0x00,
+  0x00, 0x60,
+  0x00, 0x60,
+  0x00, 0x60,
+  0x0F, 0xA0,
+  0x24, 0xA0,
+  0x30, 0x60,
+  0x20, 0x60,
+  0x30, 0x60,
+  0x24, 0xA0,
+  0x0F, 0xA0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0065[ 28] = { /* code 0065, LATIN SMALL LETTER E */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xD0,
+  0x24, 0x24,
+  0x30, 0x14,
+  0x3F, 0xF8,
+  0x20, 0x00,
+  0x24, 0x14,
+  0x0B, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0066[ 28] = { /* code 0066, LATIN SMALL LETTER F */
+  0x00, 0x00,
+  0x01, 0xF0,
+  0x02, 0x00,
+  0x03, 0x00,
+  0x2F, 0xF0,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0067[ 28] = { /* code 0067, LATIN SMALL LETTER G */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xA0,
+  0x24, 0xA0,
+  0x30, 0x60,
+  0x20, 0x60,
+  0x30, 0x60,
+  0x24, 0xA0,
+  0x0F, 0xA0,
+  0x00, 0x60,
+  0x10, 0x90,
+  0x0B, 0x80
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0068[ 28] = { /* code 0068, LATIN SMALL LETTER H */
+  0x00, 0x00,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x2B, 0xC0,
+  0x34, 0x60,
+  0x30, 0x60,
+  0x20, 0x60,
+  0x20, 0x60,
+  0x20, 0x60,
+  0x20, 0x60,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0069[ 28] = { /* code 0069, LATIN SMALL LETTER I */
+  0x00, 0x00,
+  0x02, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0x40,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x3F, 0xF4,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_006A[ 28] = { /* code 006A, LATIN SMALL LETTER J */
+  0x00, 0x00,
+  0x01, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x01, 0x40,
+  0x02, 0x40,
+  0x3E, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_006B[ 28] = { /* code 006B, LATIN SMALL LETTER K */
+  0x00, 0x00,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x20, 0xA0,
+  0x22, 0x40,
+  0x2D, 0x00,
+  0x3F, 0x00,
+  0x22, 0x80,
+  0x20, 0xD0,
+  0x20, 0x74,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_006C[ 28] = { /* code 006C, LATIN SMALL LETTER L */
+  0x00, 0x00,
+  0x7E, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x03, 0x00,
+  0x02, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_006D[ 28] = { /* code 006D, LATIN SMALL LETTER M */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xFE, 0xD0,
+  0xC9, 0x60,
+  0x89, 0x20,
+  0x89, 0x20,
+  0x89, 0x20,
+  0x89, 0x20,
+  0x89, 0x20,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_006E[ 28] = { /* code 006E, LATIN SMALL LETTER N */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2B, 0xC0,
+  0x34, 0x60,
+  0x30, 0x60,
+  0x20, 0x60,
+  0x20, 0x60,
+  0x20, 0x60,
+  0x20, 0x60,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_006F[ 28] = { /* code 006F, LATIN SMALL LETTER O */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0x80,
+  0x24, 0x90,
+  0x30, 0x60,
+  0x20, 0x60,
+  0x30, 0x60,
+  0x24, 0x90,
+  0x0F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0070[ 28] = { /* code 0070, LATIN SMALL LETTER P */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2B, 0x80,
+  0x34, 0x90,
+  0x30, 0x60,
+  0x20, 0x60,
+  0x30, 0x60,
+  0x34, 0x90,
+  0x2B, 0x80,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x20, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0071[ 28] = { /* code 0071, LATIN SMALL LETTER Q */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xA0,
+  0x24, 0xA0,
+  0x30, 0x60,
+  0x20, 0x60,
+  0x30, 0x60,
+  0x24, 0xA0,
+  0x0F, 0xA0,
+  0x00, 0x60,
+  0x00, 0x60,
+  0x00, 0x60
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0072[ 28] = { /* code 0072, LATIN SMALL LETTER R */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x09, 0xF8,
+  0x0A, 0x00,
+  0x09, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0073[ 28] = { /* code 0073, LATIN SMALL LETTER S */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xC0,
+  0x30, 0x10,
+  0x30, 0x00,
+  0x0F, 0xC0,
+  0x00, 0x60,
+  0x10, 0x60,
+  0x1F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0074[ 28] = { /* code 0074, LATIN SMALL LETTER T */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x7F, 0xF0,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x05, 0x00,
+  0x06, 0x00,
+  0x03, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0075[ 28] = { /* code 0075, LATIN SMALL LETTER U */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x20, 0x60,
+  0x20, 0x60,
+  0x20, 0x60,
+  0x20, 0x60,
+  0x20, 0x60,
+  0x30, 0xA0,
+  0x1F, 0xA0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0076[ 28] = { /* code 0076, LATIN SMALL LETTER V */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x30, 0x18,
+  0x24, 0x24,
+  0x18, 0x20,
+  0x08, 0x60,
+  0x09, 0x90,
+  0x06, 0x80,
+  0x03, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0077[ 28] = { /* code 0077, LATIN SMALL LETTER W */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x80, 0x0C,
+  0x90, 0x0C,
+  0x53, 0x18,
+  0x22, 0x54,
+  0x25, 0x64,
+  0x2C, 0xB0,
+  0x18, 0x60,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0078[ 28] = { /* code 0078, LATIN SMALL LETTER X */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x28, 0x28,
+  0x09, 0x60,
+  0x03, 0xC0,
+  0x02, 0x80,
+  0x06, 0x90,
+  0x0C, 0x30,
+  0x34, 0x1C,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_0079[ 28] = { /* code 0079, LATIN SMALL LETTER Y */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x30, 0x18,
+  0x24, 0x24,
+  0x18, 0x20,
+  0x0C, 0x60,
+  0x05, 0x90,
+  0x03, 0xC0,
+  0x02, 0x80,
+  0x02, 0x40,
+  0x03, 0x00,
+  0x2D, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_007A[ 28] = { /* code 007A, LATIN SMALL LETTER Z */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xE0,
+  0x00, 0x90,
+  0x01, 0x80,
+  0x07, 0x00,
+  0x0C, 0x00,
+  0x24, 0x00,
+  0x3F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_007B[ 28] = { /* code 007B, LEFT CURLY BRACKET */
+  0x00, 0x00,
+  0x01, 0xF0,
+  0x02, 0x40,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x03, 0x00,
+  0x2C, 0x00,
+  0x03, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x40,
+  0x01, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_007C[ 28] = { /* code 007C, VERTICAL LINE */
+  0x00, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x02, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_007D[ 28] = { /* code 007D, RIGHT CURLY BRACKET */
+  0x00, 0x00,
+  0x2E, 0x00,
+  0x02, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x02, 0x40,
+  0x00, 0xB0,
+  0x02, 0x40,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x02, 0x00,
+  0x2E, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontDejaVuSansMono14_AA2_007E[ 28] = { /* code 007E, TILDE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3E, 0x04,
+  0x41, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const aafontsCharInfo_t charTable_DejaVuSansMono14_AA2[95] = 
+{
+  {   7,   2, FontDejaVuSansMono14_AA2_0020 }, /* code 0020 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0021 }, /* code 0021 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0022 }, /* code 0022 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0023 }, /* code 0023 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0024 }, /* code 0024 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0025 }, /* code 0025 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0026 }, /* code 0026 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0027 }, /* code 0027 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0028 }, /* code 0028 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0029 }, /* code 0029 */
+  {   7,   2, FontDejaVuSansMono14_AA2_002A }, /* code 002A */
+  {   7,   2, FontDejaVuSansMono14_AA2_002B }, /* code 002B */
+  {   7,   2, FontDejaVuSansMono14_AA2_002C }, /* code 002C */
+  {   7,   2, FontDejaVuSansMono14_AA2_002D }, /* code 002D */
+  {   7,   2, FontDejaVuSansMono14_AA2_002E }, /* code 002E */
+  {   7,   2, FontDejaVuSansMono14_AA2_002F }, /* code 002F */
+  {   7,   2, FontDejaVuSansMono14_AA2_0030 }, /* code 0030 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0031 }, /* code 0031 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0032 }, /* code 0032 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0033 }, /* code 0033 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0034 }, /* code 0034 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0035 }, /* code 0035 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0036 }, /* code 0036 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0037 }, /* code 0037 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0038 }, /* code 0038 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0039 }, /* code 0039 */
+  {   7,   2, FontDejaVuSansMono14_AA2_003A }, /* code 003A */
+  {   7,   2, FontDejaVuSansMono14_AA2_003B }, /* code 003B */
+  {   7,   2, FontDejaVuSansMono14_AA2_003C }, /* code 003C */
+  {   7,   2, FontDejaVuSansMono14_AA2_003D }, /* code 003D */
+  {   7,   2, FontDejaVuSansMono14_AA2_003E }, /* code 003E */
+  {   7,   2, FontDejaVuSansMono14_AA2_003F }, /* code 003F */
+  {   7,   2, FontDejaVuSansMono14_AA2_0040 }, /* code 0040 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0041 }, /* code 0041 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0042 }, /* code 0042 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0043 }, /* code 0043 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0044 }, /* code 0044 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0045 }, /* code 0045 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0046 }, /* code 0046 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0047 }, /* code 0047 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0048 }, /* code 0048 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0049 }, /* code 0049 */
+  {   7,   2, FontDejaVuSansMono14_AA2_004A }, /* code 004A */
+  {   7,   2, FontDejaVuSansMono14_AA2_004B }, /* code 004B */
+  {   7,   2, FontDejaVuSansMono14_AA2_004C }, /* code 004C */
+  {   7,   2, FontDejaVuSansMono14_AA2_004D }, /* code 004D */
+  {   7,   2, FontDejaVuSansMono14_AA2_004E }, /* code 004E */
+  {   7,   2, FontDejaVuSansMono14_AA2_004F }, /* code 004F */
+  {   7,   2, FontDejaVuSansMono14_AA2_0050 }, /* code 0050 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0051 }, /* code 0051 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0052 }, /* code 0052 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0053 }, /* code 0053 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0054 }, /* code 0054 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0055 }, /* code 0055 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0056 }, /* code 0056 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0057 }, /* code 0057 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0058 }, /* code 0058 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0059 }, /* code 0059 */
+  {   7,   2, FontDejaVuSansMono14_AA2_005A }, /* code 005A */
+  {   7,   2, FontDejaVuSansMono14_AA2_005B }, /* code 005B */
+  {   7,   2, FontDejaVuSansMono14_AA2_005C }, /* code 005C */
+  {   7,   2, FontDejaVuSansMono14_AA2_005D }, /* code 005D */
+  {   7,   2, FontDejaVuSansMono14_AA2_005E }, /* code 005E */
+  {   7,   2, FontDejaVuSansMono14_AA2_005F }, /* code 005F */
+  {   7,   2, FontDejaVuSansMono14_AA2_0060 }, /* code 0060 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0061 }, /* code 0061 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0062 }, /* code 0062 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0063 }, /* code 0063 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0064 }, /* code 0064 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0065 }, /* code 0065 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0066 }, /* code 0066 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0067 }, /* code 0067 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0068 }, /* code 0068 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0069 }, /* code 0069 */
+  {   7,   2, FontDejaVuSansMono14_AA2_006A }, /* code 006A */
+  {   7,   2, FontDejaVuSansMono14_AA2_006B }, /* code 006B */
+  {   7,   2, FontDejaVuSansMono14_AA2_006C }, /* code 006C */
+  {   7,   2, FontDejaVuSansMono14_AA2_006D }, /* code 006D */
+  {   7,   2, FontDejaVuSansMono14_AA2_006E }, /* code 006E */
+  {   7,   2, FontDejaVuSansMono14_AA2_006F }, /* code 006F */
+  {   7,   2, FontDejaVuSansMono14_AA2_0070 }, /* code 0070 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0071 }, /* code 0071 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0072 }, /* code 0072 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0073 }, /* code 0073 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0074 }, /* code 0074 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0075 }, /* code 0075 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0076 }, /* code 0076 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0077 }, /* code 0077 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0078 }, /* code 0078 */
+  {   7,   2, FontDejaVuSansMono14_AA2_0079 }, /* code 0079 */
+  {   7,   2, FontDejaVuSansMono14_AA2_007A }, /* code 007A */
+  {   7,   2, FontDejaVuSansMono14_AA2_007B }, /* code 007B */
+  {   7,   2, FontDejaVuSansMono14_AA2_007C }, /* code 007C */
+  {   7,   2, FontDejaVuSansMono14_AA2_007D }, /* code 007D */
+  {   7,   2, FontDejaVuSansMono14_AA2_007E }  /* code 007E */
+};
+
+aafontsFont_t DejaVuSansMono14_AA2 = 
+{
+  AAFONTS_FONTTYPE_AA2,                         /* Font type (anti-aliasing level) */
+  14,                                           /* Font height in pixels */
+  7,                                            /* Width to insert for unknown characters */
+  9,                                            /* Height of upper-case characters */
+  7,                                            /* Height of lower-case characters */
+  11,                                           /* Font baseline */
+  0x0020,                                       /* Unicode address of first character */
+  0x007E,                                       /* Unicode address of last character */
+  &charTable_DejaVuSansMono14_AA2[0]  	    /* Font char data */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansMono14_AA2.h b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansMono14_AA2.h
new file mode 100644
index 0000000000000000000000000000000000000000..0098a950fcc33c03ea4ddc6c31ae4ee0881ff2d5
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/DejaVuSansMono14_AA2.h
@@ -0,0 +1,52 @@
+/**************************************************************************/
+/*! 
+    @file     DejaVuSansMono14_AA2.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __DejaVuSansMono14_AA2_H__
+#define __DejaVuSansMono14_AA2_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "drivers/displays/graphic/aafonts.h"
+
+extern aafontsFont_t DejaVuSansMono14_AA2;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontCalibri18_AA2.c b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontCalibri18_AA2.c
new file mode 100644
index 0000000000000000000000000000000000000000..934ece658ad8b35a16c7dbffecf0bca0e05babef
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontCalibri18_AA2.c
@@ -0,0 +1,2144 @@
+/**************************************************************************/
+/*! 
+    @file     FontCalibri18_AA2.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "FontCalibri18_AA2.h"
+
+/* Start of unicode area <Basic Latin> */
+const uint8_t FontCalibri18_AA2_0020[ 18] = { /* code 0020, SPACE */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibri18_AA2_0021[ 36] = { /* code 0021, EXCLAMATION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0D, 0x00,
+  0x0D, 0x00,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x00, 0x00,
+  0x0D, 0x00,
+  0x0D, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0022[ 36] = { /* code 0022, QUOTATION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x35, 0x80,
+  0x31, 0x80,
+  0x21, 0x80,
+  0x20, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0023[ 36] = { /* code 0023, NUMBER SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x08, 0x24,
+  0x08, 0x20,
+  0x7F, 0xFC,
+  0x18, 0x20,
+  0x18, 0x60,
+  0xBF, 0xF8,
+  0x24, 0x50,
+  0x24, 0x90,
+  0x20, 0x90,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0024[ 36] = { /* code 0024, DOLLAR SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x80,
+  0x01, 0x80,
+  0x0F, 0xF0,
+  0x34, 0x24,
+  0x30, 0x00,
+  0x2C, 0x00,
+  0x07, 0xE0,
+  0x00, 0x38,
+  0x00, 0x18,
+  0x60, 0x28,
+  0x2F, 0xE0,
+  0x06, 0x00,
+  0x05, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0025[ 54] = { /* code 0025, PERCENT SIGN */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x2F, 0x00, 0xC0,
+  0x61, 0x42, 0x40,
+  0x61, 0x86, 0x00,
+  0x61, 0x4C, 0x00,
+  0x2F, 0x24, 0x00,
+  0x00, 0x63, 0xD0,
+  0x00, 0x89, 0x30,
+  0x03, 0x08, 0x20,
+  0x09, 0x09, 0x20,
+  0x18, 0x07, 0xD0,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0026[ 54] = { /* code 0026, AMPERSAND */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x07, 0xF4, 0x00,
+  0x0C, 0x1C, 0x00,
+  0x1C, 0x1C, 0x00,
+  0x0D, 0x34, 0x00,
+  0x07, 0xC0, 0x00,
+  0x1E, 0xC1, 0x80,
+  0x34, 0xB2, 0x80,
+  0x30, 0x2F, 0x00,
+  0x38, 0x1F, 0x40,
+  0x0F, 0xF0, 0xE0,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0027[ 18] = { /* code 0027, APOSTROPHE */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x34,
+  0x30,
+  0x20,
+  0x20,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibri18_AA2_0028[ 36] = { /* code 0028, LEFT PARENTHESIS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x05, 0x00,
+  0x0C, 0x00,
+  0x18, 0x00,
+  0x28, 0x00,
+  0x24, 0x00,
+  0x34, 0x00,
+  0x34, 0x00,
+  0x34, 0x00,
+  0x24, 0x00,
+  0x28, 0x00,
+  0x18, 0x00,
+  0x0C, 0x00,
+  0x05, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0029[ 36] = { /* code 0029, RIGHT PARENTHESIS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x30, 0x00,
+  0x14, 0x00,
+  0x18, 0x00,
+  0x0C, 0x00,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x0C, 0x00,
+  0x1C, 0x00,
+  0x28, 0x00,
+  0x30, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_002A[ 36] = { /* code 002A, ASTERISK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x02, 0x00,
+  0x2A, 0x70,
+  0x03, 0x80,
+  0x2A, 0x70,
+  0x02, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_002B[ 36] = { /* code 002B, PLUS SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x7F, 0xFC,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_002C[ 18] = { /* code 002C, COMMA */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x28,
+  0x28,
+  0x30,
+  0x50,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibri18_AA2_002D[ 36] = { /* code 002D, HYPHEN-MINUS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_002E[ 18] = { /* code 002E, FULL STOP */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x28,
+  0x28,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibri18_AA2_002F[ 36] = { /* code 002F, SOLIDUS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0xA0,
+  0x00, 0xD0,
+  0x01, 0x80,
+  0x02, 0x40,
+  0x03, 0x00,
+  0x06, 0x00,
+  0x09, 0x00,
+  0x0C, 0x00,
+  0x18, 0x00,
+  0x24, 0x00,
+  0x30, 0x00,
+  0x60, 0x00,
+  0x90, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0030[ 36] = { /* code 0030, DIGIT ZERO */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xD0,
+  0x34, 0x70,
+  0x70, 0x24,
+  0x60, 0x24,
+  0x60, 0x24,
+  0x60, 0x24,
+  0x70, 0x24,
+  0x34, 0x70,
+  0x0F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0031[ 36] = { /* code 0031, DIGIT ONE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0x40,
+  0x36, 0x40,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x3F, 0xF4,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0032[ 36] = { /* code 0032, DIGIT TWO */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xD0,
+  0x20, 0x70,
+  0x00, 0x30,
+  0x00, 0x70,
+  0x00, 0x90,
+  0x02, 0x80,
+  0x0A, 0x00,
+  0x28, 0x00,
+  0x7F, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0033[ 36] = { /* code 0033, DIGIT THREE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xC0,
+  0x20, 0xA0,
+  0x00, 0x60,
+  0x00, 0xD0,
+  0x1F, 0x80,
+  0x00, 0x70,
+  0x00, 0x30,
+  0x20, 0x70,
+  0x2F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0034[ 36] = { /* code 0034, DIGIT FOUR */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x02, 0xD0,
+  0x07, 0xD0,
+  0x09, 0x90,
+  0x18, 0x90,
+  0x30, 0x90,
+  0x90, 0x90,
+  0xFF, 0xF8,
+  0x00, 0x90,
+  0x00, 0x90,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0035[ 36] = { /* code 0035, DIGIT FIVE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0xE0,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x2F, 0xC0,
+  0x00, 0x70,
+  0x00, 0x34,
+  0x00, 0x30,
+  0x80, 0xA0,
+  0x7F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0036[ 36] = { /* code 0036, DIGIT SIX */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xF0,
+  0x18, 0x00,
+  0x30, 0x00,
+  0x3F, 0xE0,
+  0x70, 0x34,
+  0x70, 0x24,
+  0x30, 0x24,
+  0x24, 0x70,
+  0x0F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0037[ 36] = { /* code 0037, DIGIT SEVEN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xFC,
+  0x00, 0x28,
+  0x00, 0x30,
+  0x00, 0xA0,
+  0x00, 0xD0,
+  0x01, 0x80,
+  0x03, 0x40,
+  0x07, 0x00,
+  0x0D, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0038[ 36] = { /* code 0038, DIGIT EIGHT */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xD0,
+  0x30, 0x30,
+  0x30, 0x30,
+  0x2C, 0x90,
+  0x0B, 0x80,
+  0x34, 0x70,
+  0x60, 0x24,
+  0x70, 0x34,
+  0x2F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0039[ 36] = { /* code 0039, DIGIT NINE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xC0,
+  0x70, 0x70,
+  0x60, 0x30,
+  0x70, 0x34,
+  0x2F, 0xF4,
+  0x00, 0x34,
+  0x00, 0x70,
+  0x00, 0xD0,
+  0x3F, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_003A[ 18] = { /* code 003A, COLON */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x28,
+  0x28,
+  0x00,
+  0x00,
+  0x00,
+  0x28,
+  0x28,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibri18_AA2_003B[ 18] = { /* code 003B, SEMICOLON */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x28,
+  0x28,
+  0x00,
+  0x00,
+  0x00,
+  0x18,
+  0x18,
+  0x24,
+  0x60,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibri18_AA2_003C[ 36] = { /* code 003C, LESS-THAN SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x18,
+  0x01, 0xD0,
+  0x1E, 0x00,
+  0x60, 0x00,
+  0x1E, 0x00,
+  0x01, 0xD0,
+  0x00, 0x18,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_003D[ 36] = { /* code 003D, EQUALS SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_003E[ 36] = { /* code 003E, GREATER-THAN SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x70, 0x00,
+  0x0F, 0x00,
+  0x00, 0xF0,
+  0x00, 0x1C,
+  0x00, 0xF0,
+  0x0F, 0x00,
+  0x70, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_003F[ 36] = { /* code 003F, QUESTION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xC0,
+  0x20, 0x70,
+  0x00, 0x34,
+  0x00, 0x70,
+  0x07, 0xD0,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x00, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0040[ 72] = { /* code 0040, COMMERCIAL AT */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x7F, 0xF0, 0x00,
+  0x02, 0xC0, 0x1D, 0x00,
+  0x0A, 0x00, 0x07, 0x00,
+  0x0C, 0x3E, 0x83, 0x00,
+  0x18, 0x91, 0x83, 0x00,
+  0x24, 0xC1, 0x43, 0x00,
+  0x24, 0xC3, 0x49, 0x00,
+  0x24, 0xBD, 0xF8, 0x00,
+  0x18, 0x00, 0x00, 0x00,
+  0x0A, 0x00, 0x00, 0x00,
+  0x02, 0xFF, 0xC0, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0041[ 54] = { /* code 0041, LATIN CAPITAL LETTER A */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x02, 0xD0, 0x00,
+  0x03, 0xA0, 0x00,
+  0x06, 0x30, 0x00,
+  0x09, 0x24, 0x00,
+  0x0C, 0x18, 0x00,
+  0x18, 0x0C, 0x00,
+  0x2F, 0xFD, 0x00,
+  0x70, 0x07, 0x00,
+  0xA0, 0x03, 0x40,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0042[ 36] = { /* code 0042, LATIN CAPITAL LETTER B */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0xF0,
+  0x24, 0x28,
+  0x24, 0x18,
+  0x24, 0x24,
+  0x2F, 0xF0,
+  0x24, 0x1C,
+  0x24, 0x0D,
+  0x24, 0x1C,
+  0x2F, 0xF4,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0043[ 36] = { /* code 0043, LATIN CAPITAL LETTER C */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0xF8,
+  0x1C, 0x05,
+  0x34, 0x00,
+  0x30, 0x00,
+  0x70, 0x00,
+  0x70, 0x00,
+  0x34, 0x00,
+  0x1C, 0x05,
+  0x07, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0044[ 54] = { /* code 0044, LATIN CAPITAL LETTER D */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x2F, 0xF4, 0x00,
+  0x24, 0x1D, 0x00,
+  0x24, 0x07, 0x00,
+  0x24, 0x03, 0x40,
+  0x24, 0x03, 0x40,
+  0x24, 0x03, 0x40,
+  0x24, 0x07, 0x00,
+  0x24, 0x0D, 0x00,
+  0x2F, 0xF0, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0045[ 36] = { /* code 0045, LATIN CAPITAL LETTER E */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0xF4,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x2F, 0xF0,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x2F, 0xF4,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0046[ 36] = { /* code 0046, LATIN CAPITAL LETTER F */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0xF4,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x2F, 0xF0,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0047[ 54] = { /* code 0047, LATIN CAPITAL LETTER G */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x03, 0xFD, 0x00,
+  0x1D, 0x02, 0x00,
+  0x34, 0x00, 0x00,
+  0x70, 0x00, 0x00,
+  0x70, 0x7F, 0x00,
+  0x70, 0x07, 0x00,
+  0x34, 0x07, 0x00,
+  0x1D, 0x07, 0x00,
+  0x03, 0xFD, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0048[ 54] = { /* code 0048, LATIN CAPITAL LETTER H */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x24, 0x06, 0x00,
+  0x24, 0x06, 0x00,
+  0x24, 0x06, 0x00,
+  0x24, 0x06, 0x00,
+  0x2F, 0xFE, 0x00,
+  0x24, 0x06, 0x00,
+  0x24, 0x06, 0x00,
+  0x24, 0x06, 0x00,
+  0x24, 0x06, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0049[ 18] = { /* code 0049, LATIN CAPITAL LETTER I */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x28,
+  0x28,
+  0x28,
+  0x28,
+  0x28,
+  0x28,
+  0x28,
+  0x28,
+  0x28,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibri18_AA2_004A[ 36] = { /* code 004A, LATIN CAPITAL LETTER J */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x0A, 0x00,
+  0xFC, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_004B[ 36] = { /* code 004B, LATIN CAPITAL LETTER K */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x24, 0x1C,
+  0x24, 0x34,
+  0x24, 0xD0,
+  0x26, 0x40,
+  0x2F, 0x00,
+  0x25, 0xC0,
+  0x24, 0xA0,
+  0x24, 0x34,
+  0x24, 0x0D,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_004C[ 36] = { /* code 004C, LATIN CAPITAL LETTER L */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x2F, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_004D[ 54] = { /* code 004D, LATIN CAPITAL LETTER M */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x2D, 0x00, 0x78,
+  0x2E, 0x00, 0xA8,
+  0x27, 0x00, 0xD8,
+  0x26, 0x41, 0x98,
+  0x25, 0xC3, 0x18,
+  0x24, 0xD6, 0x18,
+  0x24, 0x69, 0x18,
+  0x24, 0x3C, 0x18,
+  0x24, 0x28, 0x18,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_004E[ 54] = { /* code 004E, LATIN CAPITAL LETTER N */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x2D, 0x01, 0x80,
+  0x2F, 0x01, 0x80,
+  0x26, 0x81, 0x80,
+  0x24, 0xC1, 0x80,
+  0x24, 0xA1, 0x80,
+  0x24, 0x35, 0x80,
+  0x24, 0x1E, 0x80,
+  0x24, 0x0B, 0x80,
+  0x24, 0x03, 0x80,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_004F[ 54] = { /* code 004F, LATIN CAPITAL LETTER O */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x03, 0xFD, 0x00,
+  0x1D, 0x03, 0x40,
+  0x24, 0x01, 0xC0,
+  0x30, 0x00, 0xC0,
+  0x30, 0x00, 0xD0,
+  0x30, 0x00, 0xC0,
+  0x34, 0x01, 0xC0,
+  0x1C, 0x03, 0x40,
+  0x07, 0xFC, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0050[ 36] = { /* code 0050, LATIN CAPITAL LETTER P */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0xF0,
+  0x24, 0x1C,
+  0x24, 0x0D,
+  0x24, 0x0C,
+  0x24, 0x28,
+  0x2F, 0xE0,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0051[ 54] = { /* code 0051, LATIN CAPITAL LETTER Q */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x03, 0xFD, 0x00,
+  0x1C, 0x03, 0x40,
+  0x34, 0x01, 0x80,
+  0x30, 0x00, 0xC0,
+  0x70, 0x00, 0xC0,
+  0x30, 0x00, 0xC0,
+  0x34, 0x01, 0x80,
+  0x1C, 0x07, 0x40,
+  0x07, 0xFF, 0xC0,
+  0x00, 0x00, 0x70,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0052[ 36] = { /* code 0052, LATIN CAPITAL LETTER R */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0xF0,
+  0x24, 0x28,
+  0x24, 0x18,
+  0x24, 0x28,
+  0x2F, 0xD0,
+  0x24, 0x70,
+  0x24, 0x24,
+  0x24, 0x1C,
+  0x24, 0x0D,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0053[ 36] = { /* code 0053, LATIN CAPITAL LETTER S */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xD0,
+  0x34, 0x20,
+  0x30, 0x00,
+  0x2C, 0x00,
+  0x0B, 0xC0,
+  0x00, 0x70,
+  0x00, 0x24,
+  0x50, 0x70,
+  0x2F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0054[ 36] = { /* code 0054, LATIN CAPITAL LETTER T */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xFF, 0xFC,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0055[ 54] = { /* code 0055, LATIN CAPITAL LETTER U */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x24, 0x06, 0x00,
+  0x24, 0x06, 0x00,
+  0x24, 0x06, 0x00,
+  0x24, 0x06, 0x00,
+  0x24, 0x06, 0x00,
+  0x24, 0x06, 0x00,
+  0x24, 0x06, 0x00,
+  0x1C, 0x0D, 0x00,
+  0x07, 0xF4, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0056[ 54] = { /* code 0056, LATIN CAPITAL LETTER V */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x70, 0x02, 0x40,
+  0x34, 0x07, 0x00,
+  0x28, 0x0A, 0x00,
+  0x1C, 0x0D, 0x00,
+  0x0D, 0x18, 0x00,
+  0x06, 0x24, 0x00,
+  0x03, 0x70, 0x00,
+  0x02, 0xE0, 0x00,
+  0x01, 0xD0, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0057[ 72] = { /* code 0057, LATIN CAPITAL LETTER W */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x60, 0x0D, 0x01, 0x80,
+  0x30, 0x1E, 0x02, 0x40,
+  0x24, 0x2B, 0x03, 0x00,
+  0x18, 0x37, 0x47, 0x00,
+  0x1C, 0x22, 0x46, 0x00,
+  0x0D, 0x61, 0x89, 0x00,
+  0x09, 0x90, 0xDC, 0x00,
+  0x07, 0xC0, 0xB8, 0x00,
+  0x03, 0x80, 0x74, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0058[ 36] = { /* code 0058, LATIN CAPITAL LETTER X */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x70, 0x0C,
+  0x28, 0x24,
+  0x0D, 0x70,
+  0x07, 0xD0,
+  0x03, 0x80,
+  0x0A, 0xD0,
+  0x0C, 0x70,
+  0x24, 0x28,
+  0x70, 0x0D,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0059[ 36] = { /* code 0059, LATIN CAPITAL LETTER Y */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xA0, 0x28,
+  0x70, 0x30,
+  0x28, 0xA0,
+  0x0D, 0xC0,
+  0x0B, 0x80,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_005A[ 36] = { /* code 005A, LATIN CAPITAL LETTER Z */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xF4,
+  0x00, 0x30,
+  0x00, 0x90,
+  0x01, 0x80,
+  0x03, 0x00,
+  0x09, 0x00,
+  0x18, 0x00,
+  0x30, 0x00,
+  0x7F, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_005B[ 36] = { /* code 005B, LEFT SQUARE BRACKET */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x2F, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_005C[ 36] = { /* code 005C, REVERSE SOLIDUS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x90, 0x00,
+  0x60, 0x00,
+  0x30, 0x00,
+  0x24, 0x00,
+  0x18, 0x00,
+  0x0C, 0x00,
+  0x09, 0x00,
+  0x06, 0x00,
+  0x03, 0x40,
+  0x02, 0x80,
+  0x01, 0xC0,
+  0x00, 0x90,
+  0x00, 0x60,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_005D[ 36] = { /* code 005D, RIGHT SQUARE BRACKET */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7C, 0x00,
+  0x0C, 0x00,
+  0x0C, 0x00,
+  0x0C, 0x00,
+  0x0C, 0x00,
+  0x0C, 0x00,
+  0x0C, 0x00,
+  0x0C, 0x00,
+  0x0C, 0x00,
+  0x0C, 0x00,
+  0x0C, 0x00,
+  0x7C, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_005E[ 36] = { /* code 005E, CIRCUMFLEX ACCENT */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0x40,
+  0x0A, 0xC0,
+  0x0C, 0x90,
+  0x28, 0x30,
+  0x30, 0x24,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_005F[ 36] = { /* code 005F, LOW LINE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xFF, 0xFC,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0060[ 18] = { /* code 0060, GRAVE ACCENT */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x24,
+  0x09,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibri18_AA2_0061[ 36] = { /* code 0061, LATIN SMALL LETTER A */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xD0,
+  0x20, 0x60,
+  0x00, 0x30,
+  0x1F, 0xF0,
+  0x70, 0x30,
+  0x70, 0xB0,
+  0x2F, 0xA0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0062[ 36] = { /* code 0062, LATIN SMALL LETTER B */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x27, 0xF0,
+  0x2C, 0x1C,
+  0x24, 0x0C,
+  0x24, 0x0D,
+  0x24, 0x0C,
+  0x2C, 0x18,
+  0x27, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0063[ 36] = { /* code 0063, LATIN SMALL LETTER C */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xD0,
+  0x34, 0x20,
+  0x70, 0x00,
+  0x60, 0x00,
+  0x70, 0x00,
+  0x34, 0x20,
+  0x0F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0064[ 36] = { /* code 0064, LATIN SMALL LETTER D */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x18,
+  0x00, 0x18,
+  0x00, 0x18,
+  0x0F, 0xD8,
+  0x24, 0x38,
+  0x30, 0x18,
+  0x70, 0x18,
+  0x30, 0x18,
+  0x34, 0x38,
+  0x0F, 0xD8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0065[ 36] = { /* code 0065, LATIN SMALL LETTER E */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xF0,
+  0x28, 0x18,
+  0x30, 0x0C,
+  0x3F, 0xFC,
+  0x30, 0x00,
+  0x24, 0x00,
+  0x0B, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0066[ 36] = { /* code 0066, LATIN SMALL LETTER F */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0x80,
+  0x1C, 0x00,
+  0x18, 0x00,
+  0x7F, 0x80,
+  0x18, 0x00,
+  0x18, 0x00,
+  0x18, 0x00,
+  0x18, 0x00,
+  0x18, 0x00,
+  0x18, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0067[ 36] = { /* code 0067, LATIN SMALL LETTER G */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xF8,
+  0x30, 0x60,
+  0x30, 0x60,
+  0x30, 0xA0,
+  0x3F, 0xC0,
+  0x60, 0x00,
+  0x2F, 0xE0,
+  0x60, 0x24,
+  0xA0, 0x24,
+  0x2F, 0xD0,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0068[ 36] = { /* code 0068, LATIN SMALL LETTER H */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x27, 0xF0,
+  0x2C, 0x28,
+  0x24, 0x18,
+  0x24, 0x18,
+  0x24, 0x18,
+  0x24, 0x18,
+  0x24, 0x18,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0069[ 18] = { /* code 0069, LATIN SMALL LETTER I */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x28,
+  0x00,
+  0x28,
+  0x28,
+  0x28,
+  0x28,
+  0x28,
+  0x28,
+  0x28,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibri18_AA2_006A[ 18] = { /* code 006A, LATIN SMALL LETTER J */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x28,
+  0x00,
+  0x18,
+  0x18,
+  0x18,
+  0x18,
+  0x18,
+  0x18,
+  0x18,
+  0x18,
+  0x24,
+  0xF0,
+  0x00
+};
+
+const uint8_t FontCalibri18_AA2_006B[ 36] = { /* code 006B, LATIN SMALL LETTER K */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x70,
+  0x25, 0xC0,
+  0x27, 0x00,
+  0x2F, 0x00,
+  0x25, 0x80,
+  0x24, 0xA0,
+  0x24, 0x34,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_006C[ 18] = { /* code 006C, LATIN SMALL LETTER L */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x28,
+  0x28,
+  0x28,
+  0x28,
+  0x28,
+  0x28,
+  0x28,
+  0x28,
+  0x28,
+  0x28,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibri18_AA2_006D[ 54] = { /* code 006D, LATIN SMALL LETTER M */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x27, 0xF2, 0xF0,
+  0x2C, 0x2D, 0x18,
+  0x24, 0x18, 0x1C,
+  0x24, 0x18, 0x1C,
+  0x24, 0x18, 0x1C,
+  0x24, 0x18, 0x1C,
+  0x24, 0x18, 0x1C,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_006E[ 36] = { /* code 006E, LATIN SMALL LETTER N */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x27, 0xF0,
+  0x2C, 0x28,
+  0x24, 0x18,
+  0x24, 0x18,
+  0x24, 0x18,
+  0x24, 0x18,
+  0x24, 0x18,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_006F[ 36] = { /* code 006F, LATIN SMALL LETTER O */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xF0,
+  0x28, 0x1C,
+  0x30, 0x0C,
+  0x70, 0x09,
+  0x30, 0x0C,
+  0x28, 0x18,
+  0x0F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0070[ 36] = { /* code 0070, LATIN SMALL LETTER P */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x27, 0xF0,
+  0x2C, 0x1C,
+  0x24, 0x0C,
+  0x24, 0x0D,
+  0x24, 0x0C,
+  0x2C, 0x18,
+  0x27, 0xF0,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0071[ 36] = { /* code 0071, LATIN SMALL LETTER Q */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xD8,
+  0x24, 0x38,
+  0x30, 0x18,
+  0x70, 0x18,
+  0x30, 0x18,
+  0x34, 0x38,
+  0x0F, 0xD8,
+  0x00, 0x18,
+  0x00, 0x18,
+  0x00, 0x18,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0072[ 36] = { /* code 0072, LATIN SMALL LETTER R */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x37, 0xC0,
+  0x3C, 0x00,
+  0x34, 0x00,
+  0x34, 0x00,
+  0x34, 0x00,
+  0x34, 0x00,
+  0x34, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0073[ 36] = { /* code 0073, LATIN SMALL LETTER S */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xC0,
+  0x30, 0x00,
+  0x34, 0x00,
+  0x0F, 0x40,
+  0x00, 0xD0,
+  0x00, 0x90,
+  0x7F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0074[ 36] = { /* code 0074, LATIN SMALL LETTER T */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x18, 0x00,
+  0x18, 0x00,
+  0xBF, 0x40,
+  0x18, 0x00,
+  0x18, 0x00,
+  0x18, 0x00,
+  0x18, 0x00,
+  0x18, 0x00,
+  0x0F, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0075[ 36] = { /* code 0075, LATIN SMALL LETTER U */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x24, 0x18,
+  0x24, 0x18,
+  0x24, 0x18,
+  0x24, 0x18,
+  0x24, 0x18,
+  0x28, 0x38,
+  0x0F, 0xD8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0076[ 36] = { /* code 0076, LATIN SMALL LETTER V */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xA0, 0x24,
+  0x70, 0x30,
+  0x34, 0x60,
+  0x28, 0x90,
+  0x0D, 0xC0,
+  0x0B, 0x80,
+  0x07, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0077[ 54] = { /* code 0077, LATIN SMALL LETTER W */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x60, 0x70, 0x34,
+  0x30, 0x74, 0x30,
+  0x34, 0x94, 0x60,
+  0x24, 0x48, 0x90,
+  0x19, 0x49, 0x80,
+  0x0E, 0x4A, 0x80,
+  0x0B, 0x07, 0x40,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0078[ 36] = { /* code 0078, LATIN SMALL LETTER X */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x30, 0x30,
+  0x18, 0x90,
+  0x0F, 0x80,
+  0x07, 0x40,
+  0x0D, 0xC0,
+  0x28, 0xA0,
+  0x70, 0x30,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_0079[ 36] = { /* code 0079, LATIN SMALL LETTER Y */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xA0, 0x24,
+  0x70, 0x30,
+  0x34, 0x60,
+  0x18, 0x90,
+  0x0D, 0xC0,
+  0x0B, 0x80,
+  0x07, 0x40,
+  0x07, 0x00,
+  0x0A, 0x00,
+  0x0D, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_007A[ 36] = { /* code 007A, LATIN SMALL LETTER Z */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xC0,
+  0x01, 0x80,
+  0x03, 0x00,
+  0x0A, 0x00,
+  0x1C, 0x00,
+  0x34, 0x00,
+  0x7F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_007B[ 36] = { /* code 007B, LEFT CURLY BRACKET */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0x40,
+  0x0C, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x18, 0x00,
+  0x60, 0x00,
+  0x18, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x0C, 0x00,
+  0x0B, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_007C[ 36] = { /* code 007C, VERTICAL LINE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_007D[ 36] = { /* code 007D, RIGHT CURLY BRACKET */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x38, 0x00,
+  0x0C, 0x00,
+  0x0C, 0x00,
+  0x0C, 0x00,
+  0x09, 0x00,
+  0x02, 0x40,
+  0x09, 0x00,
+  0x08, 0x00,
+  0x0C, 0x00,
+  0x0C, 0x00,
+  0x0C, 0x00,
+  0x38, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA2_007E[ 36] = { /* code 007E, TILDE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3D, 0x18,
+  0x52, 0x14,
+  0x91, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const aafontsCharInfo_t charTable_Calibri18_AA2[95] = 
+{
+  {   3,   1, FontCalibri18_AA2_0020 }, /* code 0020 */
+  {   5,   2, FontCalibri18_AA2_0021 }, /* code 0021 */
+  {   6,   2, FontCalibri18_AA2_0022 }, /* code 0022 */
+  {   7,   2, FontCalibri18_AA2_0023 }, /* code 0023 */
+  {   7,   2, FontCalibri18_AA2_0024 }, /* code 0024 */
+  {  11,   3, FontCalibri18_AA2_0025 }, /* code 0025 */
+  {  10,   3, FontCalibri18_AA2_0026 }, /* code 0026 */
+  {   3,   1, FontCalibri18_AA2_0027 }, /* code 0027 */
+  {   5,   2, FontCalibri18_AA2_0028 }, /* code 0028 */
+  {   5,   2, FontCalibri18_AA2_0029 }, /* code 0029 */
+  {   7,   2, FontCalibri18_AA2_002A }, /* code 002A */
+  {   7,   2, FontCalibri18_AA2_002B }, /* code 002B */
+  {   4,   1, FontCalibri18_AA2_002C }, /* code 002C */
+  {   5,   2, FontCalibri18_AA2_002D }, /* code 002D */
+  {   4,   1, FontCalibri18_AA2_002E }, /* code 002E */
+  {   6,   2, FontCalibri18_AA2_002F }, /* code 002F */
+  {   7,   2, FontCalibri18_AA2_0030 }, /* code 0030 */
+  {   7,   2, FontCalibri18_AA2_0031 }, /* code 0031 */
+  {   7,   2, FontCalibri18_AA2_0032 }, /* code 0032 */
+  {   7,   2, FontCalibri18_AA2_0033 }, /* code 0033 */
+  {   7,   2, FontCalibri18_AA2_0034 }, /* code 0034 */
+  {   7,   2, FontCalibri18_AA2_0035 }, /* code 0035 */
+  {   7,   2, FontCalibri18_AA2_0036 }, /* code 0036 */
+  {   7,   2, FontCalibri18_AA2_0037 }, /* code 0037 */
+  {   7,   2, FontCalibri18_AA2_0038 }, /* code 0038 */
+  {   7,   2, FontCalibri18_AA2_0039 }, /* code 0039 */
+  {   4,   1, FontCalibri18_AA2_003A }, /* code 003A */
+  {   4,   1, FontCalibri18_AA2_003B }, /* code 003B */
+  {   7,   2, FontCalibri18_AA2_003C }, /* code 003C */
+  {   7,   2, FontCalibri18_AA2_003D }, /* code 003D */
+  {   7,   2, FontCalibri18_AA2_003E }, /* code 003E */
+  {   7,   2, FontCalibri18_AA2_003F }, /* code 003F */
+  {  13,   4, FontCalibri18_AA2_0040 }, /* code 0040 */
+  {   9,   3, FontCalibri18_AA2_0041 }, /* code 0041 */
+  {   8,   2, FontCalibri18_AA2_0042 }, /* code 0042 */
+  {   8,   2, FontCalibri18_AA2_0043 }, /* code 0043 */
+  {   9,   3, FontCalibri18_AA2_0044 }, /* code 0044 */
+  {   7,   2, FontCalibri18_AA2_0045 }, /* code 0045 */
+  {   7,   2, FontCalibri18_AA2_0046 }, /* code 0046 */
+  {   9,   3, FontCalibri18_AA2_0047 }, /* code 0047 */
+  {   9,   3, FontCalibri18_AA2_0048 }, /* code 0048 */
+  {   4,   1, FontCalibri18_AA2_0049 }, /* code 0049 */
+  {   5,   2, FontCalibri18_AA2_004A }, /* code 004A */
+  {   8,   2, FontCalibri18_AA2_004B }, /* code 004B */
+  {   6,   2, FontCalibri18_AA2_004C }, /* code 004C */
+  {  12,   3, FontCalibri18_AA2_004D }, /* code 004D */
+  {  10,   3, FontCalibri18_AA2_004E }, /* code 004E */
+  {  10,   3, FontCalibri18_AA2_004F }, /* code 004F */
+  {   8,   2, FontCalibri18_AA2_0050 }, /* code 0050 */
+  {  10,   3, FontCalibri18_AA2_0051 }, /* code 0051 */
+  {   8,   2, FontCalibri18_AA2_0052 }, /* code 0052 */
+  {   7,   2, FontCalibri18_AA2_0053 }, /* code 0053 */
+  {   7,   2, FontCalibri18_AA2_0054 }, /* code 0054 */
+  {   9,   3, FontCalibri18_AA2_0055 }, /* code 0055 */
+  {   9,   3, FontCalibri18_AA2_0056 }, /* code 0056 */
+  {  13,   4, FontCalibri18_AA2_0057 }, /* code 0057 */
+  {   8,   2, FontCalibri18_AA2_0058 }, /* code 0058 */
+  {   7,   2, FontCalibri18_AA2_0059 }, /* code 0059 */
+  {   7,   2, FontCalibri18_AA2_005A }, /* code 005A */
+  {   5,   2, FontCalibri18_AA2_005B }, /* code 005B */
+  {   6,   2, FontCalibri18_AA2_005C }, /* code 005C */
+  {   5,   2, FontCalibri18_AA2_005D }, /* code 005D */
+  {   7,   2, FontCalibri18_AA2_005E }, /* code 005E */
+  {   7,   2, FontCalibri18_AA2_005F }, /* code 005F */
+  {   4,   1, FontCalibri18_AA2_0060 }, /* code 0060 */
+  {   7,   2, FontCalibri18_AA2_0061 }, /* code 0061 */
+  {   8,   2, FontCalibri18_AA2_0062 }, /* code 0062 */
+  {   6,   2, FontCalibri18_AA2_0063 }, /* code 0063 */
+  {   8,   2, FontCalibri18_AA2_0064 }, /* code 0064 */
+  {   8,   2, FontCalibri18_AA2_0065 }, /* code 0065 */
+  {   5,   2, FontCalibri18_AA2_0066 }, /* code 0066 */
+  {   7,   2, FontCalibri18_AA2_0067 }, /* code 0067 */
+  {   8,   2, FontCalibri18_AA2_0068 }, /* code 0068 */
+  {   4,   1, FontCalibri18_AA2_0069 }, /* code 0069 */
+  {   4,   1, FontCalibri18_AA2_006A }, /* code 006A */
+  {   7,   2, FontCalibri18_AA2_006B }, /* code 006B */
+  {   4,   1, FontCalibri18_AA2_006C }, /* code 006C */
+  {  12,   3, FontCalibri18_AA2_006D }, /* code 006D */
+  {   8,   2, FontCalibri18_AA2_006E }, /* code 006E */
+  {   8,   2, FontCalibri18_AA2_006F }, /* code 006F */
+  {   8,   2, FontCalibri18_AA2_0070 }, /* code 0070 */
+  {   8,   2, FontCalibri18_AA2_0071 }, /* code 0071 */
+  {   5,   2, FontCalibri18_AA2_0072 }, /* code 0072 */
+  {   6,   2, FontCalibri18_AA2_0073 }, /* code 0073 */
+  {   5,   2, FontCalibri18_AA2_0074 }, /* code 0074 */
+  {   8,   2, FontCalibri18_AA2_0075 }, /* code 0075 */
+  {   7,   2, FontCalibri18_AA2_0076 }, /* code 0076 */
+  {  11,   3, FontCalibri18_AA2_0077 }, /* code 0077 */
+  {   7,   2, FontCalibri18_AA2_0078 }, /* code 0078 */
+  {   7,   2, FontCalibri18_AA2_0079 }, /* code 0079 */
+  {   6,   2, FontCalibri18_AA2_007A }, /* code 007A */
+  {   5,   2, FontCalibri18_AA2_007B }, /* code 007B */
+  {   7,   2, FontCalibri18_AA2_007C }, /* code 007C */
+  {   5,   2, FontCalibri18_AA2_007D }, /* code 007D */
+  {   7,   2, FontCalibri18_AA2_007E }  /* code 007E */
+};
+
+aafontsFont_t FontCalibri18_AA2 = 
+{
+  AAFONTS_FONTTYPE_AA2,                 /* Font type (anti-aliasing level) */
+  18,                                   /* Font height in pixels */
+  3,                                    /* Width to insert for unknown characters */
+  9,                                    /* Height of upper-case characters */
+  7,                                    /* Height of lower-case characters */
+  14,                                   /* Font baseline */
+  0x0020,                               /* Unicode address of first character */
+  0x007E,                               /* Unicode address of last character */
+  &charTable_Calibri18_AA2[0]           /* Font char data */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontCalibri18_AA2.h b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontCalibri18_AA2.h
new file mode 100644
index 0000000000000000000000000000000000000000..05a68409da7c358225a9d9e6f116224a5e2cc23a
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontCalibri18_AA2.h
@@ -0,0 +1,52 @@
+/**************************************************************************/
+/*! 
+    @file     FontCalibri18_AA2.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __FONTCALIBRI18_AA2_H__
+#define __FONTCALIBRI18_AA2_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "drivers/displays/graphic/aafonts.h"
+
+extern aafontsFont_t FontCalibri18_AA2;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontCalibriBold18_AA2.c b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontCalibriBold18_AA2.c
new file mode 100644
index 0000000000000000000000000000000000000000..2ca3381069e6c59a3cdbbdd7b37d34a5f4eec4cb
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontCalibriBold18_AA2.c
@@ -0,0 +1,2144 @@
+/**************************************************************************/
+/*! 
+    @file     FontCalibriBold18_AA2.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "FontCalibriBold18_AA2.h"
+
+/* Start of unicode area <Basic Latin> */
+const uint8_t FontCalibriBold18_AA2_0020[ 18] = { /* code 0020, SPACE */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0021[ 36] = { /* code 0021, EXCLAMATION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x0D, 0x00,
+  0x00, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0022[ 36] = { /* code 0022, QUOTATION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x38, 0xE0,
+  0x38, 0xE0,
+  0x24, 0x90,
+  0x24, 0x90,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0023[ 36] = { /* code 0023, NUMBER SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0D, 0x34,
+  0x0C, 0x34,
+  0x7F, 0xFC,
+  0x1C, 0x70,
+  0x18, 0x70,
+  0x28, 0x70,
+  0xBF, 0xF8,
+  0x24, 0xA0,
+  0x34, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0024[ 36] = { /* code 0024, DOLLAR SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x02, 0x80,
+  0x02, 0x40,
+  0x1F, 0xD0,
+  0x3C, 0x20,
+  0x38, 0x00,
+  0x3E, 0x00,
+  0x0F, 0xE0,
+  0x00, 0xF4,
+  0x00, 0x74,
+  0x50, 0xB4,
+  0x2F, 0xD0,
+  0x0A, 0x00,
+  0x0A, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0025[ 54] = { /* code 0025, PERCENT SIGN */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x2F, 0x00, 0xD0,
+  0x72, 0x82, 0x80,
+  0x62, 0x87, 0x00,
+  0x72, 0x8D, 0x00,
+  0x3F, 0x78, 0x00,
+  0x00, 0xA3, 0xF0,
+  0x01, 0xCA, 0x34,
+  0x03, 0x4A, 0x24,
+  0x0A, 0x0A, 0x34,
+  0x1C, 0x03, 0xE0,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0026[ 54] = { /* code 0026, AMPERSAND */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x07, 0xFC, 0x00,
+  0x1E, 0x1E, 0x00,
+  0x1E, 0x1D, 0x00,
+  0x0F, 0xF8, 0x00,
+  0x0F, 0xD1, 0xD0,
+  0x3D, 0xF5, 0xD0,
+  0x78, 0x2F, 0xC0,
+  0x3C, 0x1F, 0xC0,
+  0x0F, 0xF8, 0xB0,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0027[ 18] = { /* code 0027, APOSTROPHE */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x28,
+  0x28,
+  0x28,
+  0x28,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0028[ 36] = { /* code 0028, LEFT PARENTHESIS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0x00,
+  0x0E, 0x00,
+  0x1D, 0x00,
+  0x2C, 0x00,
+  0x3C, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x3C, 0x00,
+  0x2C, 0x00,
+  0x1D, 0x00,
+  0x0E, 0x00,
+  0x0B, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0029[ 36] = { /* code 0029, RIGHT PARENTHESIS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x38, 0x00,
+  0x2C, 0x00,
+  0x1D, 0x00,
+  0x0E, 0x00,
+  0x0F, 0x00,
+  0x0B, 0x00,
+  0x0B, 0x00,
+  0x0B, 0x00,
+  0x0F, 0x00,
+  0x0E, 0x00,
+  0x1D, 0x00,
+  0x2C, 0x00,
+  0x38, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_002A[ 36] = { /* code 002A, ASTERISK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0x00,
+  0x3A, 0xB0,
+  0x07, 0x40,
+  0x3A, 0xB0,
+  0x03, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_002B[ 36] = { /* code 002B, PLUS SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0x40,
+  0x03, 0x40,
+  0x03, 0x40,
+  0xBF, 0xFC,
+  0x03, 0x40,
+  0x03, 0x40,
+  0x03, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_002C[ 18] = { /* code 002C, COMMA */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x2C,
+  0x2C,
+  0x34,
+  0xA0,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_002D[ 36] = { /* code 002D, HYPHEN-MINUS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_002E[ 18] = { /* code 002E, FULL STOP */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x3C,
+  0x3C,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_002F[ 36] = { /* code 002F, SOLIDUS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0xE0,
+  0x01, 0xD0,
+  0x02, 0xC0,
+  0x03, 0x80,
+  0x07, 0x40,
+  0x0B, 0x00,
+  0x0E, 0x00,
+  0x1D, 0x00,
+  0x2C, 0x00,
+  0x38, 0x00,
+  0x74, 0x00,
+  0xB0, 0x00,
+  0xE0, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0030[ 36] = { /* code 0030, DIGIT ZERO */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xD0,
+  0x38, 0xB4,
+  0x74, 0x78,
+  0xB4, 0x38,
+  0xB4, 0x38,
+  0xB4, 0x38,
+  0x74, 0x74,
+  0x38, 0xB0,
+  0x1F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0031[ 36] = { /* code 0031, DIGIT ONE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0x80,
+  0x2F, 0x80,
+  0x37, 0x80,
+  0x03, 0x80,
+  0x03, 0x80,
+  0x03, 0x80,
+  0x03, 0x80,
+  0x03, 0x80,
+  0x3F, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0032[ 36] = { /* code 0032, DIGIT TWO */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xD0,
+  0x60, 0xB4,
+  0x00, 0x74,
+  0x00, 0xB4,
+  0x01, 0xE0,
+  0x03, 0xC0,
+  0x0F, 0x00,
+  0x3C, 0x00,
+  0x7F, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0033[ 36] = { /* code 0033, DIGIT THREE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xD0,
+  0x20, 0xF0,
+  0x00, 0xF0,
+  0x01, 0xE0,
+  0x1F, 0xC0,
+  0x00, 0xF4,
+  0x00, 0xB4,
+  0x50, 0xB0,
+  0x1F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0034[ 36] = { /* code 0034, DIGIT FOUR */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x02, 0xF0,
+  0x07, 0xF0,
+  0x0D, 0xB0,
+  0x1C, 0xB0,
+  0x34, 0xB0,
+  0xB0, 0xB0,
+  0xBF, 0xFC,
+  0x00, 0xB0,
+  0x00, 0xB0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0035[ 36] = { /* code 0035, DIGIT FIVE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xF0,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x3F, 0xE0,
+  0x00, 0xB4,
+  0x00, 0xB4,
+  0x50, 0xF0,
+  0x1F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0036[ 36] = { /* code 0036, DIGIT SIX */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xF0,
+  0x2C, 0x00,
+  0x34, 0x00,
+  0x7F, 0xE0,
+  0x74, 0x74,
+  0x74, 0x38,
+  0x74, 0x38,
+  0x38, 0x74,
+  0x1F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0037[ 36] = { /* code 0037, DIGIT SEVEN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xF4,
+  0x00, 0xB4,
+  0x00, 0xE0,
+  0x01, 0xD0,
+  0x03, 0xC0,
+  0x07, 0x80,
+  0x0B, 0x40,
+  0x0F, 0x00,
+  0x1D, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0038[ 36] = { /* code 0038, DIGIT EIGHT */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xE0,
+  0x74, 0xB4,
+  0x74, 0x74,
+  0x3D, 0xE0,
+  0x0F, 0xD0,
+  0x78, 0xF4,
+  0xB0, 0x78,
+  0x74, 0x74,
+  0x2F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0039[ 36] = { /* code 0039, DIGIT NINE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xD0,
+  0x34, 0xB0,
+  0x74, 0x74,
+  0xB4, 0x74,
+  0x74, 0x74,
+  0x2F, 0xF4,
+  0x00, 0x74,
+  0x00, 0xE0,
+  0x3F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_003A[ 18] = { /* code 003A, COLON */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x2C,
+  0x2C,
+  0x00,
+  0x00,
+  0x00,
+  0x2C,
+  0x2C,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_003B[ 18] = { /* code 003B, SEMICOLON */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x2C,
+  0x2C,
+  0x00,
+  0x00,
+  0x00,
+  0x2C,
+  0x2C,
+  0x38,
+  0x60,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_003C[ 36] = { /* code 003C, LESS-THAN SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x28,
+  0x02, 0xF4,
+  0x3F, 0xC0,
+  0xB0, 0x00,
+  0x3F, 0x80,
+  0x02, 0xF4,
+  0x00, 0x28,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_003D[ 36] = { /* code 003D, EQUALS SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_003E[ 36] = { /* code 003E, GREATER-THAN SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x30, 0x00,
+  0x3F, 0x00,
+  0x0B, 0xF0,
+  0x00, 0x38,
+  0x0B, 0xF0,
+  0x3F, 0x00,
+  0x30, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_003F[ 36] = { /* code 003F, QUESTION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xD0,
+  0x00, 0xB0,
+  0x00, 0x74,
+  0x00, 0xB0,
+  0x0B, 0xD0,
+  0x0B, 0x00,
+  0x0B, 0x00,
+  0x00, 0x00,
+  0x0B, 0x00,
+  0x0B, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0040[ 72] = { /* code 0040, COMMERCIAL AT */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x7F, 0xF0, 0x00,
+  0x03, 0x80, 0x2D, 0x00,
+  0x0E, 0x00, 0x0B, 0x00,
+  0x1C, 0x7E, 0xC7, 0x00,
+  0x28, 0xE3, 0xC7, 0x00,
+  0x35, 0xC3, 0x8B, 0x00,
+  0x35, 0xC7, 0x4D, 0x00,
+  0x34, 0xF9, 0xF8, 0x00,
+  0x28, 0x00, 0x00, 0x00,
+  0x1E, 0x00, 0x00, 0x00,
+  0x03, 0xFF, 0x80, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0041[ 54] = { /* code 0041, LATIN CAPITAL LETTER A */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x02, 0xF0, 0x00,
+  0x03, 0xF4, 0x00,
+  0x07, 0x78, 0x00,
+  0x0E, 0x2C, 0x00,
+  0x1D, 0x1D, 0x00,
+  0x2C, 0x0E, 0x00,
+  0x3F, 0xFF, 0x00,
+  0x74, 0x07, 0x40,
+  0xB0, 0x03, 0xC0,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0042[ 36] = { /* code 0042, LATIN CAPITAL LETTER B */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xF0,
+  0x38, 0x38,
+  0x38, 0x3C,
+  0x38, 0x38,
+  0x3F, 0xF4,
+  0x38, 0x2D,
+  0x38, 0x1D,
+  0x38, 0x2C,
+  0x3F, 0xF4,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0043[ 36] = { /* code 0043, LATIN CAPITAL LETTER C */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xF8,
+  0x1E, 0x05,
+  0x3C, 0x00,
+  0x78, 0x00,
+  0x78, 0x00,
+  0x78, 0x00,
+  0x3C, 0x00,
+  0x2E, 0x05,
+  0x07, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0044[ 54] = { /* code 0044, LATIN CAPITAL LETTER D */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x3F, 0xF4, 0x00,
+  0x38, 0x1E, 0x00,
+  0x38, 0x0B, 0x40,
+  0x38, 0x07, 0x40,
+  0x38, 0x07, 0x40,
+  0x38, 0x07, 0x40,
+  0x38, 0x0B, 0x00,
+  0x38, 0x1E, 0x00,
+  0x3F, 0xF4, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0045[ 36] = { /* code 0045, LATIN CAPITAL LETTER E */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xF8,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x3F, 0xF0,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x3F, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0046[ 36] = { /* code 0046, LATIN CAPITAL LETTER F */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0xF4,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x2F, 0xF0,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0047[ 54] = { /* code 0047, LATIN CAPITAL LETTER G */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x02, 0xFF, 0x00,
+  0x1F, 0x00, 0xC0,
+  0x3C, 0x00, 0x00,
+  0x78, 0x00, 0x00,
+  0x74, 0x3F, 0xC0,
+  0x78, 0x03, 0xC0,
+  0x3C, 0x03, 0xC0,
+  0x1E, 0x03, 0xC0,
+  0x03, 0xFF, 0x80,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0048[ 54] = { /* code 0048, LATIN CAPITAL LETTER H */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x38, 0x0B, 0x00,
+  0x38, 0x0B, 0x00,
+  0x38, 0x0B, 0x00,
+  0x38, 0x0B, 0x00,
+  0x3F, 0xFF, 0x00,
+  0x38, 0x0B, 0x00,
+  0x38, 0x0B, 0x00,
+  0x38, 0x0B, 0x00,
+  0x38, 0x0B, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0049[ 18] = { /* code 0049, LATIN CAPITAL LETTER I */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x3C,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_004A[ 36] = { /* code 004A, LATIN CAPITAL LETTER J */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0x00,
+  0x0F, 0x00,
+  0x0F, 0x00,
+  0x0F, 0x00,
+  0x0F, 0x00,
+  0x0F, 0x00,
+  0x0F, 0x00,
+  0x0E, 0x00,
+  0xFC, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_004B[ 36] = { /* code 004B, LATIN CAPITAL LETTER K */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3C, 0x1E,
+  0x3C, 0x3C,
+  0x3C, 0xB0,
+  0x3E, 0xD0,
+  0x3F, 0xC0,
+  0x3D, 0xE0,
+  0x3C, 0xB4,
+  0x3C, 0x3C,
+  0x3C, 0x1E,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_004C[ 36] = { /* code 004C, LATIN CAPITAL LETTER L */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x3F, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_004D[ 72] = { /* code 004D, LATIN CAPITAL LETTER M */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x3F, 0x40, 0x3F, 0x00,
+  0x3F, 0x80, 0x7F, 0x00,
+  0x3E, 0xC0, 0xEB, 0x00,
+  0x3D, 0xD1, 0xDB, 0x00,
+  0x3C, 0xA2, 0xCB, 0x00,
+  0x3C, 0x77, 0x8B, 0x00,
+  0x3C, 0x3F, 0x0B, 0x00,
+  0x3C, 0x2E, 0x0B, 0x00,
+  0x3C, 0x1D, 0x0B, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_004E[ 54] = { /* code 004E, LATIN CAPITAL LETTER N */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x2F, 0x02, 0xC0,
+  0x2F, 0x42, 0xC0,
+  0x2F, 0xC2, 0xC0,
+  0x29, 0xD2, 0xC0,
+  0x28, 0xF2, 0xC0,
+  0x28, 0x76, 0xC0,
+  0x28, 0x2E, 0xC0,
+  0x28, 0x0F, 0xC0,
+  0x28, 0x0B, 0xC0,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_004F[ 54] = { /* code 004F, LATIN CAPITAL LETTER O */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x03, 0xFE, 0x00,
+  0x1E, 0x07, 0x80,
+  0x3C, 0x02, 0xC0,
+  0x78, 0x02, 0xD0,
+  0x78, 0x01, 0xD0,
+  0x78, 0x02, 0xD0,
+  0x3C, 0x02, 0xC0,
+  0x2D, 0x07, 0x80,
+  0x07, 0xFD, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0050[ 36] = { /* code 0050, LATIN CAPITAL LETTER P */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xF4,
+  0x3C, 0x2D,
+  0x3C, 0x1D,
+  0x3C, 0x1D,
+  0x3C, 0x3C,
+  0x3F, 0xF0,
+  0x3C, 0x00,
+  0x3C, 0x00,
+  0x3C, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0051[ 54] = { /* code 0051, LATIN CAPITAL LETTER Q */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x07, 0xFD, 0x00,
+  0x1D, 0x07, 0x80,
+  0x3C, 0x03, 0xC0,
+  0x78, 0x02, 0xD0,
+  0x78, 0x02, 0xD0,
+  0x78, 0x02, 0xD0,
+  0x38, 0x03, 0xC0,
+  0x2D, 0x0B, 0x40,
+  0x07, 0xFF, 0xC0,
+  0x00, 0x01, 0xF0,
+  0x00, 0x00, 0x70,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0052[ 36] = { /* code 0052, LATIN CAPITAL LETTER R */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3F, 0xF4,
+  0x38, 0x2C,
+  0x38, 0x2D,
+  0x38, 0x3C,
+  0x3F, 0xE0,
+  0x38, 0x74,
+  0x38, 0x38,
+  0x38, 0x2D,
+  0x38, 0x1E,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0053[ 36] = { /* code 0053, LATIN CAPITAL LETTER S */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xD0,
+  0x38, 0x20,
+  0x78, 0x00,
+  0x3E, 0x00,
+  0x0F, 0xE0,
+  0x00, 0xF4,
+  0x00, 0x78,
+  0x50, 0xB4,
+  0x2F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0054[ 36] = { /* code 0054, LATIN CAPITAL LETTER T */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xFF, 0xFC,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0055[ 54] = { /* code 0055, LATIN CAPITAL LETTER U */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x2C, 0x03, 0xC0,
+  0x2C, 0x03, 0xC0,
+  0x2C, 0x03, 0xC0,
+  0x2C, 0x03, 0xC0,
+  0x2C, 0x03, 0xC0,
+  0x2C, 0x03, 0xC0,
+  0x2C, 0x03, 0x80,
+  0x1E, 0x07, 0x40,
+  0x07, 0xFD, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0056[ 54] = { /* code 0056, LATIN CAPITAL LETTER V */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0xB4, 0x03, 0x80,
+  0x78, 0x07, 0x40,
+  0x3C, 0x0B, 0x00,
+  0x2D, 0x0E, 0x00,
+  0x1E, 0x1D, 0x00,
+  0x0F, 0x2C, 0x00,
+  0x0B, 0x74, 0x00,
+  0x07, 0xF0, 0x00,
+  0x03, 0xE0, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0057[ 72] = { /* code 0057, LATIN CAPITAL LETTER W */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0xB4, 0x1F, 0x01, 0xD0,
+  0x78, 0x1F, 0x41, 0xD0,
+  0x38, 0x2F, 0x42, 0xC0,
+  0x2C, 0x3B, 0x83, 0x80,
+  0x1D, 0x76, 0xC7, 0x40,
+  0x0E, 0x71, 0xDB, 0x00,
+  0x0F, 0xE0, 0xEE, 0x00,
+  0x0B, 0xD0, 0xFD, 0x00,
+  0x07, 0xD0, 0xBC, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0058[ 36] = { /* code 0058, LATIN CAPITAL LETTER X */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x78, 0x1E,
+  0x3C, 0x2C,
+  0x1E, 0x74,
+  0x0B, 0xE0,
+  0x07, 0xD0,
+  0x0F, 0xF0,
+  0x1D, 0x78,
+  0x3C, 0x2C,
+  0xB4, 0x1E,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0059[ 36] = { /* code 0059, LATIN CAPITAL LETTER Y */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xB4, 0x1E,
+  0x38, 0x2C,
+  0x2D, 0x78,
+  0x0E, 0xB0,
+  0x07, 0xD0,
+  0x03, 0xC0,
+  0x03, 0xC0,
+  0x03, 0xC0,
+  0x03, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_005A[ 36] = { /* code 005A, LATIN CAPITAL LETTER Z */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xF8,
+  0x00, 0xB4,
+  0x01, 0xE0,
+  0x02, 0xC0,
+  0x07, 0x40,
+  0x0F, 0x00,
+  0x2D, 0x00,
+  0x78, 0x00,
+  0xBF, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_005B[ 36] = { /* code 005B, LEFT SQUARE BRACKET */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0x40,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x2F, 0x40,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_005C[ 36] = { /* code 005C, REVERSE SOLIDUS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xB0, 0x00,
+  0x74, 0x00,
+  0x38, 0x00,
+  0x2C, 0x00,
+  0x1D, 0x00,
+  0x0E, 0x00,
+  0x0B, 0x00,
+  0x07, 0x40,
+  0x03, 0x80,
+  0x02, 0xC0,
+  0x01, 0xD0,
+  0x00, 0xE0,
+  0x00, 0xB0,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_005D[ 36] = { /* code 005D, RIGHT SQUARE BRACKET */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7E, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x7E, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_005E[ 36] = { /* code 005E, CIRCUMFLEX ACCENT */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0x80,
+  0x0F, 0xC0,
+  0x1D, 0xE0,
+  0x38, 0xB0,
+  0x74, 0x74,
+  0xB0, 0x38,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_005F[ 36] = { /* code 005F, LOW LINE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xFF, 0xFC,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0060[ 36] = { /* code 0060, GRAVE ACCENT */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x38, 0x00,
+  0x0E, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0061[ 36] = { /* code 0061, LATIN SMALL LETTER A */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xD0,
+  0x20, 0xB0,
+  0x00, 0xB0,
+  0x2F, 0xF0,
+  0x74, 0xB0,
+  0x70, 0xF0,
+  0x3F, 0xB0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0062[ 36] = { /* code 0062, LATIN SMALL LETTER B */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x3A, 0xF4,
+  0x3D, 0x2C,
+  0x38, 0x1D,
+  0x38, 0x1D,
+  0x38, 0x1D,
+  0x3D, 0x3C,
+  0x36, 0xF4,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0063[ 36] = { /* code 0063, LATIN SMALL LETTER C */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xD0,
+  0x38, 0x20,
+  0x74, 0x00,
+  0x74, 0x00,
+  0x74, 0x00,
+  0x38, 0x20,
+  0x0F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0064[ 36] = { /* code 0064, LATIN SMALL LETTER D */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x2C,
+  0x00, 0x2C,
+  0x00, 0x2C,
+  0x1F, 0xFC,
+  0x38, 0x7C,
+  0x74, 0x2C,
+  0x74, 0x2C,
+  0x74, 0x2C,
+  0x38, 0x7C,
+  0x1F, 0x9C,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0065[ 36] = { /* code 0065, LATIN SMALL LETTER E */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xF0,
+  0x2C, 0x2C,
+  0x38, 0x1D,
+  0x7F, 0xFD,
+  0x74, 0x00,
+  0x3C, 0x00,
+  0x0F, 0xFC,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0066[ 36] = { /* code 0066, LATIN SMALL LETTER F */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xC0,
+  0x1D, 0x00,
+  0x1D, 0x00,
+  0xBF, 0x80,
+  0x1D, 0x00,
+  0x1D, 0x00,
+  0x1D, 0x00,
+  0x1D, 0x00,
+  0x1D, 0x00,
+  0x1D, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0067[ 36] = { /* code 0067, LATIN SMALL LETTER G */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xF8,
+  0x34, 0xB0,
+  0x70, 0x70,
+  0x34, 0xA0,
+  0x3F, 0xC0,
+  0x70, 0x00,
+  0x3F, 0xF0,
+  0xB0, 0x38,
+  0xB0, 0x78,
+  0x3F, 0xE0,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0068[ 36] = { /* code 0068, LATIN SMALL LETTER H */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x3A, 0xF4,
+  0x3D, 0x3C,
+  0x38, 0x2C,
+  0x38, 0x2C,
+  0x38, 0x2C,
+  0x38, 0x2C,
+  0x38, 0x2C,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0069[ 18] = { /* code 0069, LATIN SMALL LETTER I */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x3C,
+  0x3C,
+  0x00,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_006A[ 18] = { /* code 006A, LATIN SMALL LETTER J */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x2C,
+  0x2C,
+  0x00,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x38,
+  0xF4,
+  0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_006B[ 36] = { /* code 006B, LATIN SMALL LETTER K */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0xB4,
+  0x39, 0xE0,
+  0x3F, 0xC0,
+  0x3F, 0xC0,
+  0x39, 0xE0,
+  0x38, 0xF0,
+  0x38, 0x78,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_006C[ 18] = { /* code 006C, LATIN SMALL LETTER L */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x2C,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_006D[ 54] = { /* code 006D, LATIN SMALL LETTER M */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x36, 0xF6, 0xF4,
+  0x3C, 0x3D, 0x3C,
+  0x38, 0x2C, 0x2C,
+  0x38, 0x2C, 0x2C,
+  0x38, 0x2C, 0x2C,
+  0x38, 0x2C, 0x2C,
+  0x38, 0x2C, 0x2C,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_006E[ 36] = { /* code 006E, LATIN SMALL LETTER N */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x36, 0xF4,
+  0x3D, 0x3C,
+  0x38, 0x2C,
+  0x38, 0x2C,
+  0x38, 0x2C,
+  0x38, 0x2C,
+  0x38, 0x2C,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_006F[ 36] = { /* code 006F, LATIN SMALL LETTER O */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xF0,
+  0x3C, 0x2C,
+  0x74, 0x1D,
+  0x74, 0x1D,
+  0x74, 0x1D,
+  0x38, 0x2C,
+  0x0F, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0070[ 36] = { /* code 0070, LATIN SMALL LETTER P */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x36, 0xF4,
+  0x3D, 0x2C,
+  0x38, 0x1D,
+  0x38, 0x1D,
+  0x38, 0x1D,
+  0x3D, 0x3C,
+  0x3F, 0xF4,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0071[ 36] = { /* code 0071, LATIN SMALL LETTER Q */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0x9C,
+  0x38, 0x7C,
+  0x74, 0x2C,
+  0x74, 0x2C,
+  0x74, 0x2C,
+  0x38, 0x7C,
+  0x1F, 0xAC,
+  0x00, 0x2C,
+  0x00, 0x2C,
+  0x00, 0x2C,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0072[ 36] = { /* code 0072, LATIN SMALL LETTER R */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3B, 0xC0,
+  0x3D, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x38, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0073[ 36] = { /* code 0073, LATIN SMALL LETTER S */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0x80,
+  0x74, 0x40,
+  0x78, 0x00,
+  0x2F, 0xC0,
+  0x01, 0xD0,
+  0x51, 0xD0,
+  0x2F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0074[ 36] = { /* code 0074, LATIN SMALL LETTER T */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0xBF, 0x80,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x2C, 0x00,
+  0x0F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0075[ 36] = { /* code 0075, LATIN SMALL LETTER U */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x38, 0x2C,
+  0x38, 0x2C,
+  0x38, 0x2C,
+  0x38, 0x2C,
+  0x38, 0x2C,
+  0x3C, 0x7C,
+  0x1F, 0x9C,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0076[ 36] = { /* code 0076, LATIN SMALL LETTER V */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xB0, 0x38,
+  0x74, 0x74,
+  0x38, 0xB0,
+  0x2C, 0xE0,
+  0x1D, 0xD0,
+  0x0F, 0xC0,
+  0x0B, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0077[ 54] = { /* code 0077, LATIN SMALL LETTER W */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0xB0, 0x74, 0x38,
+  0x74, 0x78, 0x74,
+  0x38, 0xAC, 0x70,
+  0x28, 0xDC, 0xA0,
+  0x1D, 0xCA, 0xE0,
+  0x0F, 0x8B, 0xD0,
+  0x0F, 0x47, 0xC0,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0078[ 36] = { /* code 0078, LATIN SMALL LETTER X */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x74, 0x74,
+  0x3C, 0xE0,
+  0x1F, 0xD0,
+  0x0F, 0x80,
+  0x1F, 0xD0,
+  0x38, 0xF0,
+  0xB4, 0x78,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_0079[ 36] = { /* code 0079, LATIN SMALL LETTER Y */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xB0, 0x38,
+  0x74, 0x74,
+  0x38, 0xB0,
+  0x2C, 0xA0,
+  0x1F, 0xD0,
+  0x0B, 0xC0,
+  0x07, 0x80,
+  0x07, 0x40,
+  0x0B, 0x40,
+  0x0F, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_007A[ 36] = { /* code 007A, LATIN SMALL LETTER Z */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xD0,
+  0x03, 0xC0,
+  0x07, 0x40,
+  0x0E, 0x00,
+  0x1D, 0x00,
+  0x38, 0x00,
+  0x7F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_007B[ 36] = { /* code 007B, LEFT CURLY BRACKET */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0x80,
+  0x0D, 0x00,
+  0x1D, 0x00,
+  0x1D, 0x00,
+  0x1D, 0x00,
+  0x2C, 0x00,
+  0xA0, 0x00,
+  0x1C, 0x00,
+  0x1D, 0x00,
+  0x1D, 0x00,
+  0x1D, 0x00,
+  0x0D, 0x00,
+  0x0B, 0x80,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_007C[ 36] = { /* code 007C, VERTICAL LINE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x07, 0x40,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_007D[ 36] = { /* code 007D, RIGHT CURLY BRACKET */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7C, 0x00,
+  0x0D, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x0A, 0x00,
+  0x01, 0xC0,
+  0x0B, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x0E, 0x00,
+  0x0D, 0x00,
+  0x7C, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriBold18_AA2_007E[ 36] = { /* code 007E, TILDE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x3E, 0x28,
+  0xA2, 0xF4,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const aafontsCharInfo_t charTable_CalibriBold18_AA2[95] = 
+{
+  {   3,   1, FontCalibriBold18_AA2_0020 }, /* code 0020 */
+  {   5,   2, FontCalibriBold18_AA2_0021 }, /* code 0021 */
+  {   7,   2, FontCalibriBold18_AA2_0022 }, /* code 0022 */
+  {   7,   2, FontCalibriBold18_AA2_0023 }, /* code 0023 */
+  {   7,   2, FontCalibriBold18_AA2_0024 }, /* code 0024 */
+  {  11,   3, FontCalibriBold18_AA2_0025 }, /* code 0025 */
+  {  11,   3, FontCalibriBold18_AA2_0026 }, /* code 0026 */
+  {   4,   1, FontCalibriBold18_AA2_0027 }, /* code 0027 */
+  {   5,   2, FontCalibriBold18_AA2_0028 }, /* code 0028 */
+  {   5,   2, FontCalibriBold18_AA2_0029 }, /* code 0029 */
+  {   7,   2, FontCalibriBold18_AA2_002A }, /* code 002A */
+  {   7,   2, FontCalibriBold18_AA2_002B }, /* code 002B */
+  {   4,   1, FontCalibriBold18_AA2_002C }, /* code 002C */
+  {   5,   2, FontCalibriBold18_AA2_002D }, /* code 002D */
+  {   4,   1, FontCalibriBold18_AA2_002E }, /* code 002E */
+  {   6,   2, FontCalibriBold18_AA2_002F }, /* code 002F */
+  {   7,   2, FontCalibriBold18_AA2_0030 }, /* code 0030 */
+  {   7,   2, FontCalibriBold18_AA2_0031 }, /* code 0031 */
+  {   7,   2, FontCalibriBold18_AA2_0032 }, /* code 0032 */
+  {   7,   2, FontCalibriBold18_AA2_0033 }, /* code 0033 */
+  {   7,   2, FontCalibriBold18_AA2_0034 }, /* code 0034 */
+  {   7,   2, FontCalibriBold18_AA2_0035 }, /* code 0035 */
+  {   7,   2, FontCalibriBold18_AA2_0036 }, /* code 0036 */
+  {   7,   2, FontCalibriBold18_AA2_0037 }, /* code 0037 */
+  {   7,   2, FontCalibriBold18_AA2_0038 }, /* code 0038 */
+  {   7,   2, FontCalibriBold18_AA2_0039 }, /* code 0039 */
+  {   4,   1, FontCalibriBold18_AA2_003A }, /* code 003A */
+  {   4,   1, FontCalibriBold18_AA2_003B }, /* code 003B */
+  {   7,   2, FontCalibriBold18_AA2_003C }, /* code 003C */
+  {   7,   2, FontCalibriBold18_AA2_003D }, /* code 003D */
+  {   7,   2, FontCalibriBold18_AA2_003E }, /* code 003E */
+  {   7,   2, FontCalibriBold18_AA2_003F }, /* code 003F */
+  {  13,   4, FontCalibriBold18_AA2_0040 }, /* code 0040 */
+  {   9,   3, FontCalibriBold18_AA2_0041 }, /* code 0041 */
+  {   8,   2, FontCalibriBold18_AA2_0042 }, /* code 0042 */
+  {   8,   2, FontCalibriBold18_AA2_0043 }, /* code 0043 */
+  {   9,   3, FontCalibriBold18_AA2_0044 }, /* code 0044 */
+  {   7,   2, FontCalibriBold18_AA2_0045 }, /* code 0045 */
+  {   7,   2, FontCalibriBold18_AA2_0046 }, /* code 0046 */
+  {  10,   3, FontCalibriBold18_AA2_0047 }, /* code 0047 */
+  {   9,   3, FontCalibriBold18_AA2_0048 }, /* code 0048 */
+  {   4,   1, FontCalibriBold18_AA2_0049 }, /* code 0049 */
+  {   5,   2, FontCalibriBold18_AA2_004A }, /* code 004A */
+  {   8,   2, FontCalibriBold18_AA2_004B }, /* code 004B */
+  {   6,   2, FontCalibriBold18_AA2_004C }, /* code 004C */
+  {  13,   4, FontCalibriBold18_AA2_004D }, /* code 004D */
+  {  10,   3, FontCalibriBold18_AA2_004E }, /* code 004E */
+  {  10,   3, FontCalibriBold18_AA2_004F }, /* code 004F */
+  {   8,   2, FontCalibriBold18_AA2_0050 }, /* code 0050 */
+  {  10,   3, FontCalibriBold18_AA2_0051 }, /* code 0051 */
+  {   8,   2, FontCalibriBold18_AA2_0052 }, /* code 0052 */
+  {   7,   2, FontCalibriBold18_AA2_0053 }, /* code 0053 */
+  {   7,   2, FontCalibriBold18_AA2_0054 }, /* code 0054 */
+  {  10,   3, FontCalibriBold18_AA2_0055 }, /* code 0055 */
+  {   9,   3, FontCalibriBold18_AA2_0056 }, /* code 0056 */
+  {  14,   4, FontCalibriBold18_AA2_0057 }, /* code 0057 */
+  {   8,   2, FontCalibriBold18_AA2_0058 }, /* code 0058 */
+  {   8,   2, FontCalibriBold18_AA2_0059 }, /* code 0059 */
+  {   7,   2, FontCalibriBold18_AA2_005A }, /* code 005A */
+  {   5,   2, FontCalibriBold18_AA2_005B }, /* code 005B */
+  {   6,   2, FontCalibriBold18_AA2_005C }, /* code 005C */
+  {   5,   2, FontCalibriBold18_AA2_005D }, /* code 005D */
+  {   7,   2, FontCalibriBold18_AA2_005E }, /* code 005E */
+  {   7,   2, FontCalibriBold18_AA2_005F }, /* code 005F */
+  {   5,   2, FontCalibriBold18_AA2_0060 }, /* code 0060 */
+  {   7,   2, FontCalibriBold18_AA2_0061 }, /* code 0061 */
+  {   8,   2, FontCalibriBold18_AA2_0062 }, /* code 0062 */
+  {   6,   2, FontCalibriBold18_AA2_0063 }, /* code 0063 */
+  {   8,   2, FontCalibriBold18_AA2_0064 }, /* code 0064 */
+  {   8,   2, FontCalibriBold18_AA2_0065 }, /* code 0065 */
+  {   5,   2, FontCalibriBold18_AA2_0066 }, /* code 0066 */
+  {   7,   2, FontCalibriBold18_AA2_0067 }, /* code 0067 */
+  {   8,   2, FontCalibriBold18_AA2_0068 }, /* code 0068 */
+  {   4,   1, FontCalibriBold18_AA2_0069 }, /* code 0069 */
+  {   4,   1, FontCalibriBold18_AA2_006A }, /* code 006A */
+  {   7,   2, FontCalibriBold18_AA2_006B }, /* code 006B */
+  {   4,   1, FontCalibriBold18_AA2_006C }, /* code 006C */
+  {  12,   3, FontCalibriBold18_AA2_006D }, /* code 006D */
+  {   8,   2, FontCalibriBold18_AA2_006E }, /* code 006E */
+  {   8,   2, FontCalibriBold18_AA2_006F }, /* code 006F */
+  {   8,   2, FontCalibriBold18_AA2_0070 }, /* code 0070 */
+  {   8,   2, FontCalibriBold18_AA2_0071 }, /* code 0071 */
+  {   5,   2, FontCalibriBold18_AA2_0072 }, /* code 0072 */
+  {   6,   2, FontCalibriBold18_AA2_0073 }, /* code 0073 */
+  {   5,   2, FontCalibriBold18_AA2_0074 }, /* code 0074 */
+  {   8,   2, FontCalibriBold18_AA2_0075 }, /* code 0075 */
+  {   7,   2, FontCalibriBold18_AA2_0076 }, /* code 0076 */
+  {  11,   3, FontCalibriBold18_AA2_0077 }, /* code 0077 */
+  {   7,   2, FontCalibriBold18_AA2_0078 }, /* code 0078 */
+  {   7,   2, FontCalibriBold18_AA2_0079 }, /* code 0079 */
+  {   6,   2, FontCalibriBold18_AA2_007A }, /* code 007A */
+  {   5,   2, FontCalibriBold18_AA2_007B }, /* code 007B */
+  {   7,   2, FontCalibriBold18_AA2_007C }, /* code 007C */
+  {   5,   2, FontCalibriBold18_AA2_007D }, /* code 007D */
+  {   7,   2, FontCalibriBold18_AA2_007E }, /* code 007E */
+};
+
+aafontsFont_t FontCalibriBold18_AA2 = 
+{
+  AAFONTS_FONTTYPE_AA2,                 /* Font type (anti-aliasing level) */
+  18,                                   /* Font height in pixels */
+  3,                                    /* Width to insert for unknown characters */
+  9,                                    /* Height of upper-case characters */
+  7,                                    /* Height of lower-case characters */
+  14,                                   /* Font baseline */
+  0x0020,                               /* Unicode address of first character */
+  0x007E,                               /* Unicode address of last character */
+  &charTable_CalibriBold18_AA2[0]       /* Font char data */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontCalibriBold18_AA2.h b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontCalibriBold18_AA2.h
new file mode 100644
index 0000000000000000000000000000000000000000..3337e0f27a13c22d105e714c81f25e23d6262310
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontCalibriBold18_AA2.h
@@ -0,0 +1,52 @@
+/**************************************************************************/
+/*! 
+    @file     FontCalibriBold18_AA2.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __FONTCALIBRIBOLD18_AA2_H__
+#define __FONTCALIBRIBOLD18_AA2_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "drivers/displays/graphic/aafonts.h"
+
+extern aafontsFont_t FontCalibriBold18_AA2;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontCalibriItalic18_AA2.c b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontCalibriItalic18_AA2.c
new file mode 100644
index 0000000000000000000000000000000000000000..29066ff834a3aae43bb0cd31151ca0b892cc5aab
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontCalibriItalic18_AA2.c
@@ -0,0 +1,2144 @@
+/**************************************************************************/
+/*! 
+    @file     FontCalibriItalic18_AA2.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "FontCalibriItalic18_AA2.h"
+
+/* Start of unicode area <Basic Latin> */
+const uint8_t FontCalibriItalic18_AA2_0020[ 18] = { /* code 0020, SPACE */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0021[ 36] = { /* code 0021, EXCLAMATION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x02, 0x80,
+  0x02, 0x40,
+  0x03, 0x00,
+  0x07, 0x00,
+  0x06, 0x00,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x00, 0x00,
+  0x1C, 0x00,
+  0x18, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0022[ 36] = { /* code 0022, QUOTATION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x09, 0x30,
+  0x09, 0x30,
+  0x08, 0x60,
+  0x08, 0x50,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0023[ 36] = { /* code 0023, NUMBER SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0x08,
+  0x06, 0x18,
+  0x2F, 0xFC,
+  0x08, 0x30,
+  0x18, 0x60,
+  0xBF, 0xF8,
+  0x20, 0x80,
+  0x60, 0xC0,
+  0x51, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0024[ 36] = { /* code 0024, DOLLAR SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x20,
+  0x00, 0x20,
+  0x03, 0xF8,
+  0x0D, 0x08,
+  0x1C, 0x00,
+  0x0E, 0x00,
+  0x03, 0xE0,
+  0x00, 0x28,
+  0x00, 0x28,
+  0x90, 0x34,
+  0x7F, 0xC0,
+  0x08, 0x00,
+  0x14, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0025[ 54] = { /* code 0025, PERCENT SIGN */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x0B, 0xC0, 0x24,
+  0x18, 0x50, 0x90,
+  0x24, 0x91, 0x40,
+  0x24, 0xC6, 0x00,
+  0x1F, 0x58, 0x00,
+  0x00, 0x63, 0xE0,
+  0x01, 0x89, 0x30,
+  0x02, 0x0C, 0x20,
+  0x0C, 0x08, 0x60,
+  0x30, 0x0B, 0xC0,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0026[ 54] = { /* code 0026, AMPERSAND */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x02, 0xFD, 0x00,
+  0x07, 0x06, 0x00,
+  0x06, 0x0A, 0x00,
+  0x03, 0xB4, 0x00,
+  0x0B, 0x81, 0x80,
+  0x28, 0xA2, 0x80,
+  0x60, 0x3F, 0x00,
+  0x70, 0x1E, 0x00,
+  0x2F, 0xE2, 0xC0,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0027[ 18] = { /* code 0027, APOSTROPHE */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x0C,
+  0x0C,
+  0x08,
+  0x18,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0028[ 36] = { /* code 0028, LEFT PARENTHESIS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x80,
+  0x02, 0x80,
+  0x03, 0x00,
+  0x09, 0x00,
+  0x0C, 0x00,
+  0x18, 0x00,
+  0x24, 0x00,
+  0x34, 0x00,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x34, 0x00,
+  0x24, 0x00,
+  0x18, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0029[ 36] = { /* code 0029, RIGHT PARENTHESIS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x05, 0x00,
+  0x02, 0x00,
+  0x03, 0x00,
+  0x03, 0x40,
+  0x03, 0x40,
+  0x03, 0x00,
+  0x07, 0x00,
+  0x0A, 0x00,
+  0x0D, 0x00,
+  0x1C, 0x00,
+  0x24, 0x00,
+  0x60, 0x00,
+  0xC0, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_002A[ 36] = { /* code 002A, ASTERISK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x50,
+  0x0A, 0x9C,
+  0x01, 0xE0,
+  0x0E, 0x68,
+  0x01, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_002B[ 36] = { /* code 002B, PLUS SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x01, 0x80,
+  0x01, 0x80,
+  0x01, 0x80,
+  0x7F, 0xF8,
+  0x02, 0x40,
+  0x03, 0x00,
+  0x06, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_002C[ 18] = { /* code 002C, COMMA */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x34,
+  0x30,
+  0x90,
+  0x40,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_002D[ 36] = { /* code 002D, HYPHEN-MINUS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_002E[ 18] = { /* code 002E, FULL STOP */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x30,
+  0x70,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_002F[ 36] = { /* code 002F, SOLIDUS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x20,
+  0x00, 0x30,
+  0x00, 0x90,
+  0x01, 0xC0,
+  0x03, 0x40,
+  0x06, 0x00,
+  0x0C, 0x00,
+  0x28, 0x00,
+  0x30, 0x00,
+  0x90, 0x00,
+  0xC0, 0x00,
+  0x40, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0030[ 36] = { /* code 0030, DIGIT ZERO */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0xF4,
+  0x0D, 0x1C,
+  0x28, 0x1C,
+  0x34, 0x1C,
+  0x70, 0x18,
+  0x60, 0x28,
+  0x60, 0x34,
+  0x70, 0x60,
+  0x2F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0031[ 36] = { /* code 0031, DIGIT ONE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x01, 0xE0,
+  0x0A, 0xA0,
+  0x00, 0x90,
+  0x00, 0xC0,
+  0x00, 0xC0,
+  0x01, 0x80,
+  0x02, 0x80,
+  0x02, 0x40,
+  0x7F, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0032[ 36] = { /* code 0032, DIGIT TWO */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0xF0,
+  0x08, 0x34,
+  0x00, 0x24,
+  0x00, 0x34,
+  0x00, 0xA0,
+  0x02, 0x80,
+  0x0A, 0x00,
+  0x38, 0x00,
+  0xBF, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0033[ 36] = { /* code 0033, DIGIT THREE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0xF0,
+  0x08, 0x34,
+  0x00, 0x34,
+  0x00, 0x70,
+  0x0F, 0x80,
+  0x00, 0x70,
+  0x00, 0x70,
+  0x90, 0xA0,
+  0x2F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0034[ 36] = { /* code 0034, DIGIT FOUR */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x74,
+  0x01, 0xF0,
+  0x03, 0x60,
+  0x09, 0x60,
+  0x28, 0x50,
+  0x60, 0x90,
+  0xBF, 0xF4,
+  0x00, 0xC0,
+  0x01, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0035[ 36] = { /* code 0035, DIGIT FIVE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xFC,
+  0x08, 0x00,
+  0x0C, 0x00,
+  0x1F, 0xE0,
+  0x00, 0x28,
+  0x00, 0x18,
+  0x00, 0x24,
+  0x90, 0xB0,
+  0x2F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0036[ 36] = { /* code 0036, DIGIT SIX */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x01, 0xFC,
+  0x0A, 0x00,
+  0x18, 0x00,
+  0x2F, 0xF4,
+  0x34, 0x18,
+  0x30, 0x1C,
+  0x70, 0x28,
+  0x30, 0x70,
+  0x1F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0037[ 36] = { /* code 0037, DIGIT SEVEN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0xFC,
+  0x00, 0x08,
+  0x00, 0x18,
+  0x00, 0x30,
+  0x00, 0x90,
+  0x01, 0x80,
+  0x03, 0x00,
+  0x09, 0x00,
+  0x28, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0038[ 36] = { /* code 0038, DIGIT EIGHT */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x03, 0xF4,
+  0x0C, 0x1C,
+  0x18, 0x18,
+  0x0D, 0x70,
+  0x07, 0xC0,
+  0x34, 0x70,
+  0xA0, 0x34,
+  0xA0, 0x70,
+  0x3F, 0xC0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0039[ 36] = { /* code 0039, DIGIT NINE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xF0,
+  0x1C, 0x18,
+  0x24, 0x18,
+  0x24, 0x18,
+  0x1F, 0xF8,
+  0x00, 0x34,
+  0x00, 0x70,
+  0x00, 0xD0,
+  0xBF, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_003A[ 18] = { /* code 003A, COLON */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x0D,
+  0x0D,
+  0x00,
+  0x00,
+  0x00,
+  0x34,
+  0x34,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_003B[ 18] = { /* code 003B, SEMICOLON */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x0D,
+  0x0D,
+  0x00,
+  0x00,
+  0x00,
+  0x24,
+  0x30,
+  0x90,
+  0x80,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_003C[ 36] = { /* code 003C, LESS-THAN SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x1C,
+  0x01, 0xD0,
+  0x1E, 0x00,
+  0x60, 0x00,
+  0x0F, 0x00,
+  0x00, 0xF4,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_003D[ 36] = { /* code 003D, EQUALS SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0xFC,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x7F, 0xF8,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_003E[ 36] = { /* code 003E, GREATER-THAN SIGN */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1E, 0x00,
+  0x01, 0xF0,
+  0x00, 0x1C,
+  0x00, 0xF4,
+  0x0B, 0x40,
+  0x74, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_003F[ 36] = { /* code 003F, QUESTION MARK */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xF4,
+  0x00, 0x1C,
+  0x00, 0x0C,
+  0x00, 0x28,
+  0x03, 0xE0,
+  0x03, 0x00,
+  0x06, 0x00,
+  0x00, 0x00,
+  0x0D, 0x00,
+  0x0D, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0040[ 72] = { /* code 0040, COMMERCIAL AT */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x1F, 0xF4, 0x00,
+  0x00, 0xE0, 0x0E, 0x00,
+  0x03, 0x40, 0x03, 0x00,
+  0x09, 0x2F, 0x53, 0x00,
+  0x0C, 0x61, 0xC3, 0x00,
+  0x18, 0xD0, 0xC3, 0x00,
+  0x24, 0xC1, 0x86, 0x00,
+  0x24, 0xC7, 0x4C, 0x00,
+  0x24, 0xB9, 0xF4, 0x00,
+  0x24, 0x00, 0x00, 0x00,
+  0x0D, 0x00, 0x00, 0x00,
+  0x03, 0xFF, 0x40, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0041[ 54] = { /* code 0041, LATIN CAPITAL LETTER A */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x74, 0x00,
+  0x00, 0xF4, 0x00,
+  0x02, 0xA8, 0x00,
+  0x07, 0x18, 0x00,
+  0x09, 0x1C, 0x00,
+  0x18, 0x0C, 0x00,
+  0x3F, 0xFD, 0x00,
+  0xA0, 0x09, 0x00,
+  0xC0, 0x0A, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0042[ 36] = { /* code 0042, LATIN CAPITAL LETTER B */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xFC,
+  0x09, 0x09,
+  0x0C, 0x09,
+  0x1C, 0x1C,
+  0x1F, 0xF4,
+  0x24, 0x1C,
+  0x24, 0x0C,
+  0x30, 0x28,
+  0x7F, 0xE0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0043[ 36] = { /* code 0043, LATIN CAPITAL LETTER C */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0xFE,
+  0x07, 0x02,
+  0x0D, 0x00,
+  0x28, 0x00,
+  0x34, 0x00,
+  0x34, 0x00,
+  0x34, 0x00,
+  0x2C, 0x08,
+  0x0B, 0xF4,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0044[ 54] = { /* code 0044, LATIN CAPITAL LETTER D */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x0B, 0xFD, 0x00,
+  0x09, 0x07, 0x40,
+  0x0C, 0x02, 0x80,
+  0x1C, 0x01, 0x80,
+  0x18, 0x02, 0x80,
+  0x24, 0x03, 0x40,
+  0x24, 0x06, 0x00,
+  0x30, 0x2C, 0x00,
+  0x7F, 0xE0, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0045[ 36] = { /* code 0045, LATIN CAPITAL LETTER E */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xFC,
+  0x09, 0x00,
+  0x0C, 0x00,
+  0x18, 0x00,
+  0x1F, 0xF4,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x30, 0x00,
+  0x7F, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0046[ 36] = { /* code 0046, LATIN CAPITAL LETTER F */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xFC,
+  0x09, 0x00,
+  0x0C, 0x00,
+  0x1C, 0x00,
+  0x1F, 0xF4,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x30, 0x00,
+  0x70, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0047[ 54] = { /* code 0047, LATIN CAPITAL LETTER G */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0xFF, 0x80,
+  0x07, 0x40, 0x80,
+  0x1C, 0x00, 0x00,
+  0x24, 0x00, 0x00,
+  0x30, 0x3F, 0x40,
+  0x70, 0x03, 0x00,
+  0x30, 0x06, 0x00,
+  0x2C, 0x0A, 0x00,
+  0x0B, 0xFC, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0048[ 54] = { /* code 0048, LATIN CAPITAL LETTER H */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x09, 0x00, 0xC0,
+  0x09, 0x01, 0x80,
+  0x0C, 0x01, 0x80,
+  0x1C, 0x02, 0x40,
+  0x1F, 0xFF, 0x40,
+  0x24, 0x03, 0x00,
+  0x24, 0x06, 0x00,
+  0x30, 0x06, 0x00,
+  0x70, 0x09, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0049[ 18] = { /* code 0049, LATIN CAPITAL LETTER I */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x09,
+  0x09,
+  0x0C,
+  0x1C,
+  0x18,
+  0x24,
+  0x24,
+  0x30,
+  0x70,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_004A[ 36] = { /* code 004A, LATIN CAPITAL LETTER J */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x03, 0x00,
+  0x07, 0x00,
+  0x06, 0x00,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x0C, 0x00,
+  0xF4, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_004B[ 36] = { /* code 004B, LATIN CAPITAL LETTER K */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x09, 0x07,
+  0x09, 0x1C,
+  0x0C, 0x70,
+  0x1E, 0xC0,
+  0x1F, 0x00,
+  0x25, 0x80,
+  0x24, 0xD0,
+  0x30, 0x70,
+  0x70, 0x28,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_004C[ 36] = { /* code 004C, LATIN CAPITAL LETTER L */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x0C, 0x00,
+  0x1C, 0x00,
+  0x18, 0x00,
+  0x24, 0x00,
+  0x24, 0x00,
+  0x30, 0x00,
+  0x7F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_004D[ 72] = { /* code 004D, LATIN CAPITAL LETTER M */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x0B, 0x40, 0x0B, 0x40,
+  0x0F, 0x80, 0x1F, 0x40,
+  0x0D, 0x80, 0x37, 0x00,
+  0x18, 0xC0, 0xA3, 0x00,
+  0x18, 0x91, 0xC6, 0x00,
+  0x24, 0x93, 0x49, 0x00,
+  0x34, 0x66, 0x09, 0x00,
+  0x30, 0x3C, 0x0C, 0x00,
+  0x60, 0x34, 0x0C, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_004E[ 54] = { /* code 004E, LATIN CAPITAL LETTER N */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x0B, 0x00, 0x90,
+  0x0A, 0x40, 0xD0,
+  0x09, 0x80, 0xC0,
+  0x18, 0x81, 0x80,
+  0x18, 0x61, 0x80,
+  0x24, 0x32, 0x40,
+  0x24, 0x2B, 0x40,
+  0x30, 0x1F, 0x00,
+  0x60, 0x0E, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_004F[ 54] = { /* code 004F, LATIN CAPITAL LETTER O */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x01, 0xFF, 0x40,
+  0x07, 0x01, 0xD0,
+  0x1C, 0x00, 0x90,
+  0x28, 0x00, 0xA0,
+  0x34, 0x00, 0x90,
+  0x30, 0x00, 0xC0,
+  0x30, 0x02, 0x80,
+  0x28, 0x0B, 0x00,
+  0x0F, 0xF8, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0050[ 36] = { /* code 0050, LATIN CAPITAL LETTER P */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xFC,
+  0x09, 0x07,
+  0x0C, 0x07,
+  0x1C, 0x06,
+  0x18, 0x1D,
+  0x2F, 0xF0,
+  0x24, 0x00,
+  0x30, 0x00,
+  0x70, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0051[ 54] = { /* code 0051, LATIN CAPITAL LETTER Q */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x01, 0xFF, 0x00,
+  0x0B, 0x01, 0xC0,
+  0x1C, 0x00, 0x90,
+  0x24, 0x00, 0x90,
+  0x34, 0x00, 0xD0,
+  0x30, 0x01, 0xC0,
+  0x30, 0x02, 0x40,
+  0x28, 0x0A, 0x00,
+  0x0F, 0xF7, 0x80,
+  0x00, 0x00, 0xD0,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0052[ 36] = { /* code 0052, LATIN CAPITAL LETTER R */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0B, 0xFC,
+  0x09, 0x0A,
+  0x0C, 0x0A,
+  0x1C, 0x1D,
+  0x1F, 0xF0,
+  0x24, 0x70,
+  0x24, 0x34,
+  0x30, 0x28,
+  0x70, 0x18,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0053[ 36] = { /* code 0053, LATIN CAPITAL LETTER S */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xF0,
+  0x0C, 0x18,
+  0x18, 0x00,
+  0x1D, 0x00,
+  0x03, 0xC0,
+  0x00, 0x70,
+  0x00, 0x30,
+  0x80, 0xA0,
+  0x7F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0054[ 36] = { /* code 0054, LATIN CAPITAL LETTER T */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0xFC,
+  0x00, 0xC0,
+  0x01, 0x80,
+  0x01, 0x80,
+  0x02, 0x40,
+  0x03, 0x40,
+  0x03, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0055[ 54] = { /* code 0055, LATIN CAPITAL LETTER U */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x09, 0x00, 0x90,
+  0x09, 0x00, 0xC0,
+  0x0C, 0x00, 0xC0,
+  0x18, 0x01, 0x80,
+  0x18, 0x02, 0x40,
+  0x24, 0x02, 0x40,
+  0x24, 0x03, 0x00,
+  0x28, 0x0D, 0x00,
+  0x0B, 0xF4, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0056[ 54] = { /* code 0056, LATIN CAPITAL LETTER V */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x24, 0x00, 0xC0,
+  0x18, 0x02, 0x40,
+  0x18, 0x06, 0x00,
+  0x0C, 0x09, 0x00,
+  0x0C, 0x18, 0x00,
+  0x09, 0x30, 0x00,
+  0x09, 0xA0, 0x00,
+  0x07, 0xC0, 0x00,
+  0x07, 0x40, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0057[ 72] = { /* code 0057, LATIN CAPITAL LETTER W */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x18, 0x07, 0x00, 0x80,
+  0x18, 0x0B, 0x00, 0xC0,
+  0x18, 0x0F, 0x42, 0x80,
+  0x1C, 0x26, 0x43, 0x00,
+  0x0C, 0x32, 0x46, 0x00,
+  0x0C, 0x91, 0x8C, 0x00,
+  0x0D, 0xC1, 0x98, 0x00,
+  0x0F, 0x41, 0xF0, 0x00,
+  0x0B, 0x01, 0xE0, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0058[ 36] = { /* code 0058, LATIN CAPITAL LETTER X */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1C, 0x03,
+  0x09, 0x0A,
+  0x07, 0x28,
+  0x03, 0xE0,
+  0x02, 0xC0,
+  0x07, 0xD0,
+  0x1C, 0x70,
+  0x70, 0x34,
+  0xD0, 0x18,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0059[ 36] = { /* code 0059, LATIN CAPITAL LETTER Y */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x28, 0x08,
+  0x1C, 0x1C,
+  0x0D, 0x34,
+  0x0A, 0xA0,
+  0x07, 0x80,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x06, 0x00,
+  0x0A, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_005A[ 36] = { /* code 005A, LATIN CAPITAL LETTER Z */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1F, 0xFC,
+  0x00, 0x1C,
+  0x00, 0x70,
+  0x00, 0xD0,
+  0x03, 0x40,
+  0x0A, 0x00,
+  0x28, 0x00,
+  0xA0, 0x00,
+  0xFF, 0xF0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_005B[ 36] = { /* code 005B, LEFT SQUARE BRACKET */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xC0,
+  0x05, 0x00,
+  0x09, 0x00,
+  0x0C, 0x00,
+  0x08, 0x00,
+  0x18, 0x00,
+  0x14, 0x00,
+  0x24, 0x00,
+  0x20, 0x00,
+  0x20, 0x00,
+  0x60, 0x00,
+  0x50, 0x00,
+  0xB8, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_005C[ 36] = { /* code 005C, REVERSE SOLIDUS */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x18, 0x00,
+  0x0C, 0x00,
+  0x0C, 0x00,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x03, 0x00,
+  0x03, 0x00,
+  0x02, 0x40,
+  0x02, 0x40,
+  0x01, 0x80,
+  0x01, 0x80,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_005D[ 36] = { /* code 005D, RIGHT SQUARE BRACKET */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0x40,
+  0x02, 0x00,
+  0x03, 0x00,
+  0x06, 0x00,
+  0x05, 0x00,
+  0x09, 0x00,
+  0x08, 0x00,
+  0x0C, 0x00,
+  0x18, 0x00,
+  0x14, 0x00,
+  0x24, 0x00,
+  0x20, 0x00,
+  0xF0, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_005E[ 36] = { /* code 005E, CIRCUMFLEX ACCENT */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0xD0,
+  0x02, 0xA0,
+  0x0A, 0x20,
+  0x1C, 0x30,
+  0x34, 0x34,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_005F[ 36] = { /* code 005F, LOW LINE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0xFF, 0xF4,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0060[ 18] = { /* code 0060, GRAVE ACCENT */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x0D,
+  0x02,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0061[ 36] = { /* code 0061, LATIN SMALL LETTER A */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xE5,
+  0x1C, 0x1D,
+  0x24, 0x0C,
+  0x30, 0x18,
+  0x70, 0x28,
+  0x30, 0xB4,
+  0x2F, 0x64,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0062[ 36] = { /* code 0062, LATIN SMALL LETTER B */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x0C, 0x00,
+  0x1D, 0xF8,
+  0x1E, 0x0D,
+  0x28, 0x09,
+  0x24, 0x0D,
+  0x30, 0x1C,
+  0x34, 0x34,
+  0x6B, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0063[ 36] = { /* code 0063, LATIN SMALL LETTER C */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xE0,
+  0x1C, 0x20,
+  0x34, 0x00,
+  0x70, 0x00,
+  0x60, 0x00,
+  0x70, 0x50,
+  0x2F, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0064[ 36] = { /* code 0064, LATIN SMALL LETTER D */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x06,
+  0x00, 0x06,
+  0x00, 0x09,
+  0x07, 0xE9,
+  0x1C, 0x2C,
+  0x34, 0x18,
+  0x30, 0x18,
+  0x70, 0x34,
+  0x30, 0xB4,
+  0x2F, 0x60,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0065[ 36] = { /* code 0065, LATIN SMALL LETTER E */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xF0,
+  0x1C, 0x28,
+  0x34, 0x24,
+  0x7F, 0xD0,
+  0x60, 0x00,
+  0x70, 0x00,
+  0x2F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0066[ 36] = { /* code 0066, LATIN SMALL LETTER F */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x02, 0xC0,
+  0x06, 0x00,
+  0x09, 0x00,
+  0x3F, 0xC0,
+  0x0C, 0x00,
+  0x18, 0x00,
+  0x18, 0x00,
+  0x24, 0x00,
+  0x34, 0x00,
+  0x30, 0x00,
+  0x70, 0x00,
+  0xA0, 0x00,
+  0xC0, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0067[ 36] = { /* code 0067, LATIN SMALL LETTER G */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xE9,
+  0x1C, 0x2C,
+  0x34, 0x18,
+  0x30, 0x18,
+  0x70, 0x34,
+  0x70, 0xB0,
+  0x2F, 0x70,
+  0x00, 0x60,
+  0x50, 0x90,
+  0x3F, 0x40,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0068[ 36] = { /* code 0068, LATIN SMALL LETTER H */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x0C, 0x00,
+  0x0D, 0xF4,
+  0x1E, 0x18,
+  0x28, 0x18,
+  0x24, 0x18,
+  0x30, 0x24,
+  0x30, 0x34,
+  0x60, 0x30,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0069[ 18] = { /* code 0069, LATIN SMALL LETTER I */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x0C,
+  0x00,
+  0x0C,
+  0x18,
+  0x24,
+  0x24,
+  0x30,
+  0x30,
+  0x60,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_006A[ 18] = { /* code 006A, LATIN SMALL LETTER J */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x07,
+  0x00,
+  0x0C,
+  0x18,
+  0x18,
+  0x24,
+  0x34,
+  0x30,
+  0x60,
+  0x60,
+  0x90,
+  0x80,
+  0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_006B[ 36] = { /* code 006B, LATIN SMALL LETTER K */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x09, 0x00,
+  0x09, 0x00,
+  0x0C, 0x00,
+  0x0C, 0x28,
+  0x18, 0xA0,
+  0x2B, 0x40,
+  0x2F, 0x00,
+  0x32, 0x80,
+  0x30, 0xD0,
+  0x60, 0xA0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_006C[ 18] = { /* code 006C, LATIN SMALL LETTER L */
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x08,
+  0x08,
+  0x0C,
+  0x0C,
+  0x18,
+  0x24,
+  0x24,
+  0x30,
+  0x30,
+  0x60,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_006D[ 54] = { /* code 006D, LATIN SMALL LETTER M */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x09, 0xF4, 0xF8,
+  0x1E, 0x1E, 0x0C,
+  0x28, 0x1C, 0x0C,
+  0x24, 0x24, 0x18,
+  0x30, 0x24, 0x28,
+  0x30, 0x30, 0x24,
+  0x60, 0x30, 0x30,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_006E[ 36] = { /* code 006E, LATIN SMALL LETTER N */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x09, 0xF4,
+  0x1E, 0x1C,
+  0x28, 0x18,
+  0x24, 0x18,
+  0x30, 0x24,
+  0x30, 0x34,
+  0x60, 0x30,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_006F[ 36] = { /* code 006F, LATIN SMALL LETTER O */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xF4,
+  0x1C, 0x0D,
+  0x34, 0x09,
+  0x70, 0x0D,
+  0x70, 0x1C,
+  0x70, 0x34,
+  0x2F, 0xD0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0070[ 36] = { /* code 0070, LATIN SMALL LETTER P */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x09, 0xF8,
+  0x1E, 0x0D,
+  0x28, 0x0D,
+  0x24, 0x0C,
+  0x30, 0x18,
+  0x74, 0x34,
+  0x6B, 0xD0,
+  0x90, 0x00,
+  0x90, 0x00,
+  0x80, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0071[ 36] = { /* code 0071, LATIN SMALL LETTER Q */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xE9,
+  0x1C, 0x2C,
+  0x24, 0x18,
+  0x30, 0x18,
+  0x70, 0x34,
+  0x70, 0xB4,
+  0x2F, 0x70,
+  0x00, 0x60,
+  0x00, 0x60,
+  0x00, 0x90,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0072[ 36] = { /* code 0072, LATIN SMALL LETTER R */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x09, 0xC0,
+  0x1D, 0x00,
+  0x28, 0x00,
+  0x24, 0x00,
+  0x30, 0x00,
+  0x30, 0x00,
+  0x60, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0073[ 36] = { /* code 0073, LATIN SMALL LETTER S */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0x80,
+  0x24, 0x50,
+  0x28, 0x00,
+  0x0F, 0x40,
+  0x01, 0xC0,
+  0x81, 0x80,
+  0x7F, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0074[ 36] = { /* code 0074, LATIN SMALL LETTER T */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0A, 0x00,
+  0x09, 0x00,
+  0x3F, 0xC0,
+  0x0C, 0x00,
+  0x18, 0x00,
+  0x28, 0x00,
+  0x24, 0x00,
+  0x34, 0x00,
+  0x2E, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0075[ 36] = { /* code 0075, LATIN SMALL LETTER U */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x18, 0x0C,
+  0x18, 0x0C,
+  0x24, 0x18,
+  0x24, 0x28,
+  0x30, 0x34,
+  0x30, 0xB0,
+  0x2F, 0x60,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0076[ 36] = { /* code 0076, LATIN SMALL LETTER V */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x34, 0x0C,
+  0x24, 0x28,
+  0x24, 0x30,
+  0x18, 0xA0,
+  0x18, 0xC0,
+  0x0F, 0x40,
+  0x0E, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0077[ 54] = { /* code 0077, LATIN SMALL LETTER W */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x24, 0x28, 0x1C,
+  0x24, 0x38, 0x28,
+  0x24, 0xA8, 0x30,
+  0x18, 0xDC, 0xA0,
+  0x1A, 0x4D, 0xC0,
+  0x1F, 0x0B, 0x40,
+  0x0D, 0x0A, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0078[ 36] = { /* code 0078, LATIN SMALL LETTER X */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x28, 0x1C,
+  0x0C, 0x70,
+  0x0B, 0xC0,
+  0x07, 0x40,
+  0x1E, 0xC0,
+  0x30, 0xD0,
+  0xD0, 0x60,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_0079[ 36] = { /* code 0079, LATIN SMALL LETTER Y */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x34, 0x0C,
+  0x24, 0x28,
+  0x28, 0x30,
+  0x18, 0x60,
+  0x1C, 0xC0,
+  0x0F, 0x40,
+  0x0E, 0x00,
+  0x0C, 0x00,
+  0x34, 0x00,
+  0xA0, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_007A[ 36] = { /* code 007A, LATIN SMALL LETTER Z */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2F, 0xE0,
+  0x00, 0xC0,
+  0x03, 0x40,
+  0x0A, 0x00,
+  0x28, 0x00,
+  0x70, 0x00,
+  0xBF, 0x80,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_007B[ 36] = { /* code 007B, LEFT CURLY BRACKET */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x01, 0xC0,
+  0x02, 0x00,
+  0x06, 0x00,
+  0x05, 0x00,
+  0x09, 0x00,
+  0x0C, 0x00,
+  0x60, 0x00,
+  0x18, 0x00,
+  0x14, 0x00,
+  0x24, 0x00,
+  0x20, 0x00,
+  0x30, 0x00,
+  0x2C, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_007C[ 36] = { /* code 007C, VERTICAL LINE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0xC0,
+  0x00, 0x80,
+  0x01, 0x80,
+  0x01, 0x40,
+  0x02, 0x40,
+  0x02, 0x00,
+  0x03, 0x00,
+  0x06, 0x00,
+  0x05, 0x00,
+  0x09, 0x00,
+  0x08, 0x00,
+  0x08, 0x00,
+  0x18, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_007D[ 36] = { /* code 007D, RIGHT CURLY BRACKET */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0E, 0x00,
+  0x02, 0x00,
+  0x03, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x06, 0x00,
+  0x03, 0x40,
+  0x08, 0x00,
+  0x18, 0x00,
+  0x14, 0x00,
+  0x24, 0x00,
+  0x20, 0x00,
+  0xD0, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibriItalic18_AA2_007E[ 36] = { /* code 007E, TILDE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0F, 0x44,
+  0x24, 0xC8,
+  0x20, 0x78,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const aafontsCharInfo_t charTable_CalibriItalic18_AA2[95] = 
+{
+  {   3,   1, FontCalibriItalic18_AA2_0020 }, /* code 0020 */
+  {   5,   2, FontCalibriItalic18_AA2_0021 }, /* code 0021 */
+  {   6,   2, FontCalibriItalic18_AA2_0022 }, /* code 0022 */
+  {   7,   2, FontCalibriItalic18_AA2_0023 }, /* code 0023 */
+  {   7,   2, FontCalibriItalic18_AA2_0024 }, /* code 0024 */
+  {  11,   3, FontCalibriItalic18_AA2_0025 }, /* code 0025 */
+  {  10,   3, FontCalibriItalic18_AA2_0026 }, /* code 0026 */
+  {   3,   1, FontCalibriItalic18_AA2_0027 }, /* code 0027 */
+  {   5,   2, FontCalibriItalic18_AA2_0028 }, /* code 0028 */
+  {   5,   2, FontCalibriItalic18_AA2_0029 }, /* code 0029 */
+  {   7,   2, FontCalibriItalic18_AA2_002A }, /* code 002A */
+  {   7,   2, FontCalibriItalic18_AA2_002B }, /* code 002B */
+  {   4,   1, FontCalibriItalic18_AA2_002C }, /* code 002C */
+  {   5,   2, FontCalibriItalic18_AA2_002D }, /* code 002D */
+  {   4,   1, FontCalibriItalic18_AA2_002E }, /* code 002E */
+  {   6,   2, FontCalibriItalic18_AA2_002F }, /* code 002F */
+  {   7,   2, FontCalibriItalic18_AA2_0030 }, /* code 0030 */
+  {   7,   2, FontCalibriItalic18_AA2_0031 }, /* code 0031 */
+  {   7,   2, FontCalibriItalic18_AA2_0032 }, /* code 0032 */
+  {   7,   2, FontCalibriItalic18_AA2_0033 }, /* code 0033 */
+  {   7,   2, FontCalibriItalic18_AA2_0034 }, /* code 0034 */
+  {   7,   2, FontCalibriItalic18_AA2_0035 }, /* code 0035 */
+  {   7,   2, FontCalibriItalic18_AA2_0036 }, /* code 0036 */
+  {   7,   2, FontCalibriItalic18_AA2_0037 }, /* code 0037 */
+  {   7,   2, FontCalibriItalic18_AA2_0038 }, /* code 0038 */
+  {   7,   2, FontCalibriItalic18_AA2_0039 }, /* code 0039 */
+  {   4,   1, FontCalibriItalic18_AA2_003A }, /* code 003A */
+  {   4,   1, FontCalibriItalic18_AA2_003B }, /* code 003B */
+  {   7,   2, FontCalibriItalic18_AA2_003C }, /* code 003C */
+  {   7,   2, FontCalibriItalic18_AA2_003D }, /* code 003D */
+  {   7,   2, FontCalibriItalic18_AA2_003E }, /* code 003E */
+  {   7,   2, FontCalibriItalic18_AA2_003F }, /* code 003F */
+  {  13,   4, FontCalibriItalic18_AA2_0040 }, /* code 0040 */
+  {   9,   3, FontCalibriItalic18_AA2_0041 }, /* code 0041 */
+  {   8,   2, FontCalibriItalic18_AA2_0042 }, /* code 0042 */
+  {   8,   2, FontCalibriItalic18_AA2_0043 }, /* code 0043 */
+  {   9,   3, FontCalibriItalic18_AA2_0044 }, /* code 0044 */
+  {   7,   2, FontCalibriItalic18_AA2_0045 }, /* code 0045 */
+  {   7,   2, FontCalibriItalic18_AA2_0046 }, /* code 0046 */
+  {   9,   3, FontCalibriItalic18_AA2_0047 }, /* code 0047 */
+  {   9,   3, FontCalibriItalic18_AA2_0048 }, /* code 0048 */
+  {   4,   1, FontCalibriItalic18_AA2_0049 }, /* code 0049 */
+  {   5,   2, FontCalibriItalic18_AA2_004A }, /* code 004A */
+  {   8,   2, FontCalibriItalic18_AA2_004B }, /* code 004B */
+  {   6,   2, FontCalibriItalic18_AA2_004C }, /* code 004C */
+  {  13,   4, FontCalibriItalic18_AA2_004D }, /* code 004D */
+  {  10,   3, FontCalibriItalic18_AA2_004E }, /* code 004E */
+  {  10,   3, FontCalibriItalic18_AA2_004F }, /* code 004F */
+  {   8,   2, FontCalibriItalic18_AA2_0050 }, /* code 0050 */
+  {  10,   3, FontCalibriItalic18_AA2_0051 }, /* code 0051 */
+  {   8,   2, FontCalibriItalic18_AA2_0052 }, /* code 0052 */
+  {   7,   2, FontCalibriItalic18_AA2_0053 }, /* code 0053 */
+  {   7,   2, FontCalibriItalic18_AA2_0054 }, /* code 0054 */
+  {  10,   3, FontCalibriItalic18_AA2_0055 }, /* code 0055 */
+  {   9,   3, FontCalibriItalic18_AA2_0056 }, /* code 0056 */
+  {  13,   4, FontCalibriItalic18_AA2_0057 }, /* code 0057 */
+  {   8,   2, FontCalibriItalic18_AA2_0058 }, /* code 0058 */
+  {   7,   2, FontCalibriItalic18_AA2_0059 }, /* code 0059 */
+  {   7,   2, FontCalibriItalic18_AA2_005A }, /* code 005A */
+  {   5,   2, FontCalibriItalic18_AA2_005B }, /* code 005B */
+  {   6,   2, FontCalibriItalic18_AA2_005C }, /* code 005C */
+  {   5,   2, FontCalibriItalic18_AA2_005D }, /* code 005D */
+  {   7,   2, FontCalibriItalic18_AA2_005E }, /* code 005E */
+  {   7,   2, FontCalibriItalic18_AA2_005F }, /* code 005F */
+  {   4,   1, FontCalibriItalic18_AA2_0060 }, /* code 0060 */
+  {   8,   2, FontCalibriItalic18_AA2_0061 }, /* code 0061 */
+  {   8,   2, FontCalibriItalic18_AA2_0062 }, /* code 0062 */
+  {   6,   2, FontCalibriItalic18_AA2_0063 }, /* code 0063 */
+  {   8,   2, FontCalibriItalic18_AA2_0064 }, /* code 0064 */
+  {   7,   2, FontCalibriItalic18_AA2_0065 }, /* code 0065 */
+  {   5,   2, FontCalibriItalic18_AA2_0066 }, /* code 0066 */
+  {   8,   2, FontCalibriItalic18_AA2_0067 }, /* code 0067 */
+  {   8,   2, FontCalibriItalic18_AA2_0068 }, /* code 0068 */
+  {   3,   1, FontCalibriItalic18_AA2_0069 }, /* code 0069 */
+  {   4,   1, FontCalibriItalic18_AA2_006A }, /* code 006A */
+  {   7,   2, FontCalibriItalic18_AA2_006B }, /* code 006B */
+  {   3,   1, FontCalibriItalic18_AA2_006C }, /* code 006C */
+  {  12,   3, FontCalibriItalic18_AA2_006D }, /* code 006D */
+  {   8,   2, FontCalibriItalic18_AA2_006E }, /* code 006E */
+  {   8,   2, FontCalibriItalic18_AA2_006F }, /* code 006F */
+  {   8,   2, FontCalibriItalic18_AA2_0070 }, /* code 0070 */
+  {   8,   2, FontCalibriItalic18_AA2_0071 }, /* code 0071 */
+  {   5,   2, FontCalibriItalic18_AA2_0072 }, /* code 0072 */
+  {   6,   2, FontCalibriItalic18_AA2_0073 }, /* code 0073 */
+  {   5,   2, FontCalibriItalic18_AA2_0074 }, /* code 0074 */
+  {   8,   2, FontCalibriItalic18_AA2_0075 }, /* code 0075 */
+  {   7,   2, FontCalibriItalic18_AA2_0076 }, /* code 0076 */
+  {  11,   3, FontCalibriItalic18_AA2_0077 }, /* code 0077 */
+  {   7,   2, FontCalibriItalic18_AA2_0078 }, /* code 0078 */
+  {   7,   2, FontCalibriItalic18_AA2_0079 }, /* code 0079 */
+  {   6,   2, FontCalibriItalic18_AA2_007A }, /* code 007A */
+  {   5,   2, FontCalibriItalic18_AA2_007B }, /* code 007B */
+  {   7,   2, FontCalibriItalic18_AA2_007C }, /* code 007C */
+  {   5,   2, FontCalibriItalic18_AA2_007D }, /* code 007D */
+  {   7,   2, FontCalibriItalic18_AA2_007E }, /* code 007E */
+};
+
+aafontsFont_t FontCalibriItalic18_AA2 = 
+{
+  AAFONTS_FONTTYPE_AA2,                 /* Font type (anti-aliasing level) */
+  18,                                   /* Font height in pixels */
+  3,                                    /* Width to insert for unknown characters */
+  9,                                    /* Height of upper-case characters */
+  7,                                    /* Height of lower-case characters */
+  14,                                   /* Font baseline */
+  0x0020,                               /* Unicode address of first character */
+  0x007E,                               /* Unicode address of last character */
+  &charTable_CalibriItalic18_AA2[0]       /* Font char data */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontCalibriItalic18_AA2.h b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontCalibriItalic18_AA2.h
new file mode 100644
index 0000000000000000000000000000000000000000..a03a9b488bf3267f5e4024bde4c23094fc5cadf7
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontCalibriItalic18_AA2.h
@@ -0,0 +1,52 @@
+/**************************************************************************/
+/*! 
+    @file     FontCalibriItalic18_AA2.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __FONTCALIBRIITALIC18_AA2_H__
+#define __FONTCALIBRIITALIC18_AA2_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "drivers/displays/graphic/aafonts.h"
+
+extern aafontsFont_t FontCalibriItalic18_AA2;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontFranklinGothicBold99_Numbers_AA2.c b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontFranklinGothicBold99_Numbers_AA2.c
new file mode 100644
index 0000000000000000000000000000000000000000..41667eef9aaf832ac8a12ac3eaa69e2aeca3e21e
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontFranklinGothicBold99_Numbers_AA2.c
@@ -0,0 +1,1187 @@
+/**************************************************************************/
+/*! 
+    @file     FontCalibri18_AA2.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "FontFranklinGothicBold99_Numbers_AA2.h"
+
+/* Start of unicode area <Basic Latin> */
+const uint8_t FontFranklinGothicBold99_Numbers_AA2_0030[1188] = { /* code 0030, DIGIT ZERO */
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
+  0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00,
+  0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00,
+  0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+  0x00, 0x03, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
+  0x00, 0x07, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xD0, 0x00,
+  0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x00,
+  0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xF0, 0x00,
+  0x00, 0x2F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF8, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFC, 0x00,
+  0x00, 0xBF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFC, 0x00,
+  0x00, 0xBF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFE, 0x00,
+  0x01, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0x00,
+  0x01, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x02, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0x40,
+  0x02, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40,
+  0x03, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x80,
+  0x03, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x80,
+  0x03, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x80,
+  0x03, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0x80,
+  0x03, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0x80,
+  0x03, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x80,
+  0x03, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x80,
+  0x03, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x80,
+  0x03, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x80,
+  0x03, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x80,
+  0x03, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40,
+  0x02, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40,
+  0x02, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0x40,
+  0x02, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x01, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0x00,
+  0x01, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFE, 0x00,
+  0x00, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0xBF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFC, 0x00,
+  0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF8, 0x00,
+  0x00, 0x2F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xF4, 0x00,
+  0x00, 0x1F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x00,
+  0x00, 0x0B, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xD0, 0x00,
+  0x00, 0x07, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
+  0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xD0, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+  0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00,
+  0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00,
+  0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00,
+  0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00,
+  0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontFranklinGothicBold99_Numbers_AA2_0031[1188] = { /* code 0031, DIGIT ONE */
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x03, 0xFF, 0xFF, 0xFD, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x03, 0xFF, 0xFF, 0xF4, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x03, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x03, 0xFF, 0xFD, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x03, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x03, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x03, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
+  0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
+  0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
+  0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
+  0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
+  0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
+  0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
+  0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
+  0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontFranklinGothicBold99_Numbers_AA2_0032[1188] = { /* code 0032, DIGIT TWO */
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00,
+  0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
+  0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00,
+  0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+  0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
+  0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xD0, 0x00,
+  0x00, 0x1F, 0xFF, 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xE0, 0x00,
+  0x00, 0x3F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF4, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF8, 0x00,
+  0x00, 0xBF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFC, 0x00,
+  0x00, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFC, 0x00,
+  0x01, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFD, 0x00,
+  0x02, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFD, 0x00,
+  0x02, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0x1F, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0x00, 0x0F, 0xF4, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFC, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xF8, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF4, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xE0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x40, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00,
+  0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00,
+  0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00,
+  0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00,
+  0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00,
+  0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00,
+  0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00,
+  0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00,
+  0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontFranklinGothicBold99_Numbers_AA2_0033[1188] = { /* code 0033, DIGIT THREE */
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00,
+  0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
+  0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00,
+  0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+  0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
+  0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0x40, 0x0F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xE0, 0x00,
+  0x00, 0xBF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xF0, 0x00,
+  0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF0, 0x00,
+  0x02, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xF4, 0x00,
+  0x03, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF4, 0x00,
+  0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF4, 0x00,
+  0x00, 0x02, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF4, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xF4, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xF0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xD0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xC0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x40, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF8, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFC, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFE, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFE, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFE, 0x00,
+  0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0x00,
+  0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0x00,
+  0x0F, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFE, 0x00,
+  0x0F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFE, 0x00,
+  0x0B, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFE, 0x00,
+  0x07, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFD, 0x00,
+  0x03, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFC, 0x00,
+  0x01, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xF8, 0x00,
+  0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
+  0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00,
+  0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
+  0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00,
+  0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00,
+  0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00,
+  0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontFranklinGothicBold99_Numbers_AA2_0034[1188] = { /* code 0034, DIGIT FOUR */
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x9F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFD, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x02, 0xFF, 0xFF, 0xD0, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x2F, 0xFF, 0xFE, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0xFF, 0xFF, 0xF4, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x02, 0xFF, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x0F, 0xFF, 0xFF, 0x40, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x2F, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
+  0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
+  0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
+  0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
+  0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
+  0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
+  0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
+  0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
+  0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontFranklinGothicBold99_Numbers_AA2_0035[1188] = { /* code 0035, DIGIT FIVE */
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00,
+  0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00,
+  0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00,
+  0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
+  0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
+  0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
+  0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00,
+  0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00,
+  0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00,
+  0x00, 0x07, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x07, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x07, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x0B, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x0B, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x0B, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x0B, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x2F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x0F, 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00,
+  0x00, 0x0F, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00,
+  0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00,
+  0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
+  0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00,
+  0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00,
+  0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xFF, 0xFC, 0x00,
+  0x00, 0x2F, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFE, 0x00,
+  0x00, 0x3F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0x00,
+  0x00, 0x3F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x40,
+  0x00, 0x02, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x80,
+  0x00, 0x00, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xC0,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xD0,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xD0,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xD0,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xD0,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xD0,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xD0,
+  0x00, 0x02, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xD0,
+  0x03, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xC0,
+  0x03, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xC0,
+  0x02, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x80,
+  0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x40,
+  0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFE, 0x00,
+  0x00, 0xBF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xC0, 0x07, 0xFF, 0xFF, 0xFF, 0xF8, 0x00,
+  0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
+  0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00,
+  0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00,
+  0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00,
+  0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
+  0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontFranklinGothicBold99_Numbers_AA2_0036[1188] = { /* code 0036, DIGIT SIX */
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00,
+  0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00,
+  0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00,
+  0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00,
+  0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00,
+  0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xE0, 0x00,
+  0x00, 0x02, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFF, 0xF0, 0x00,
+  0x00, 0x03, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF8, 0x00,
+  0x00, 0x0B, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00,
+  0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFD, 0x00,
+  0x00, 0x2F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFD, 0x00,
+  0x00, 0x3F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x2F, 0xFD, 0x00, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xBF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xBF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x01, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x01, 0xFF, 0xFF, 0xFC, 0x00, 0x2F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x02, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00,
+  0x02, 0xFF, 0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x02, 0xFF, 0xFF, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00,
+  0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00,
+  0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
+  0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00,
+  0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00,
+  0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x02, 0xFF, 0xFF, 0xFF, 0xFC, 0x00,
+  0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x2F, 0xFF, 0xFF, 0xFD, 0x00,
+  0x03, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0x00,
+  0x02, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x40,
+  0x02, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0x40,
+  0x02, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x80,
+  0x02, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0x80,
+  0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0,
+  0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0,
+  0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0,
+  0x00, 0xBF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x80,
+  0x00, 0x3F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x80,
+  0x00, 0x2F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0x40,
+  0x00, 0x1F, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0x40,
+  0x00, 0x0F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00,
+  0x00, 0x07, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x1F, 0xFF, 0xFF, 0xFC, 0x00,
+  0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF4, 0x01, 0xFF, 0xFF, 0xFF, 0xF4, 0x00,
+  0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00,
+  0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00,
+  0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+  0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontFranklinGothicBold99_Numbers_AA2_0037[1188] = { /* code 0037, DIGIT SEVEN */
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xF0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xD0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0x40, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF4, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xE0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFD, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontFranklinGothicBold99_Numbers_AA2_0038[1188] = { /* code 0038, DIGIT EIGHT */
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00,
+  0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
+  0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00,
+  0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00,
+  0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00,
+  0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00,
+  0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, 0xF4, 0x00,
+  0x00, 0x3F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xF8, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFC, 0x00,
+  0x00, 0xBF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFC, 0x00,
+  0x00, 0xBF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFD, 0x00,
+  0x00, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFD, 0x00,
+  0x00, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFD, 0x00,
+  0x00, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFD, 0x00,
+  0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFC, 0x00,
+  0x00, 0xBF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00,
+  0x00, 0xBF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xF8, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xF0, 0x00,
+  0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x2F, 0xFF, 0xFF, 0xE0, 0x00,
+  0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
+  0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00,
+  0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00,
+  0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00,
+  0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00,
+  0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+  0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00,
+  0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00,
+  0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00,
+  0x00, 0x3F, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00,
+  0x00, 0xBF, 0xFF, 0xFF, 0xD0, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0x40,
+  0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
+  0x03, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xC0,
+  0x07, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xC0,
+  0x0B, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xD0,
+  0x0B, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xD0,
+  0x0B, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xD0,
+  0x0B, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xD0,
+  0x0B, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xD0,
+  0x0B, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xC0,
+  0x0B, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0x80,
+  0x07, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x40,
+  0x03, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0x00,
+  0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFE, 0x00,
+  0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
+  0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00,
+  0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+  0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00,
+  0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontFranklinGothicBold99_Numbers_AA2_0039[1188] = { /* code 0039, DIGIT NINE */
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00,
+  0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00,
+  0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00,
+  0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00,
+  0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x40, 0x2F, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
+  0x00, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xC0, 0x00,
+  0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xE0, 0x00,
+  0x02, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xF0, 0x00,
+  0x02, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF4, 0x00,
+  0x03, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xF8, 0x00,
+  0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFC, 0x00,
+  0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFD, 0x00,
+  0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFE, 0x00,
+  0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFE, 0x00,
+  0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x00,
+  0x03, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0x00,
+  0x03, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x00,
+  0x02, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0x40,
+  0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x40,
+  0x01, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0x40,
+  0x00, 0xBF, 0xFF, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x40,
+  0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x40,
+  0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40,
+  0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40,
+  0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40,
+  0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40,
+  0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0x00,
+  0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0x00,
+  0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xFE, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFE, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFD, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF8, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF4, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xF0, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x00,
+  0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xD0, 0x00,
+  0x00, 0x07, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0x80, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x40, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x40, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0x00,
+  0x00, 0x2F, 0xFF, 0xFF, 0xFE, 0x00, 0xBF, 0xFF, 0xFF, 0xFC, 0x00, 0x00,
+  0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00,
+  0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00,
+  0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00,
+  0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontFranklinGothicBold99_Numbers_AA2_003A[495] = { /* code 003A, COLON */
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x7F, 0xFF, 0xFF, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const aafontsCharInfo_t charTable_FranklinGothicBold99_Numbers_AA2[11] = 
+{
+  {  47,  12, FontFranklinGothicBold99_Numbers_AA2_0030 }, /* code 0030 */
+  {  47,  12, FontFranklinGothicBold99_Numbers_AA2_0031 }, /* code 0031 */
+  {  47,  12, FontFranklinGothicBold99_Numbers_AA2_0032 }, /* code 0032 */
+  {  47,  12, FontFranklinGothicBold99_Numbers_AA2_0033 }, /* code 0033 */
+  {  47,  12, FontFranklinGothicBold99_Numbers_AA2_0034 }, /* code 0034 */
+  {  47,  12, FontFranklinGothicBold99_Numbers_AA2_0035 }, /* code 0035 */
+  {  47,  12, FontFranklinGothicBold99_Numbers_AA2_0036 }, /* code 0036 */
+  {  47,  12, FontFranklinGothicBold99_Numbers_AA2_0037 }, /* code 0037 */
+  {  47,  12, FontFranklinGothicBold99_Numbers_AA2_0038 }, /* code 0038 */
+  {  47,  12, FontFranklinGothicBold99_Numbers_AA2_0039 }, /* code 0039 */
+  {  20,   5, FontFranklinGothicBold99_Numbers_AA2_003A }  /* code 003A */
+};
+
+aafontsFont_t FontFranklinGothicBold99_Numbers_AA2 = 
+{
+  AAFONTS_FONTTYPE_AA2,                 /* Font type (anti-aliasing level) */
+  99,                                   /* Font height in pixels */
+  20,                                   /* Width to insert for unknown characters */
+  54,                                   /* Height of upper-case characters */
+  42,                                   /* Height of lower-case characters */
+  76,                                   /* Font baseline */
+  0x0030,                               /* Unicode address of first character */
+  0x003A,                               /* Unicode address of last character */
+  &charTable_FranklinGothicBold99_Numbers_AA2[0]	/* Font char data */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontFranklinGothicBold99_Numbers_AA2.h b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontFranklinGothicBold99_Numbers_AA2.h
new file mode 100644
index 0000000000000000000000000000000000000000..d7b45187fe1cac4779f90d1b6eac7901faa9dae6
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/FontFranklinGothicBold99_Numbers_AA2.h
@@ -0,0 +1,52 @@
+/**************************************************************************/
+/*! 
+    @file     FontFranklinGothicBold99_Numbers_AA2.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __FONTFRANKLINGOTHICBOLD99_NUMBERS_AA2_H__
+#define __FONTFRANKLINGOTHICBOLD99_NUMBERS_AA2_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "drivers/displays/graphic/aafonts.h"
+
+extern aafontsFont_t FontFranklinGothicBold99_Numbers_AA2;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/source.zip b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/source.zip
new file mode 100644
index 0000000000000000000000000000000000000000..5b832ff47f316904174d29929513c6e2fd42e94e
Binary files /dev/null and b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa2/source.zip differ
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa4/FontCalibri18_AA4.c b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa4/FontCalibri18_AA4.c
new file mode 100644
index 0000000000000000000000000000000000000000..365a15666de2b543ba24c19b674d5b765dcf8b1c
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa4/FontCalibri18_AA4.c
@@ -0,0 +1,2144 @@
+/**************************************************************************/
+/*! 
+    @file     FontCalibri18_AA4.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "FontCalibri18_AA4.h"
+
+const uint8_t FontCalibri18_AA4_0020[ 36] = { /* code 0020, SPACE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0021[ 54] = { /* code 0021, EXCLAMATION MARK */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x02, 0xD5, 0x00,
+  0x02, 0xD5, 0x00,
+  0x01, 0xC5, 0x00,
+  0x01, 0xC5, 0x00,
+  0x01, 0xC5, 0x00,
+  0x01, 0xC5, 0x00,
+  0x01, 0xC5, 0x00,
+  0x00, 0x00, 0x00,
+  0x02, 0xD7, 0x00,
+  0x02, 0xD7, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0022[ 54] = { /* code 0022, QUOTATION MARK */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x2D, 0x55, 0xC1,
+  0x2C, 0x35, 0xC1,
+  0x1A, 0x35, 0xC1,
+  0x1A, 0x33, 0x90,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0023[ 72] = { /* code 0023, NUMBER SIGN */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x01, 0xA3, 0x0A, 0x50,
+  0x02, 0xB2, 0x1A, 0x30,
+  0x5F, 0xFF, 0xFF, 0xE0,
+  0x05, 0xC1, 0x3A, 0x10,
+  0x07, 0xA0, 0x5C, 0x10,
+  0xAF, 0xFF, 0xFF, 0xC0,
+  0x0A, 0x50, 0x77, 0x00,
+  0x1C, 0x50, 0xA5, 0x00,
+  0x1A, 0x31, 0xC5, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0024[ 72] = { /* code 0024, DOLLAR SIGN */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x03, 0x90, 0x00,
+  0x00, 0x05, 0xA0, 0x00,
+  0x03, 0xEF, 0xFD, 0x20,
+  0x2D, 0x50, 0x0A, 0x50,
+  0x3D, 0x30, 0x00, 0x00,
+  0x1C, 0xE3, 0x00, 0x00,
+  0x00, 0x7F, 0xFA, 0x00,
+  0x00, 0x00, 0x2D, 0xA0,
+  0x00, 0x00, 0x07, 0xC0,
+  0x5A, 0x00, 0x1C, 0xA0,
+  0x1C, 0xFF, 0xFA, 0x00,
+  0x00, 0x5A, 0x00, 0x00,
+  0x00, 0x77, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0025[108] = { /* code 0025, PERCENT SIGN */
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x1C, 0xFD, 0x20, 0x02, 0xC3, 0x00,
+  0x5A, 0x07, 0x70, 0x0A, 0x50, 0x00,
+  0x7A, 0x05, 0xA0, 0x7A, 0x00, 0x00,
+  0x5C, 0x17, 0x73, 0xC2, 0x00, 0x00,
+  0x1C, 0xFD, 0x3C, 0x50, 0x00, 0x00,
+  0x00, 0x00, 0x7A, 0x3E, 0xF7, 0x00,
+  0x00, 0x03, 0xA2, 0xC5, 0x2C, 0x30,
+  0x00, 0x2C, 0x31, 0xA3, 0x1A, 0x30,
+  0x00, 0xA7, 0x01, 0xC5, 0x2B, 0x20,
+  0x05, 0xC1, 0x00, 0x5F, 0xF7, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0026[ 90] = { /* code 0026, AMPERSAND */
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x7F, 0xFF, 0x50, 0x00,
+  0x03, 0xD3, 0x05, 0xD2, 0x00,
+  0x05, 0xD2, 0x05, 0xD2, 0x00,
+  0x02, 0xD7, 0x3E, 0x50, 0x00,
+  0x00, 0x5F, 0xD2, 0x00, 0x00,
+  0x05, 0xEA, 0xE3, 0x05, 0xC1,
+  0x2D, 0x50, 0xAD, 0x2A, 0xA0,
+  0x3D, 0x30, 0x0A, 0xFE, 0x30,
+  0x2D, 0xA0, 0x05, 0xFF, 0x50,
+  0x02, 0xDF, 0xFD, 0x23, 0xEA,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0027[ 36] = { /* code 0027, APOSTROPHE */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x2D, 0x50,
+  0x2C, 0x30,
+  0x1A, 0x30,
+  0x1A, 0x30,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0028[ 54] = { /* code 0028, LEFT PARENTHESIS */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x77, 0x00,
+  0x02, 0xC3, 0x00,
+  0x05, 0xC1, 0x00,
+  0x0A, 0xA0, 0x00,
+  0x1C, 0x70, 0x00,
+  0x2D, 0x50, 0x00,
+  0x2D, 0x50, 0x00,
+  0x2D, 0x50, 0x00,
+  0x1C, 0x70, 0x00,
+  0x0A, 0xA0, 0x00,
+  0x05, 0xC1, 0x00,
+  0x02, 0xC3, 0x00,
+  0x00, 0x77, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0029[ 54] = { /* code 0029, RIGHT PARENTHESIS */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x2C, 0x30, 0x00,
+  0x07, 0x70, 0x00,
+  0x05, 0xC1, 0x00,
+  0x02, 0xC3, 0x00,
+  0x01, 0xC5, 0x00,
+  0x00, 0xA7, 0x00,
+  0x00, 0xA7, 0x00,
+  0x00, 0xA7, 0x00,
+  0x01, 0xC5, 0x00,
+  0x02, 0xC3, 0x00,
+  0x05, 0xD2, 0x00,
+  0x0A, 0xA0, 0x00,
+  0x2C, 0x30, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_002A[ 72] = { /* code 002A, ASTERISK */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x1A, 0x30, 0x00,
+  0x1C, 0xCA, 0x8E, 0x30,
+  0x00, 0x3E, 0xA0, 0x00,
+  0x1C, 0xCA, 0x8E, 0x30,
+  0x00, 0x1A, 0x30, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_002B[ 72] = { /* code 002B, PLUS SIGN */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x1C, 0x50, 0x00,
+  0x00, 0x1C, 0x50, 0x00,
+  0x00, 0x1C, 0x50, 0x00,
+  0x7F, 0xFF, 0xFF, 0xD0,
+  0x00, 0x1C, 0x50, 0x00,
+  0x00, 0x1C, 0x50, 0x00,
+  0x00, 0x1C, 0x50, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_002C[ 36] = { /* code 002C, COMMA */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x3C, 0x20,
+  0x77, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_002D[ 54] = { /* code 002D, HYPHEN-MINUS */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x7F, 0xFD, 0x20,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_002E[ 36] = { /* code 002E, FULL STOP */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1C, 0xA0,
+  0x1C, 0xA0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_002F[ 54] = { /* code 002F, SOLIDUS */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0xAA,
+  0x00, 0x02, 0xD5,
+  0x00, 0x05, 0xC1,
+  0x00, 0x0A, 0x70,
+  0x00, 0x2C, 0x30,
+  0x00, 0x5C, 0x10,
+  0x01, 0xC7, 0x00,
+  0x03, 0xD3, 0x00,
+  0x07, 0xA0, 0x00,
+  0x1C, 0x50, 0x00,
+  0x3C, 0x20, 0x00,
+  0x7A, 0x00, 0x00,
+  0xC5, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0030[ 72] = { /* code 0030, DIGIT ZERO */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x03, 0xEF, 0xF5, 0x00,
+  0x2D, 0x70, 0x5E, 0x30,
+  0x5D, 0x20, 0x1C, 0x50,
+  0x7C, 0x10, 0x1C, 0x70,
+  0x7C, 0x10, 0x0A, 0x70,
+  0x7C, 0x10, 0x1C, 0x70,
+  0x5D, 0x20, 0x1C, 0x50,
+  0x2D, 0x50, 0x5D, 0x20,
+  0x03, 0xEF, 0xE3, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0031[ 72] = { /* code 0031, DIGIT ONE */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x7F, 0x70, 0x00,
+  0x2D, 0x8C, 0x70, 0x00,
+  0x00, 0x1C, 0x70, 0x00,
+  0x00, 0x1C, 0x70, 0x00,
+  0x00, 0x1C, 0x70, 0x00,
+  0x00, 0x1C, 0x70, 0x00,
+  0x00, 0x1C, 0x70, 0x00,
+  0x00, 0x1C, 0x70, 0x00,
+  0x2D, 0xFF, 0xFF, 0x70,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0032[ 72] = { /* code 0032, DIGIT TWO */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x07, 0xFF, 0xF5, 0x00,
+  0x3A, 0x10, 0x7D, 0x20,
+  0x00, 0x00, 0x3D, 0x30,
+  0x00, 0x00, 0x5D, 0x20,
+  0x00, 0x01, 0xC7, 0x00,
+  0x00, 0x0A, 0xC1, 0x00,
+  0x00, 0xAC, 0x10, 0x00,
+  0x1C, 0xC1, 0x00, 0x00,
+  0x5F, 0xFF, 0xFF, 0xA0,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0033[ 72] = { /* code 0033, DIGIT THREE */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x07, 0xFF, 0xD2, 0x00,
+  0x2A, 0x10, 0xAA, 0x00,
+  0x00, 0x00, 0x7C, 0x10,
+  0x00, 0x02, 0xD7, 0x00,
+  0x05, 0xFF, 0xA0, 0x00,
+  0x00, 0x00, 0x7D, 0x20,
+  0x00, 0x00, 0x3D, 0x30,
+  0x39, 0x00, 0x7D, 0x20,
+  0x1C, 0xFF, 0xE3, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0034[ 72] = { /* code 0034, DIGIT FOUR */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x0A, 0xF7, 0x00,
+  0x00, 0x5C, 0xC7, 0x00,
+  0x01, 0xC6, 0xC7, 0x00,
+  0x07, 0xA1, 0xC7, 0x00,
+  0x3C, 0x21, 0xC7, 0x00,
+  0xC5, 0x01, 0xC7, 0x00,
+  0xDF, 0xFF, 0xFF, 0xC0,
+  0x00, 0x01, 0xC7, 0x00,
+  0x00, 0x01, 0xC7, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0035[ 72] = { /* code 0035, DIGIT FIVE */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x1C, 0xFF, 0xFA, 0x00,
+  0x1C, 0x50, 0x00, 0x00,
+  0x1C, 0x50, 0x00, 0x00,
+  0x1C, 0xFF, 0xE3, 0x00,
+  0x00, 0x00, 0x7D, 0x20,
+  0x00, 0x00, 0x2D, 0x50,
+  0x00, 0x00, 0x3D, 0x30,
+  0x93, 0x00, 0xAC, 0x10,
+  0x5F, 0xFF, 0xC1, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0036[ 72] = { /* code 0036, DIGIT SIX */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x7F, 0xFE, 0x30,
+  0x07, 0xC1, 0x00, 0x00,
+  0x2C, 0x30, 0x00, 0x00,
+  0x3D, 0xDF, 0xFA, 0x00,
+  0x5E, 0x30, 0x3E, 0x50,
+  0x5D, 0x20, 0x1C, 0x70,
+  0x3D, 0x30, 0x1C, 0x70,
+  0x1C, 0x70, 0x5E, 0x30,
+  0x03, 0xEF, 0xF5, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0037[ 72] = { /* code 0037, DIGIT SEVEN */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x5F, 0xFF, 0xFF, 0xD0,
+  0x00, 0x00, 0x0A, 0xA0,
+  0x00, 0x00, 0x3D, 0x30,
+  0x00, 0x00, 0xAA, 0x00,
+  0x00, 0x02, 0xD5, 0x00,
+  0x00, 0x07, 0xC1, 0x00,
+  0x00, 0x2D, 0x50, 0x00,
+  0x00, 0x7D, 0x20, 0x00,
+  0x02, 0xD7, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0038[ 72] = { /* code 0038, DIGIT EIGHT */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x05, 0xFF, 0xF7, 0x00,
+  0x2C, 0x30, 0x3D, 0x30,
+  0x3C, 0x20, 0x2C, 0x30,
+  0x0A, 0xD3, 0xC7, 0x00,
+  0x00, 0xAF, 0xC1, 0x00,
+  0x2D, 0x50, 0x7E, 0x30,
+  0x7C, 0x10, 0x1C, 0x70,
+  0x5D, 0x20, 0x3E, 0x50,
+  0x0A, 0xFF, 0xF7, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0039[ 72] = { /* code 0039, DIGIT NINE */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x05, 0xFF, 0xE3, 0x00,
+  0x5E, 0x30, 0x5D, 0x20,
+  0x7C, 0x10, 0x2C, 0x30,
+  0x5D, 0x20, 0x2D, 0x50,
+  0x0A, 0xFF, 0xED, 0x50,
+  0x00, 0x00, 0x2D, 0x50,
+  0x00, 0x00, 0x5D, 0x20,
+  0x00, 0x02, 0xD7, 0x00,
+  0x3E, 0xFF, 0x70, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_003A[ 36] = { /* code 003A, COLON */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0A, 0xC1,
+  0x0A, 0xC1,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0A, 0xC1,
+  0x0A, 0xC1,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_003B[ 36] = { /* code 003B, SEMICOLON */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0A, 0xC1,
+  0x0A, 0xC1,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x07, 0xC1,
+  0x07, 0xC1,
+  0x1C, 0x50,
+  0x5A, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_003C[ 72] = { /* code 003C, LESS-THAN SIGN */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x07, 0xA0,
+  0x00, 0x07, 0xF7, 0x00,
+  0x07, 0xFA, 0x00, 0x00,
+  0x7C, 0x10, 0x00, 0x00,
+  0x07, 0xFA, 0x00, 0x00,
+  0x00, 0x07, 0xF7, 0x00,
+  0x00, 0x00, 0x07, 0xA0,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_003D[ 72] = { /* code 003D, EQUALS SIGN */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x5F, 0xFF, 0xFF, 0xC0,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x5F, 0xFF, 0xFF, 0xC0,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_003E[ 72] = { /* code 003E, GREATER-THAN SIGN */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x5D, 0x20, 0x00, 0x00,
+  0x02, 0xDD, 0x20, 0x00,
+  0x00, 0x03, 0xED, 0x20,
+  0x00, 0x00, 0x05, 0xD0,
+  0x00, 0x03, 0xED, 0x20,
+  0x02, 0xDD, 0x20, 0x00,
+  0x5D, 0x20, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_003F[ 72] = { /* code 003F, QUESTION MARK */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x07, 0xFF, 0xE3, 0x00,
+  0x2A, 0x10, 0x5D, 0x20,
+  0x00, 0x00, 0x2D, 0x50,
+  0x00, 0x00, 0x5E, 0x30,
+  0x00, 0x7F, 0xF5, 0x00,
+  0x00, 0x7A, 0x00, 0x00,
+  0x00, 0x5A, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x7C, 0x10, 0x00,
+  0x00, 0x7C, 0x10, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0040[126] = { /* code 0040, COMMERCIAL AT */
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x5F, 0xFF, 0xFE, 0x30, 0x00,
+  0x00, 0x1C, 0xD2, 0x00, 0x05, 0xF7, 0x00,
+  0x00, 0xAA, 0x00, 0x00, 0x00, 0x5D, 0x20,
+  0x03, 0xC2, 0x2D, 0xFB, 0xB2, 0x2C, 0x30,
+  0x07, 0xA0, 0xA7, 0x07, 0xC1, 0x2C, 0x30,
+  0x0A, 0x72, 0xC3, 0x07, 0x70, 0x3C, 0x20,
+  0x0A, 0x53, 0xC2, 0x2D, 0x51, 0xC7, 0x00,
+  0x0A, 0x71, 0xCF, 0xD6, 0xFF, 0xA0, 0x00,
+  0x07, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x01, 0xCC, 0x10, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x0A, 0xFF, 0xFF, 0xD2, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0041[ 90] = { /* code 0041, LATIN CAPITAL LETTER A */
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x0A, 0xF5, 0x00, 0x00,
+  0x00, 0x2C, 0xAA, 0x00, 0x00,
+  0x00, 0x5C, 0x4C, 0x20, 0x00,
+  0x00, 0xA7, 0x1C, 0x70, 0x00,
+  0x03, 0xD3, 0x07, 0xC1, 0x00,
+  0x07, 0xC1, 0x03, 0xD3, 0x00,
+  0x1C, 0xFF, 0xFF, 0xF7, 0x00,
+  0x5E, 0x30, 0x00, 0x7D, 0x20,
+  0xAA, 0x00, 0x00, 0x2D, 0x50,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0042[ 72] = { /* code 0042, LATIN CAPITAL LETTER B */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x1C, 0xFF, 0xFD, 0x20,
+  0x1C, 0x70, 0x1C, 0xA0,
+  0x1C, 0x70, 0x07, 0xC1,
+  0x1C, 0x70, 0x1C, 0x70,
+  0x1C, 0xFF, 0xFE, 0x30,
+  0x1C, 0x70, 0x05, 0xE3,
+  0x1C, 0x70, 0x02, 0xD5,
+  0x1C, 0x70, 0x05, 0xE3,
+  0x1C, 0xFF, 0xFF, 0x50,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0043[ 72] = { /* code 0043, LATIN CAPITAL LETTER C */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x3E, 0xFF, 0xC1,
+  0x05, 0xE3, 0x00, 0x77,
+  0x2D, 0x50, 0x00, 0x00,
+  0x3C, 0x20, 0x00, 0x00,
+  0x5D, 0x20, 0x00, 0x00,
+  0x5D, 0x20, 0x00, 0x00,
+  0x2D, 0x50, 0x00, 0x00,
+  0x07, 0xE3, 0x00, 0x77,
+  0x00, 0x7F, 0xFF, 0xC1,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0044[ 90] = { /* code 0044, LATIN CAPITAL LETTER D */
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x1C, 0xFF, 0xFF, 0x50, 0x00,
+  0x1C, 0x70, 0x05, 0xF7, 0x00,
+  0x1C, 0x70, 0x00, 0x5D, 0x20,
+  0x1C, 0x70, 0x00, 0x2D, 0x50,
+  0x1C, 0x70, 0x00, 0x2D, 0x50,
+  0x1C, 0x70, 0x00, 0x2D, 0x50,
+  0x1C, 0x70, 0x00, 0x5D, 0x20,
+  0x1C, 0x70, 0x03, 0xE7, 0x00,
+  0x1C, 0xFF, 0xFE, 0x30, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0045[ 72] = { /* code 0045, LATIN CAPITAL LETTER E */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x1C, 0xFF, 0xFF, 0x70,
+  0x1C, 0x50, 0x00, 0x00,
+  0x1C, 0x50, 0x00, 0x00,
+  0x1C, 0x50, 0x00, 0x00,
+  0x1C, 0xFF, 0xFD, 0x20,
+  0x1C, 0x50, 0x00, 0x00,
+  0x1C, 0x50, 0x00, 0x00,
+  0x1C, 0x50, 0x00, 0x00,
+  0x1C, 0xFF, 0xFF, 0x70,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0046[ 72] = { /* code 0046, LATIN CAPITAL LETTER F */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x0A, 0xFF, 0xFF, 0x50,
+  0x0A, 0x70, 0x00, 0x00,
+  0x0A, 0x70, 0x00, 0x00,
+  0x0A, 0x70, 0x00, 0x00,
+  0x0A, 0xFF, 0xFD, 0x20,
+  0x0A, 0x70, 0x00, 0x00,
+  0x0A, 0x70, 0x00, 0x00,
+  0x0A, 0x70, 0x00, 0x00,
+  0x0A, 0x70, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0047[ 90] = { /* code 0047, LATIN CAPITAL LETTER G */
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x3E, 0xFF, 0xF5, 0x00,
+  0x05, 0xF5, 0x00, 0x2B, 0x20,
+  0x2D, 0x50, 0x00, 0x00, 0x00,
+  0x5D, 0x20, 0x00, 0x00, 0x00,
+  0x5D, 0x20, 0x7F, 0xFD, 0x20,
+  0x5D, 0x20, 0x00, 0x5D, 0x20,
+  0x2D, 0x50, 0x00, 0x5D, 0x20,
+  0x07, 0xF5, 0x00, 0x5D, 0x20,
+  0x00, 0x3E, 0xFF, 0xF7, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0048[ 90] = { /* code 0048, LATIN CAPITAL LETTER H */
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x1C, 0x70, 0x00, 0x7C, 0x10,
+  0x1C, 0x70, 0x00, 0x7C, 0x10,
+  0x1C, 0x70, 0x00, 0x7C, 0x10,
+  0x1C, 0x70, 0x00, 0x7C, 0x10,
+  0x1C, 0xFF, 0xFF, 0xFC, 0x10,
+  0x1C, 0x70, 0x00, 0x7C, 0x10,
+  0x1C, 0x70, 0x00, 0x7C, 0x10,
+  0x1C, 0x70, 0x00, 0x7C, 0x10,
+  0x1C, 0x70, 0x00, 0x7C, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0049[ 36] = { /* code 0049, LATIN CAPITAL LETTER I */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_004A[ 54] = { /* code 004A, LATIN CAPITAL LETTER J */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x7A, 0x00,
+  0x00, 0x7A, 0x00,
+  0x00, 0x7A, 0x00,
+  0x00, 0x7A, 0x00,
+  0x00, 0x7A, 0x00,
+  0x00, 0x7A, 0x00,
+  0x00, 0x7A, 0x00,
+  0x00, 0xAA, 0x00,
+  0xDF, 0xD2, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_004B[ 72] = { /* code 004B, LATIN CAPITAL LETTER K */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x0A, 0x70, 0x05, 0xE3,
+  0x0A, 0x70, 0x3E, 0x50,
+  0x0A, 0x72, 0xD5, 0x00,
+  0x0A, 0x8C, 0x70, 0x00,
+  0x0A, 0xFE, 0x30, 0x00,
+  0x0A, 0x77, 0xD2, 0x00,
+  0x0A, 0x71, 0xCA, 0x00,
+  0x0A, 0x70, 0x2D, 0x70,
+  0x0A, 0x70, 0x03, 0xE5,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_004C[ 54] = { /* code 004C, LATIN CAPITAL LETTER L */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x1C, 0x50, 0x00,
+  0x1C, 0x50, 0x00,
+  0x1C, 0x50, 0x00,
+  0x1C, 0x50, 0x00,
+  0x1C, 0x50, 0x00,
+  0x1C, 0x50, 0x00,
+  0x1C, 0x50, 0x00,
+  0x1C, 0x50, 0x00,
+  0x1C, 0xFF, 0xFE,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_004D[108] = { /* code 004D, LATIN CAPITAL LETTER M */
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x1C, 0xF5, 0x00, 0x00, 0x5F, 0xC1,
+  0x1C, 0xCC, 0x10, 0x00, 0xA9, 0xC1,
+  0x1C, 0x6C, 0x30, 0x03, 0xC6, 0xC1,
+  0x1C, 0x5A, 0x70, 0x07, 0xA5, 0xC1,
+  0x1C, 0x55, 0xD2, 0x2C, 0x35, 0xC1,
+  0x1C, 0x52, 0xD5, 0x5C, 0x15, 0xC1,
+  0x1C, 0x50, 0x7A, 0xA7, 0x05, 0xC1,
+  0x1C, 0x50, 0x3E, 0xD2, 0x05, 0xC1,
+  0x1C, 0x50, 0x1C, 0xA0, 0x05, 0xC1,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_004E[ 90] = { /* code 004E, LATIN CAPITAL LETTER N */
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x0A, 0xF7, 0x00, 0x07, 0xA0,
+  0x0A, 0xCD, 0x20, 0x07, 0xA0,
+  0x0A, 0x8C, 0xA0, 0x07, 0xA0,
+  0x0A, 0x73, 0xD3, 0x07, 0xA0,
+  0x0A, 0x70, 0xAC, 0x17, 0xA0,
+  0x0A, 0x70, 0x2D, 0x77, 0xA0,
+  0x0A, 0x70, 0x05, 0xD9, 0xA0,
+  0x0A, 0x70, 0x01, 0xCF, 0xA0,
+  0x0A, 0x70, 0x00, 0x3E, 0xA0,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_004F[ 90] = { /* code 004F, LATIN CAPITAL LETTER O */
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x3E, 0xFF, 0xF7, 0x00,
+  0x05, 0xF5, 0x00, 0x3E, 0x70,
+  0x1C, 0x70, 0x00, 0x05, 0xD2,
+  0x3D, 0x30, 0x00, 0x02, 0xC3,
+  0x3C, 0x20, 0x00, 0x02, 0xD5,
+  0x3D, 0x30, 0x00, 0x02, 0xC3,
+  0x2D, 0x50, 0x00, 0x05, 0xD2,
+  0x07, 0xE3, 0x00, 0x3E, 0x70,
+  0x00, 0x5F, 0xFF, 0xE3, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0050[ 72] = { /* code 0050, LATIN CAPITAL LETTER P */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x0A, 0xFF, 0xFD, 0x20,
+  0x0A, 0x70, 0x07, 0xD2,
+  0x0A, 0x70, 0x02, 0xD5,
+  0x0A, 0x70, 0x03, 0xD3,
+  0x0A, 0x70, 0x0A, 0xC1,
+  0x0A, 0xFF, 0xFC, 0x10,
+  0x0A, 0x70, 0x00, 0x00,
+  0x0A, 0x70, 0x00, 0x00,
+  0x0A, 0x70, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0051[ 90] = { /* code 0051, LATIN CAPITAL LETTER Q */
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x3E, 0xFF, 0xF5, 0x00,
+  0x05, 0xE3, 0x00, 0x3E, 0x50,
+  0x2D, 0x50, 0x00, 0x07, 0xC1,
+  0x3D, 0x30, 0x00, 0x03, 0xD3,
+  0x5D, 0x20, 0x00, 0x03, 0xD3,
+  0x3D, 0x30, 0x00, 0x03, 0xD3,
+  0x2D, 0x50, 0x00, 0x07, 0xC1,
+  0x07, 0xE3, 0x00, 0x5F, 0x50,
+  0x00, 0x7F, 0xFF, 0xFF, 0xD2,
+  0x00, 0x00, 0x00, 0x00, 0x5F,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0052[ 72] = { /* code 0052, LATIN CAPITAL LETTER R */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x1C, 0xFF, 0xFD, 0x20,
+  0x1C, 0x70, 0x0A, 0xA0,
+  0x1C, 0x70, 0x05, 0xC1,
+  0x1C, 0x70, 0x1C, 0xA0,
+  0x1C, 0xFF, 0xF7, 0x00,
+  0x1C, 0x70, 0x5D, 0x20,
+  0x1C, 0x70, 0x1C, 0x70,
+  0x1C, 0x70, 0x05, 0xD2,
+  0x1C, 0x70, 0x02, 0xD5,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0053[ 72] = { /* code 0053, LATIN CAPITAL LETTER S */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x05, 0xFF, 0xF5, 0x00,
+  0x3E, 0x50, 0x2A, 0x10,
+  0x3D, 0x30, 0x00, 0x00,
+  0x1C, 0xE3, 0x00, 0x00,
+  0x00, 0xAF, 0xE3, 0x00,
+  0x00, 0x00, 0x7E, 0x30,
+  0x00, 0x00, 0x1C, 0x50,
+  0x77, 0x00, 0x5E, 0x30,
+  0x1C, 0xFF, 0xE3, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0054[ 72] = { /* code 0054, LATIN CAPITAL LETTER T */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0xDF, 0xFF, 0xFF, 0xD0,
+  0x00, 0x3D, 0x30, 0x00,
+  0x00, 0x3D, 0x30, 0x00,
+  0x00, 0x3D, 0x30, 0x00,
+  0x00, 0x3D, 0x30, 0x00,
+  0x00, 0x3D, 0x30, 0x00,
+  0x00, 0x3D, 0x30, 0x00,
+  0x00, 0x3D, 0x30, 0x00,
+  0x00, 0x3D, 0x30, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0055[ 90] = { /* code 0055, LATIN CAPITAL LETTER U */
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x1C, 0x50, 0x00, 0x5C, 0x10,
+  0x1C, 0x50, 0x00, 0x5C, 0x10,
+  0x1C, 0x50, 0x00, 0x5C, 0x10,
+  0x1C, 0x50, 0x00, 0x5C, 0x10,
+  0x1C, 0x50, 0x00, 0x5C, 0x10,
+  0x1C, 0x50, 0x00, 0x5C, 0x10,
+  0x1C, 0x70, 0x00, 0x7C, 0x10,
+  0x07, 0xD2, 0x02, 0xD5, 0x00,
+  0x00, 0x7F, 0xFF, 0x70, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0056[ 90] = { /* code 0056, LATIN CAPITAL LETTER V */
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x7D, 0x20, 0x00, 0x1C, 0x50,
+  0x2D, 0x50, 0x00, 0x5D, 0x20,
+  0x0A, 0xA0, 0x00, 0xAA, 0x00,
+  0x05, 0xD2, 0x02, 0xD5, 0x00,
+  0x02, 0xD5, 0x05, 0xC1, 0x00,
+  0x00, 0x7A, 0x0A, 0x70, 0x00,
+  0x00, 0x3D, 0x5C, 0x30, 0x00,
+  0x00, 0x1C, 0xCC, 0x10, 0x00,
+  0x00, 0x07, 0xF5, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0057[126] = { /* code 0057, LATIN CAPITAL LETTER W */
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x7C, 0x10, 0x03, 0xE5, 0x00, 0x07, 0xC0,
+  0x3D, 0x30, 0x05, 0xFA, 0x00, 0x0A, 0x70,
+  0x1C, 0x70, 0x0A, 0xAC, 0x20, 0x2C, 0x30,
+  0x07, 0xA0, 0x2C, 0x5D, 0x50, 0x5D, 0x20,
+  0x05, 0xD2, 0x3A, 0x1A, 0x70, 0x7A, 0x00,
+  0x02, 0xD5, 0x7A, 0x05, 0xC2, 0xC5, 0x00,
+  0x00, 0xA7, 0xA5, 0x02, 0xC6, 0xC2, 0x00,
+  0x00, 0x5D, 0xC2, 0x01, 0xCC, 0xA0, 0x00,
+  0x00, 0x2D, 0xC1, 0x00, 0x7F, 0x50, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0058[ 72] = { /* code 0058, LATIN CAPITAL LETTER X */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x5D, 0x20, 0x03, 0xD3,
+  0x1C, 0xA0, 0x1C, 0x70,
+  0x03, 0xE5, 0x7D, 0x20,
+  0x00, 0x7D, 0xE5, 0x00,
+  0x00, 0x2D, 0xC1, 0x00,
+  0x00, 0xAB, 0xD5, 0x00,
+  0x03, 0xD3, 0x5D, 0x20,
+  0x1C, 0x70, 0x1C, 0xA0,
+  0x7D, 0x20, 0x03, 0xE5,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0059[ 72] = { /* code 0059, LATIN CAPITAL LETTER Y */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0xCA, 0x00, 0x0A, 0xA0,
+  0x5E, 0x30, 0x3D, 0x30,
+  0x0A, 0xA0, 0xAA, 0x00,
+  0x03, 0xC5, 0xD3, 0x00,
+  0x00, 0xAF, 0xA0, 0x00,
+  0x00, 0x3C, 0x20, 0x00,
+  0x00, 0x3C, 0x20, 0x00,
+  0x00, 0x3C, 0x20, 0x00,
+  0x00, 0x3C, 0x20, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_005A[ 72] = { /* code 005A, LATIN CAPITAL LETTER Z */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x7F, 0xFF, 0xFF, 0x70,
+  0x00, 0x00, 0x3D, 0x30,
+  0x00, 0x01, 0xC7, 0x00,
+  0x00, 0x07, 0xC1, 0x00,
+  0x00, 0x3D, 0x30, 0x00,
+  0x01, 0xC7, 0x00, 0x00,
+  0x07, 0xC1, 0x00, 0x00,
+  0x3D, 0x30, 0x00, 0x00,
+  0x7F, 0xFF, 0xFF, 0xA0,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_005B[ 54] = { /* code 005B, LEFT SQUARE BRACKET */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x0A, 0xFD, 0x20,
+  0x0A, 0x70, 0x00,
+  0x0A, 0x70, 0x00,
+  0x0A, 0x70, 0x00,
+  0x0A, 0x70, 0x00,
+  0x0A, 0x70, 0x00,
+  0x0A, 0x70, 0x00,
+  0x0A, 0x70, 0x00,
+  0x0A, 0x70, 0x00,
+  0x0A, 0x70, 0x00,
+  0x0A, 0x70, 0x00,
+  0x0A, 0xFD, 0x20,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_005C[ 54] = { /* code 005C, REVERSE SOLIDUS */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0xC5, 0x00, 0x00,
+  0x7C, 0x10, 0x00,
+  0x3D, 0x30, 0x00,
+  0x1C, 0x70, 0x00,
+  0x05, 0xC1, 0x00,
+  0x02, 0xC3, 0x00,
+  0x00, 0xA7, 0x00,
+  0x00, 0x5C, 0x10,
+  0x00, 0x2D, 0x50,
+  0x00, 0x0A, 0xA0,
+  0x00, 0x05, 0xD2,
+  0x00, 0x01, 0xC5,
+  0x00, 0x00, 0x7A,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_005D[ 54] = { /* code 005D, RIGHT SQUARE BRACKET */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x5F, 0xE3, 0x00,
+  0x02, 0xC3, 0x00,
+  0x02, 0xC3, 0x00,
+  0x02, 0xC3, 0x00,
+  0x02, 0xC3, 0x00,
+  0x02, 0xC3, 0x00,
+  0x02, 0xC3, 0x00,
+  0x02, 0xC3, 0x00,
+  0x02, 0xC3, 0x00,
+  0x02, 0xC3, 0x00,
+  0x02, 0xC3, 0x00,
+  0x5F, 0xE3, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_005E[ 72] = { /* code 005E, CIRCUMFLEX ACCENT */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x3E, 0x70, 0x00,
+  0x00, 0xAA, 0xC2, 0x00,
+  0x03, 0xC2, 0xA7, 0x00,
+  0x0A, 0xA0, 0x3C, 0x20,
+  0x3D, 0x30, 0x1C, 0x70,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_005F[ 72] = { /* code 005F, LOW LINE */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0xDF, 0xFF, 0xFF, 0xF0,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0060[ 36] = { /* code 0060, GRAVE ACCENT */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x1C, 0x70,
+  0x01, 0xC5,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0061[ 72] = { /* code 0061, LATIN SMALL LETTER A */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x03, 0xEF, 0xF5, 0x00,
+  0x2A, 0x10, 0x7C, 0x10,
+  0x00, 0x00, 0x3C, 0x20,
+  0x07, 0xFF, 0xFD, 0x20,
+  0x5D, 0x20, 0x3C, 0x20,
+  0x5D, 0x20, 0xAD, 0x20,
+  0x0A, 0xFF, 0x9B, 0x20,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0062[ 72] = { /* code 0062, LATIN SMALL LETTER B */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x1C, 0x50, 0x00, 0x00,
+  0x1C, 0x50, 0x00, 0x00,
+  0x1C, 0x50, 0x00, 0x00,
+  0x1C, 0x6D, 0xFE, 0x30,
+  0x1C, 0xE3, 0x07, 0xD2,
+  0x1C, 0x50, 0x02, 0xC3,
+  0x1C, 0x50, 0x02, 0xD5,
+  0x1C, 0x50, 0x02, 0xC3,
+  0x1C, 0xE3, 0x07, 0xC1,
+  0x1A, 0x6E, 0xFD, 0x20,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0063[ 54] = { /* code 0063, LATIN SMALL LETTER C */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x03, 0xEF, 0xF5,
+  0x2D, 0x70, 0x2A,
+  0x5D, 0x20, 0x00,
+  0x5C, 0x10, 0x00,
+  0x5D, 0x20, 0x00,
+  0x2D, 0x70, 0x2A,
+  0x03, 0xEF, 0xE3,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0064[ 72] = { /* code 0064, LATIN SMALL LETTER D */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x05, 0xC1,
+  0x00, 0x00, 0x05, 0xC1,
+  0x00, 0x00, 0x05, 0xC1,
+  0x03, 0xEF, 0xE8, 0xC1,
+  0x1C, 0x70, 0x2D, 0xC1,
+  0x3C, 0x20, 0x05, 0xC1,
+  0x5D, 0x20, 0x05, 0xC1,
+  0x3C, 0x20, 0x05, 0xC1,
+  0x2D, 0x70, 0x3E, 0xC1,
+  0x03, 0xEF, 0xD5, 0xA1,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0065[ 72] = { /* code 0065, LATIN SMALL LETTER E */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x01, 0xCF, 0xFD, 0x20,
+  0x0A, 0xA0, 0x07, 0xC1,
+  0x3D, 0x30, 0x02, 0xC3,
+  0x3E, 0xFF, 0xFF, 0xE3,
+  0x3C, 0x20, 0x00, 0x00,
+  0x1C, 0x70, 0x00, 0x00,
+  0x01, 0xCF, 0xFF, 0xC1,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0066[ 54] = { /* code 0066, LATIN SMALL LETTER F */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x01, 0xCF, 0xC0,
+  0x05, 0xD2, 0x00,
+  0x05, 0xC1, 0x00,
+  0x7F, 0xFF, 0xA0,
+  0x05, 0xC1, 0x00,
+  0x05, 0xC1, 0x00,
+  0x05, 0xC1, 0x00,
+  0x05, 0xC1, 0x00,
+  0x05, 0xC1, 0x00,
+  0x05, 0xC1, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0067[ 72] = { /* code 0067, LATIN SMALL LETTER G */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x05, 0xFF, 0xFF, 0xA0,
+  0x2C, 0x30, 0x7A, 0x00,
+  0x3C, 0x20, 0x5C, 0x10,
+  0x2C, 0x30, 0xAA, 0x00,
+  0x3E, 0xFF, 0xD2, 0x00,
+  0x5A, 0x00, 0x00, 0x00,
+  0x0A, 0xFF, 0xFC, 0x10,
+  0x7C, 0x10, 0x0A, 0x70,
+  0xAA, 0x00, 0x1C, 0x70,
+  0x1C, 0xFF, 0xF7, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0068[ 72] = { /* code 0068, LATIN SMALL LETTER H */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x1C, 0x50, 0x00, 0x00,
+  0x1C, 0x50, 0x00, 0x00,
+  0x1C, 0x50, 0x00, 0x00,
+  0x1C, 0x6D, 0xFE, 0x30,
+  0x1C, 0xE3, 0x0A, 0xA0,
+  0x1C, 0x50, 0x05, 0xC1,
+  0x1C, 0x50, 0x05, 0xC1,
+  0x1C, 0x50, 0x05, 0xC1,
+  0x1C, 0x50, 0x05, 0xC1,
+  0x1C, 0x50, 0x05, 0xC1,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0069[ 36] = { /* code 0069, LATIN SMALL LETTER I */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0A, 0xC1,
+  0x00, 0x00,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_006A[ 36] = { /* code 006A, LATIN SMALL LETTER J */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0A, 0xC1,
+  0x00, 0x00,
+  0x07, 0xA0,
+  0x07, 0xA0,
+  0x07, 0xA0,
+  0x07, 0xA0,
+  0x07, 0xA0,
+  0x07, 0xA0,
+  0x07, 0xA0,
+  0x07, 0xA0,
+  0x0A, 0x70,
+  0xED, 0x20,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_006B[ 72] = { /* code 006B, LATIN SMALL LETTER K */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x1C, 0x50, 0x00, 0x00,
+  0x1C, 0x50, 0x00, 0x00,
+  0x1C, 0x50, 0x00, 0x00,
+  0x1C, 0x50, 0x5E, 0x30,
+  0x1C, 0x55, 0xE3, 0x00,
+  0x1C, 0x8D, 0x30, 0x00,
+  0x1C, 0xFE, 0x30, 0x00,
+  0x1C, 0x57, 0xC1, 0x00,
+  0x1C, 0x51, 0xCA, 0x00,
+  0x1C, 0x50, 0x2D, 0x70,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_006C[ 36] = { /* code 006C, LATIN SMALL LETTER L */
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x0A, 0xA0,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00,
+  0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_006D[108] = { /* code 006D, LATIN SMALL LETTER M */
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x1A, 0x5D, 0xFD, 0x3C, 0xFE, 0x30,
+  0x1C, 0xD2, 0x1C, 0xF5, 0x07, 0xC1,
+  0x1C, 0x50, 0x07, 0xA0, 0x05, 0xD2,
+  0x1C, 0x50, 0x07, 0xA0, 0x05, 0xD2,
+  0x1C, 0x50, 0x07, 0xA0, 0x05, 0xD2,
+  0x1C, 0x50, 0x07, 0xA0, 0x05, 0xD2,
+  0x1C, 0x50, 0x07, 0xA0, 0x05, 0xD2,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_006E[ 72] = { /* code 006E, LATIN SMALL LETTER N */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x1C, 0x6D, 0xFE, 0x30,
+  0x1C, 0xE3, 0x0A, 0xA0,
+  0x1C, 0x50, 0x05, 0xC1,
+  0x1C, 0x50, 0x05, 0xC1,
+  0x1C, 0x50, 0x05, 0xC1,
+  0x1C, 0x50, 0x05, 0xC1,
+  0x1C, 0x50, 0x05, 0xC1,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_006F[ 72] = { /* code 006F, LATIN SMALL LETTER O */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x01, 0xCF, 0xFD, 0x20,
+  0x1C, 0xA0, 0x07, 0xD2,
+  0x3C, 0x20, 0x02, 0xC3,
+  0x5D, 0x20, 0x01, 0xC5,
+  0x3C, 0x20, 0x02, 0xC3,
+  0x1C, 0xA0, 0x07, 0xC1,
+  0x02, 0xDF, 0xFC, 0x10,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0070[ 72] = { /* code 0070, LATIN SMALL LETTER P */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x1A, 0x5D, 0xFE, 0x30,
+  0x1C, 0xE3, 0x07, 0xD2,
+  0x1C, 0x50, 0x02, 0xC3,
+  0x1C, 0x50, 0x02, 0xD5,
+  0x1C, 0x50, 0x02, 0xC3,
+  0x1C, 0xE3, 0x07, 0xC1,
+  0x1C, 0x6D, 0xFD, 0x20,
+  0x1C, 0x50, 0x00, 0x00,
+  0x1C, 0x50, 0x00, 0x00,
+  0x1C, 0x50, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0071[ 72] = { /* code 0071, LATIN SMALL LETTER Q */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x02, 0xDF, 0xD5, 0xA1,
+  0x1C, 0x70, 0x2D, 0xC1,
+  0x3C, 0x20, 0x05, 0xC1,
+  0x5D, 0x20, 0x05, 0xC1,
+  0x3C, 0x20, 0x05, 0xC1,
+  0x2D, 0x70, 0x3E, 0xC1,
+  0x03, 0xEF, 0xD6, 0xC1,
+  0x00, 0x00, 0x05, 0xC1,
+  0x00, 0x00, 0x05, 0xC1,
+  0x00, 0x00, 0x05, 0xC1,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0072[ 54] = { /* code 0072, LATIN SMALL LETTER R */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x2C, 0x8F, 0xD0,
+  0x2D, 0xD2, 0x00,
+  0x2D, 0x50, 0x00,
+  0x2D, 0x50, 0x00,
+  0x2D, 0x50, 0x00,
+  0x2D, 0x50, 0x00,
+  0x2D, 0x50, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0073[ 54] = { /* code 0073, LATIN SMALL LETTER S */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x07, 0xFF, 0xE3,
+  0x3C, 0x20, 0x00,
+  0x3E, 0x50, 0x00,
+  0x03, 0xEF, 0x70,
+  0x00, 0x02, 0xD5,
+  0x00, 0x01, 0xC5,
+  0x5F, 0xFF, 0xA0,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0074[ 54] = { /* code 0074, LATIN SMALL LETTER T */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x07, 0xA0, 0x00,
+  0x07, 0xA0, 0x00,
+  0xCF, 0xFF, 0x70,
+  0x07, 0xA0, 0x00,
+  0x07, 0xA0, 0x00,
+  0x07, 0xA0, 0x00,
+  0x07, 0xA0, 0x00,
+  0x07, 0xC1, 0x00,
+  0x03, 0xEF, 0x70,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0075[ 72] = { /* code 0075, LATIN SMALL LETTER U */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x1C, 0x50, 0x05, 0xC1,
+  0x1C, 0x50, 0x05, 0xC1,
+  0x1C, 0x50, 0x05, 0xC1,
+  0x1C, 0x50, 0x05, 0xC1,
+  0x1C, 0x50, 0x05, 0xC1,
+  0x0A, 0xA0, 0x3E, 0xC1,
+  0x02, 0xDF, 0xD6, 0xC1,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0076[ 72] = { /* code 0076, LATIN SMALL LETTER V */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0xAA, 0x00, 0x1C, 0x70,
+  0x5D, 0x20, 0x3D, 0x30,
+  0x2D, 0x50, 0x7C, 0x10,
+  0x0A, 0xA1, 0xC5, 0x00,
+  0x03, 0xC5, 0xC2, 0x00,
+  0x01, 0xCC, 0xA0, 0x00,
+  0x00, 0x7F, 0x50, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0077[108] = { /* code 0077, LATIN SMALL LETTER W */
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x7A, 0x00, 0x5D, 0x20, 0x2D, 0x50,
+  0x3C, 0x20, 0x6D, 0x50, 0x3C, 0x20,
+  0x2D, 0x51, 0xA6, 0x70, 0x7A, 0x00,
+  0x0A, 0x72, 0x83, 0xA2, 0xC5, 0x00,
+  0x05, 0xC6, 0x71, 0xA5, 0xB2, 0x00,
+  0x02, 0xCA, 0x50, 0xA9, 0xA0, 0x00,
+  0x00, 0xAD, 0x20, 0x5F, 0x50, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0078[ 72] = { /* code 0078, LATIN SMALL LETTER X */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x3D, 0x30, 0x3D, 0x30,
+  0x07, 0xC2, 0xC7, 0x00,
+  0x02, 0xDC, 0xC1, 0x00,
+  0x00, 0x5F, 0x50, 0x00,
+  0x02, 0xC8, 0xD2, 0x00,
+  0x0A, 0xA1, 0xCA, 0x00,
+  0x5D, 0x20, 0x3D, 0x30,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_0079[ 72] = { /* code 0079, LATIN SMALL LETTER Y */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0xAA, 0x00, 0x1C, 0x70,
+  0x5D, 0x20, 0x3D, 0x30,
+  0x2D, 0x50, 0x7A, 0x00,
+  0x07, 0xA1, 0xC5, 0x00,
+  0x03, 0xC5, 0xC2, 0x00,
+  0x01, 0xCF, 0xA0, 0x00,
+  0x00, 0x7F, 0x50, 0x00,
+  0x00, 0x5D, 0x20, 0x00,
+  0x00, 0xAA, 0x00, 0x00,
+  0x02, 0xD5, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_007A[ 54] = { /* code 007A, LATIN SMALL LETTER Z */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x3E, 0xFF, 0xE3,
+  0x00, 0x07, 0xC1,
+  0x00, 0x2C, 0x30,
+  0x00, 0xAA, 0x00,
+  0x05, 0xD2, 0x00,
+  0x2D, 0x50, 0x00,
+  0x5F, 0xFF, 0xF5,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_007B[ 54] = { /* code 007B, LEFT CURLY BRACKET */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0xAF, 0x50,
+  0x02, 0xC3, 0x00,
+  0x02, 0xB2, 0x00,
+  0x02, 0xB2, 0x00,
+  0x05, 0xC1, 0x00,
+  0x5C, 0x10, 0x00,
+  0x05, 0xC1, 0x00,
+  0x02, 0xB2, 0x00,
+  0x02, 0xB2, 0x00,
+  0x02, 0xB2, 0x00,
+  0x02, 0xC3, 0x00,
+  0x00, 0xAE, 0x30,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_007C[ 72] = { /* code 007C, VERTICAL LINE */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x3C, 0x20, 0x00,
+  0x00, 0x3C, 0x20, 0x00,
+  0x00, 0x3C, 0x20, 0x00,
+  0x00, 0x3C, 0x20, 0x00,
+  0x00, 0x3C, 0x20, 0x00,
+  0x00, 0x3C, 0x20, 0x00,
+  0x00, 0x3C, 0x20, 0x00,
+  0x00, 0x3C, 0x20, 0x00,
+  0x00, 0x3C, 0x20, 0x00,
+  0x00, 0x3C, 0x20, 0x00,
+  0x00, 0x3C, 0x20, 0x00,
+  0x00, 0x3C, 0x20, 0x00,
+  0x00, 0x3C, 0x20, 0x00,
+  0x00, 0x3C, 0x20, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_007D[ 54] = { /* code 007D, RIGHT CURLY BRACKET */
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00,
+  0x3E, 0xC1, 0x00,
+  0x02, 0xC3, 0x00,
+  0x02, 0xC3, 0x00,
+  0x02, 0xC3, 0x00,
+  0x01, 0xC5, 0x00,
+  0x00, 0x0A, 0x70,
+  0x00, 0xA7, 0x00,
+  0x01, 0xA3, 0x00,
+  0x02, 0xC3, 0x00,
+  0x02, 0xC3, 0x00,
+  0x02, 0xC3, 0x00,
+  0x3E, 0xC1, 0x00,
+  0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00
+};
+
+const uint8_t FontCalibri18_AA4_007E[ 72] = { /* code 007E, TILDE */
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x2D, 0xF5, 0x05, 0xA0,
+  0x77, 0x2B, 0x27, 0x70,
+  0xA5, 0x05, 0xFD, 0x20,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+
+const aafontsCharInfo_t charTable_Calibri18_AA4[95] = 
+{
+  {   3,   2, FontCalibri18_AA4_0020 }, /* code 0020 */
+  {   5,   3, FontCalibri18_AA4_0021 }, /* code 0021 */
+  {   6,   3, FontCalibri18_AA4_0022 }, /* code 0022 */
+  {   7,   4, FontCalibri18_AA4_0023 }, /* code 0023 */
+  {   7,   4, FontCalibri18_AA4_0024 }, /* code 0024 */
+  {  11,   6, FontCalibri18_AA4_0025 }, /* code 0025 */
+  {  10,   5, FontCalibri18_AA4_0026 }, /* code 0026 */
+  {   3,   2, FontCalibri18_AA4_0027 }, /* code 0027 */
+  {   5,   3, FontCalibri18_AA4_0028 }, /* code 0028 */
+  {   5,   3, FontCalibri18_AA4_0029 }, /* code 0029 */
+  {   7,   4, FontCalibri18_AA4_002A }, /* code 002A */
+  {   7,   4, FontCalibri18_AA4_002B }, /* code 002B */
+  {   4,   2, FontCalibri18_AA4_002C }, /* code 002C */
+  {   5,   3, FontCalibri18_AA4_002D }, /* code 002D */
+  {   4,   2, FontCalibri18_AA4_002E }, /* code 002E */
+  {   6,   3, FontCalibri18_AA4_002F }, /* code 002F */
+  {   7,   4, FontCalibri18_AA4_0030 }, /* code 0030 */
+  {   7,   4, FontCalibri18_AA4_0031 }, /* code 0031 */
+  {   7,   4, FontCalibri18_AA4_0032 }, /* code 0032 */
+  {   7,   4, FontCalibri18_AA4_0033 }, /* code 0033 */
+  {   7,   4, FontCalibri18_AA4_0034 }, /* code 0034 */
+  {   7,   4, FontCalibri18_AA4_0035 }, /* code 0035 */
+  {   7,   4, FontCalibri18_AA4_0036 }, /* code 0036 */
+  {   7,   4, FontCalibri18_AA4_0037 }, /* code 0037 */
+  {   7,   4, FontCalibri18_AA4_0038 }, /* code 0038 */
+  {   7,   4, FontCalibri18_AA4_0039 }, /* code 0039 */
+  {   4,   2, FontCalibri18_AA4_003A }, /* code 003A */
+  {   4,   2, FontCalibri18_AA4_003B }, /* code 003B */
+  {   7,   4, FontCalibri18_AA4_003C }, /* code 003C */
+  {   7,   4, FontCalibri18_AA4_003D }, /* code 003D */
+  {   7,   4, FontCalibri18_AA4_003E }, /* code 003E */
+  {   7,   4, FontCalibri18_AA4_003F }, /* code 003F */
+  {  13,   7, FontCalibri18_AA4_0040 }, /* code 0040 */
+  {   9,   5, FontCalibri18_AA4_0041 }, /* code 0041 */
+  {   8,   4, FontCalibri18_AA4_0042 }, /* code 0042 */
+  {   8,   4, FontCalibri18_AA4_0043 }, /* code 0043 */
+  {   9,   5, FontCalibri18_AA4_0044 }, /* code 0044 */
+  {   7,   4, FontCalibri18_AA4_0045 }, /* code 0045 */
+  {   7,   4, FontCalibri18_AA4_0046 }, /* code 0046 */
+  {   9,   5, FontCalibri18_AA4_0047 }, /* code 0047 */
+  {   9,   5, FontCalibri18_AA4_0048 }, /* code 0048 */
+  {   4,   2, FontCalibri18_AA4_0049 }, /* code 0049 */
+  {   5,   3, FontCalibri18_AA4_004A }, /* code 004A */
+  {   8,   4, FontCalibri18_AA4_004B }, /* code 004B */
+  {   6,   3, FontCalibri18_AA4_004C }, /* code 004C */
+  {  12,   6, FontCalibri18_AA4_004D }, /* code 004D */
+  {  10,   5, FontCalibri18_AA4_004E }, /* code 004E */
+  {  10,   5, FontCalibri18_AA4_004F }, /* code 004F */
+  {   8,   4, FontCalibri18_AA4_0050 }, /* code 0050 */
+  {  10,   5, FontCalibri18_AA4_0051 }, /* code 0051 */
+  {   8,   4, FontCalibri18_AA4_0052 }, /* code 0052 */
+  {   7,   4, FontCalibri18_AA4_0053 }, /* code 0053 */
+  {   7,   4, FontCalibri18_AA4_0054 }, /* code 0054 */
+  {   9,   5, FontCalibri18_AA4_0055 }, /* code 0055 */
+  {   9,   5, FontCalibri18_AA4_0056 }, /* code 0056 */
+  {  13,   7, FontCalibri18_AA4_0057 }, /* code 0057 */
+  {   8,   4, FontCalibri18_AA4_0058 }, /* code 0058 */
+  {   7,   4, FontCalibri18_AA4_0059 }, /* code 0059 */
+  {   7,   4, FontCalibri18_AA4_005A }, /* code 005A */
+  {   5,   3, FontCalibri18_AA4_005B }, /* code 005B */
+  {   6,   3, FontCalibri18_AA4_005C }, /* code 005C */
+  {   5,   3, FontCalibri18_AA4_005D }, /* code 005D */
+  {   7,   4, FontCalibri18_AA4_005E }, /* code 005E */
+  {   7,   4, FontCalibri18_AA4_005F }, /* code 005F */
+  {   4,   2, FontCalibri18_AA4_0060 }, /* code 0060 */
+  {   7,   4, FontCalibri18_AA4_0061 }, /* code 0061 */
+  {   8,   4, FontCalibri18_AA4_0062 }, /* code 0062 */
+  {   6,   3, FontCalibri18_AA4_0063 }, /* code 0063 */
+  {   8,   4, FontCalibri18_AA4_0064 }, /* code 0064 */
+  {   8,   4, FontCalibri18_AA4_0065 }, /* code 0065 */
+  {   5,   3, FontCalibri18_AA4_0066 }, /* code 0066 */
+  {   7,   4, FontCalibri18_AA4_0067 }, /* code 0067 */
+  {   8,   4, FontCalibri18_AA4_0068 }, /* code 0068 */
+  {   4,   2, FontCalibri18_AA4_0069 }, /* code 0069 */
+  {   4,   2, FontCalibri18_AA4_006A }, /* code 006A */
+  {   7,   4, FontCalibri18_AA4_006B }, /* code 006B */
+  {   4,   2, FontCalibri18_AA4_006C }, /* code 006C */
+  {  12,   6, FontCalibri18_AA4_006D }, /* code 006D */
+  {   8,   4, FontCalibri18_AA4_006E }, /* code 006E */
+  {   8,   4, FontCalibri18_AA4_006F }, /* code 006F */
+  {   8,   4, FontCalibri18_AA4_0070 }, /* code 0070 */
+  {   8,   4, FontCalibri18_AA4_0071 }, /* code 0071 */
+  {   5,   3, FontCalibri18_AA4_0072 }, /* code 0072 */
+  {   6,   3, FontCalibri18_AA4_0073 }, /* code 0073 */
+  {   5,   3, FontCalibri18_AA4_0074 }, /* code 0074 */
+  {   8,   4, FontCalibri18_AA4_0075 }, /* code 0075 */
+  {   7,   4, FontCalibri18_AA4_0076 }, /* code 0076 */
+  {  11,   6, FontCalibri18_AA4_0077 }, /* code 0077 */
+  {   7,   4, FontCalibri18_AA4_0078 }, /* code 0078 */
+  {   7,   4, FontCalibri18_AA4_0079 }, /* code 0079 */
+  {   6,   3, FontCalibri18_AA4_007A }, /* code 007A */
+  {   5,   3, FontCalibri18_AA4_007B }, /* code 007B */
+  {   7,   4, FontCalibri18_AA4_007C }, /* code 007C */
+  {   5,   3, FontCalibri18_AA4_007D }, /* code 007D */
+  {   7,   4, FontCalibri18_AA4_007E }  /* code 007E */
+};
+
+aafontsFont_t FontCalibri18_AA4 = 
+{
+  AAFONTS_FONTTYPE_AA4,                 /* Font type (anti-aliasing level) */
+  18,                                   /* Font height in pixels */
+  3,                                    /* Width to insert for unknown characters */
+  9,                                    /* Height of upper-case characters */
+  7,                                    /* Height of lower-case characters */
+  14,                                   /* Font baseline */
+  0x0020,                               /* Unicode address of first character */
+  0x007E,                               /* Unicode address of last character */
+  &charTable_Calibri18_AA4[0]           /* Font char data */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa4/FontCalibri18_AA4.h b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa4/FontCalibri18_AA4.h
new file mode 100644
index 0000000000000000000000000000000000000000..10ab2ed803aee7ea4ab3d81ffd95a3a495b31f35
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa4/FontCalibri18_AA4.h
@@ -0,0 +1,52 @@
+/**************************************************************************/
+/*! 
+    @file     FontCalibri18_AA4.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __FONTCALIBRI18_AA4_H__
+#define __FONTCALIBRI18_AA4_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "drivers/displays/graphic/aafonts.h"
+
+extern aafontsFont_t FontCalibri18_AA4;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa4/source.zip b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa4/source.zip
new file mode 100644
index 0000000000000000000000000000000000000000..992870647874b8d8560420f8da1f784048424ddb
Binary files /dev/null and b/reform2-lpc-fw/src/drivers/displays/graphic/aafonts/aa4/source.zip differ
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/colors.c b/reform2-lpc-fw/src/drivers/displays/graphic/colors.c
new file mode 100644
index 0000000000000000000000000000000000000000..5ba60aa3af9acd4e959eab23718f7257772b0371
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/colors.c
@@ -0,0 +1,270 @@
+/**************************************************************************/
+/*! 
+    @file     colors.c
+    @author   K. Townsend (microBuilder.eu)
+    
+    Various helper functions to work with RGB565 colors, including 
+    color conversion, color blending, and a basic set of predefined
+    color constants (see colors.h).
+	
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, Kevin Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <string.h>
+
+#include "colors.h"
+
+/**************************************************************************/
+/*                                                                        */
+/* ----------------------- Private Methods ------------------------------ */
+/*                                                                        */
+/**************************************************************************/
+
+/**************************************************************************/
+/*                                                                        */
+/* ----------------------- Public Methods ------------------------------- */
+/*                                                                        */
+/**************************************************************************/
+
+/**************************************************************************/
+/*!
+    @brief  Converts a 24-bit RGB color to an equivalent 16-bit RGB565 value
+
+    @param[in]  r
+                8-bit red
+    @param[in]  g
+                8-bit green
+    @param[in]  b
+                8-bit blue
+
+    @section Example
+
+    @code 
+
+    // Get 16-bit equivalent of 24-bit color
+    uint16_t gray = colorsRGB24toRGB565(0x33, 0x33, 0x33);
+
+    @endcode
+*/
+/**************************************************************************/
+uint16_t colorsRGB24toRGB565(uint8_t r, uint8_t g, uint8_t b)
+{
+  return ((r / 8) << 11) | ((g / 4) << 5) | (b / 8);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Converts a 16-bit RGB565 color to a standard 32-bit BGRA32
+            color (with alpha set to 0xFF)
+
+    @param[in]  color
+                16-bit rgb565 color
+
+    @section Example
+
+    @code 
+
+    // First convert 24-bit color to RGB565
+    uint16_t rgb565 = colorsRGB24toRGB565(0xFF, 0x00, 0x00);
+  
+    // Convert RGB565 color back to BGRA32
+    uint32_t bgra32 = colorsRGB565toBGRA32(rgb565);
+  
+    // Display results
+    printf("BGRA32: 0x%08X R: %u G: %u B: %u A: %u \r\n", 
+        bgra32, 
+        (bgra32 & 0x000000FF),        // Blue
+        (bgra32 & 0x0000FF00) >> 8,   // Green
+        (bgra32 & 0x00FF0000) >> 16,  // Red
+        (bgra32 & 0xFF000000) >> 24); // Alpha
+
+    @endcode
+*/
+/**************************************************************************/
+uint32_t colorsRGB565toBGRA32(uint16_t color)
+{
+  uint32_t bits = (uint32_t)color;
+  uint32_t blue = bits & 0x001F;     // 5 bits blue
+  uint32_t green = bits & 0x07E0;    // 6 bits green
+  uint32_t red = bits & 0xF800;      // 5 bits red
+
+  // Return shifted bits with alpha set to 0xFF
+  return (red << 8) | (green << 5) | (blue << 3) | 0xFF000000;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Reverses a 16-bit color from BGR to RGB or vice verse
+*/
+/**************************************************************************/
+uint16_t colorsBGR2RGB(uint16_t color)
+{   
+  uint16_t r, g, b;   
+   
+  b = (color>>0)  & 0x1f;   
+  g = (color>>5)  & 0x3f;   
+  r = (color>>11) & 0x1f;   
+     
+  return( (b<<11) + (g<<5) + (r<<0) );
+}
+
+/**************************************************************************/
+/*!
+    @brief  Adjusts the supplied color to have the specified intensity 
+            (0..100).  100 will leave the color as is at full intensity,
+            50 will reduce the color intensity by half, and 0 will return
+            black.
+
+            This function is useful for anti-aliasing and sub-pixel
+            rendering since colors are returned as a percentage of
+            the original value, depending on the amount of space they
+            take up in the sub-pixel array.
+
+    @param[in]  color
+                Base color (rgb565)
+    @param[in]  intensity
+                Color intensity relative to the source (0..100)
+
+    @section Example
+
+    @code
+
+    #include "drivers/displays/graphic/drawing.h"
+    #include "drivers/displays/graphic/colors.h"
+
+    uint16_t newColor;
+
+    // Draw a pure red rectangle
+    drawRectangleFilled(10, 10, 200, 100, COLOR_RED);
+
+    // Draw a rectangle at 50% intensity red
+    newColor = colorsDim(COLOR_RED, 50);
+    drawRectangleFilled(20, 20, 190, 90, newColor);
+
+    // Draw a rectangle at 25% intensity red
+    newColor = colorsDim(COLOR_RED, 25);
+    drawRectangleFilled(30, 30, 180, 80, newColor);
+
+    // Draw a rectangle at 0% intensity red
+    newColor = colorsDim(COLOR_RED, 0);
+    drawRectangleFilled(40, 40, 170, 70, newColor);
+
+    @endcode
+*/
+/**************************************************************************/
+uint16_t colorsDim(uint16_t color, uint8_t intensity)
+{
+  uint16_t r, g, b;               // Individual component colors
+
+  // Add intensity adjusted forecolor
+  r = ((((color >> 11) & 0x1F) * intensity) / 100) & 0x1F;
+  g = ((((color >> 5) & 0x3F) * intensity) / 100) & 0x3F;
+  b = (((color & 0x1F)  * intensity) / 100) & 0x1F;
+
+  return (r << 11) | (g << 6) | b;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Returns an alpha-blended color based on the supplied bg color,
+            fore color, and intensity value (0..100).
+
+            This function is used when alpha-blending anti-aliased fonts
+            with an existing background image, amongst other things, and
+            can be used to create images that appear to be 'faded' or
+            semi-transparent, though at the expense of slow updates since
+            reading pixels from most LCD controllers is an extremely
+            expensive operation.
+
+    @param[in]  bgColor
+                Background color (rgb565)
+    @param[in]  foreColor
+                Forground color (rgb565)
+    @param[in]  fadePercent
+                Visibility of the background color in percent (0..100).
+                The higher the number, the more visible the back color
+                becomes.  100% signifies that the back color is entirely
+                visible (only the BG color is shown), 0% signifies
+                that only the fore color is shown, and 25% would
+                indicate that the background is visible at approximately
+                25% intensity (combined with 75% of the fore color).
+
+    @section Example
+
+    @code
+
+    #include "drivers/displays/graphic/drawing.h"
+    #include "drivers/displays/graphic/colors.h"
+
+    uint16_t bg = COLOR_GREEN;
+    uint16_t fore = COLOR_WHITE;
+
+    // Calculate the intermediate color with 25% bg blending
+    uint16_t result = colorsAlphaBlend(bg, fore, 25);
+
+    drawRectangleFilled(10, 10, 50, 50, bg);
+    drawRectangleFilled(60, 10, 100, 50, fore);
+    drawRectangleFilled(35, 60, 75, 100, result);
+
+    @endcode
+*/
+/**************************************************************************/
+uint16_t colorsAlphaBlend(uint16_t bgColor, uint16_t foreColor, uint8_t fadePercent)
+{
+  uint16_t br, bg, bb;              // Background component colors
+  uint16_t fr, fg, fb;              // Foreground component colors
+  uint16_t newr, newg, newb;        // Blended component colors
+
+  if (fadePercent > 100)
+  {
+    fadePercent = 100;
+  }
+
+  // Short cut if the color is full intensity
+  if (fadePercent == 100)
+    return bgColor;
+
+  // Note: This algorithm can definately be optimised!
+
+  // Break out component colors
+  br = ((bgColor >> 11) & 0x1F);
+  fr = ((foreColor >> 11) & 0x1F);
+  bg = ((bgColor >> 5) & 0x3F);
+  fg = ((foreColor >> 5) & 0x3F);
+  bb = (bgColor & 0x1F);
+  fb = (foreColor & 0x1F);
+
+  // Z = intensity * bgcolor + (100 - intensity) * forecolor
+  newr = (fadePercent * br + (100 - fadePercent) * fr) / 100;
+  newg = (fadePercent * bg + (100 - fadePercent) * fg) / 200;   // Need to use 5-bit green for accurate colors :(
+  newb = (fadePercent * bb + (100 - fadePercent) * fb) / 100;
+
+  return (newr << 11) | (newg << 6) | newb;
+}
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/colors.h b/reform2-lpc-fw/src/drivers/displays/graphic/colors.h
new file mode 100644
index 0000000000000000000000000000000000000000..52fd239b5f5bfa64b23e4ca167a328fd277c84c7
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/colors.h
@@ -0,0 +1,76 @@
+/**************************************************************************/
+/*! 
+    @file     colors.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Common 16-bit RGB565 color definitions
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __COLORS_H__
+#define __COLORS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+// Basic Color definitions
+#define	COLOR_BLACK                         (uint16_t)(0x0000)
+#define	COLOR_BLUE                          (uint16_t)(0x001F)
+#define	COLOR_RED                           (uint16_t)(0xF800)
+#define	COLOR_GREEN                         (uint16_t)(0x07E0)
+#define COLOR_CYAN                          (uint16_t)(0x07FF)
+#define COLOR_MAGENTA                       (uint16_t)(0xF81F)
+#define COLOR_YELLOW                        (uint16_t)(0xFFE0)
+#define COLOR_WHITE                         (uint16_t)(0xFFFF)
+
+// Grayscale Values
+#define COLOR_GRAY_15                       (uint16_t)(0x0861)    //  15  15  15
+#define COLOR_GRAY_30                       (uint16_t)(0x18E3)    //  30  30  30
+#define COLOR_GRAY_50                       (uint16_t)(0x3186)    //  50  50  50
+#define COLOR_GRAY_80                       (uint16_t)(0x528A)    //  80  80  80
+#define COLOR_GRAY_128                      (uint16_t)(0x8410)    // 128 128 128
+#define COLOR_GRAY_200                      (uint16_t)(0xCE59)    // 200 200 200
+#define COLOR_GRAY_225                      (uint16_t)(0xE71C)    // 225 225 225
+
+uint16_t colorsRGB24toRGB565  ( uint8_t r, uint8_t g, uint8_t b );
+uint32_t colorsRGB565toBGRA32 ( uint16_t color );
+uint16_t colorsBGR2RGB        ( uint16_t color );
+uint16_t colorsDim            ( uint16_t color, uint8_t intensity );
+uint16_t colorsAlphaBlend     ( uint16_t bgColor, uint16_t foreColor, uint8_t fadePercent );
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/drawing.c b/reform2-lpc-fw/src/drivers/displays/graphic/drawing.c
new file mode 100644
index 0000000000000000000000000000000000000000..a1bea50f59e7ee1e9d093c7427e9eefcc2ca2b1c
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/drawing.c
@@ -0,0 +1,1219 @@
+/**************************************************************************/
+/*!
+    @file     drawing.c
+    @author   K. Townsend (microBuilder.eu)
+
+    drawLine and drawCircle adapted from a tutorial by Leonard McMillan:
+    http://www.cs.unc.edu/~mcmillan/
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <string.h>
+
+#include "drawing.h"
+
+/**************************************************************************/
+/*                                                                        */
+/* ----------------------- Private Methods ------------------------------ */
+/*                                                                        */
+/**************************************************************************/
+
+/**************************************************************************/
+/*!
+    @brief  Swaps values a and b
+*/
+/**************************************************************************/
+void drawSwap(uint32_t a, uint32_t b)
+{
+  uint32_t t;
+  t = a;
+  a = b;
+  b = t;
+}
+
+#if defined CFG_TFTLCD_INCLUDESMALLFONTS & CFG_TFTLCD_INCLUDESMALLFONTS == 1
+/**************************************************************************/
+/*!
+    @brief  Draws a single smallfont character
+*/
+/**************************************************************************/
+void drawCharSmall(uint16_t x, uint16_t y, uint16_t color, uint8_t c, struct FONT_DEF font)
+{
+  uint8_t col, column[font.u8Width];
+
+  // Check if the requested character is available
+  if ((c >= font.u8FirstChar) && (c <= font.u8LastChar))
+  {
+    // Retrieve appropriate columns from font data
+    for (col = 0; col < font.u8Width; col++)
+    {
+      column[col] = font.au8FontTable[((c - 32) * font.u8Width) + col];    // Get first column of appropriate character
+    }
+  }
+  else
+  {
+    // Requested character is not available in this font ... send a space instead
+    for (col = 0; col < font.u8Width; col++)
+    {
+      column[col] = 0xFF;    // Send solid space
+    }
+  }
+
+  // Render each column
+  uint16_t xoffset, yoffset;
+  for (xoffset = 0; xoffset < font.u8Width; xoffset++)
+  {
+    for (yoffset = 0; yoffset < (font.u8Height + 1); yoffset++)
+    {
+      uint8_t bit = 0x00;
+      bit = (column[xoffset] << (8 - (yoffset + 1)));     // Shift current row bit left
+      bit = (bit >> 7);                                   // Shift current row bit right (results in 0x01 for black, and 0x00 for white)
+      if (bit)
+      {
+        drawPixel(x + xoffset, y + yoffset, color);
+      }
+    }
+  }
+}
+#endif
+
+/**************************************************************************/
+/*                                                                        */
+/* ----------------------- Public Methods ------------------------------- */
+/*                                                                        */
+/**************************************************************************/
+
+/**************************************************************************/
+/*!
+    @brief  Draws a single pixel at the specified location
+
+    @param[in]  x
+                Horizontal position
+    @param[in]  y
+                Vertical position
+    @param[in]  color
+                Color used when drawing
+*/
+/**************************************************************************/
+void drawPixel(uint16_t x, uint16_t y, uint16_t color)
+{
+  if ((x < lcdGetWidth()) && (y < lcdGetHeight()))
+  {
+    lcdDrawPixel(x, y, color);
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Fills the screen with the specified color
+
+    @param[in]  color
+                Color used when drawing
+*/
+/**************************************************************************/
+void drawFill(uint16_t color)
+{
+  lcdFillRGB(color);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws a simple color test pattern
+*/
+/**************************************************************************/
+void drawTestPattern(void)
+{
+  lcdTest();
+}
+
+#if defined CFG_TFTLCD_INCLUDESMALLFONTS & CFG_TFTLCD_INCLUDESMALLFONTS == 1
+/**************************************************************************/
+/*!
+    @brief  Draws a string using a small font (6 of 8 pixels high).
+
+    @param[in]  x
+                Starting x co-ordinate
+    @param[in]  y
+                Starting y co-ordinate
+    @param[in]  color
+                Color to use when rendering the font
+    @param[in]  text
+                The string to render
+    @param[in]  font
+                Pointer to the FONT_DEF to use when drawing the string
+
+    @section Example
+
+    @code
+
+    #include "drivers/displays/smallfonts.h"
+
+    drawStringSmall(1, 210, COLOR_WHITE, "5x8 System (Max 40 Characters)", Font_System5x8);
+    drawStringSmall(1, 220, COLOR_WHITE, "7x8 System (Max 30 Characters)", Font_System7x8);
+
+    @endcode
+*/
+/**************************************************************************/
+void drawStringSmall(uint16_t x, uint16_t y, uint16_t color, char* text, struct FONT_DEF font)
+{
+  uint8_t l;
+  for (l = 0; l < strlen(text); l++)
+  {
+    drawCharSmall(x + (l * (font.u8Width + 1)), y, color, text[l], font);
+  }
+}
+#endif
+
+/**************************************************************************/
+/*!
+    @brief  Draws a bresenham line
+
+    @param[in]  x0
+                Starting x co-ordinate
+    @param[in]  y0
+                Starting y co-ordinate
+    @param[in]  x1
+                Ending x co-ordinate
+    @param[in]  y1
+                Ending y co-ordinate
+    @param[in]  color
+                Color used when drawing
+*/
+/**************************************************************************/
+void drawLine ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color )
+{
+  drawLineDotted(x0, y0, x1, y1, 0, 1, color);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws a bresenham line with a fixed pattern of empty
+            and solid pixels
+
+    Based on: http://www.cs.unc.edu/~mcmillan/comp136/Lecture6/Lines.html
+
+    @param[in]  x0
+                Starting x co-ordinate
+    @param[in]  y0
+                Starting y co-ordinate
+    @param[in]  x1
+                Ending x co-ordinate
+    @param[in]  y1
+                Ending y co-ordinate
+    @param[in]  empty
+                The number of 'empty' pixels to render
+    @param[in]  solid
+                The number of 'solid' pixels to render
+    @param[in]  color
+                Color used when drawing
+*/
+/**************************************************************************/
+void drawLineDotted ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t empty, uint16_t solid, uint16_t color )
+{
+  lcdProperties_t properties;
+
+  // Get the LCD properties (to check for HW acceleration in the driver)
+  properties = lcdGetProperties();
+
+  if (solid == 0)
+  {
+    return;
+  }
+
+  // If a negative y int was passed in it will overflow to 65K something
+  // Ugly, but drawCircleFilled() can pass in negative values so we need
+  // to check the values here
+  y0 = y0 > 65000 ? 0 : y0;
+  y1 = y1 > 65000 ? 0 : y1;
+
+  // Check if we can use the optimised horizontal line method
+  if ((y0 == y1) && (empty == 0) && properties.fastHLine)
+  {
+    lcdDrawHLine(x0, x1, y0, color);
+    return;
+  }
+
+  // Check if we can use the optimised vertical line method.
+  // This can make a huge difference in performance, but may
+  // not work properly on every LCD controller:
+  if ((x0 == x1) && (empty == 0) && properties.fastVLine)
+  {
+    // Warning: This may actually be slower than drawing individual pixels on
+    // short lines ... Set a minimum line size to use the 'optimised' method
+    // (which changes the screen orientation) ?
+    lcdDrawVLine(x0, y0, y1, color);
+    return;
+  }
+
+  // Draw non-horizontal or dotted line
+  int dy = y1 - y0;
+  int dx = x1 - x0;
+  int stepx, stepy;
+  int emptycount, solidcount;
+
+  if (dy < 0) { dy = -dy;  stepy = -1; } else { stepy = 1; }
+  if (dx < 0) { dx = -dx;  stepx = -1; } else { stepx = 1; }
+  dy <<= 1;                               // dy is now 2*dy
+  dx <<= 1;                               // dx is now 2*dx
+
+  emptycount = empty;
+  solidcount = solid;
+
+  drawPixel(x0, y0, color);               // always start with solid pixels
+  solidcount--;
+  if (dx > dy)
+  {
+    int fraction = dy - (dx >> 1);        // same as 2*dy - dx
+    while (x0 != x1)
+    {
+      if (fraction >= 0)
+      {
+        y0 += stepy;
+        fraction -= dx;                   // same as fraction -= 2*dx
+      }
+      x0 += stepx;
+      fraction += dy;                     // same as fraction -= 2*dy
+      if (empty == 0)
+      {
+        // always draw a pixel ... no dotted line requested
+        drawPixel(x0, y0, color);
+      }
+      else if (solidcount)
+      {
+        // Draw solid pxiel and decrement counter
+        drawPixel(x0, y0, color);
+        solidcount--;
+      }
+      else if(emptycount)
+      {
+        // Empty pixel ... don't draw anything an decrement counter
+        emptycount--;
+      }
+      else
+      {
+        // Reset counters and draw solid pixel
+        emptycount = empty;
+        solidcount = solid;
+        drawPixel(x0, y0, color);
+        solidcount--;
+      }
+    }
+  }
+  else
+  {
+    int fraction = dx - (dy >> 1);
+    while (y0 != y1)
+    {
+      if (fraction >= 0)
+      {
+        x0 += stepx;
+        fraction -= dy;
+      }
+      y0 += stepy;
+      fraction += dx;
+      if (empty == 0)
+      {
+        // always draw a pixel ... no dotted line requested
+        drawPixel(x0, y0, color);
+      }
+      if (solidcount)
+      {
+        // Draw solid pxiel and decrement counter
+        drawPixel(x0, y0, color);
+        solidcount--;
+      }
+      else if(emptycount)
+      {
+        // Empty pixel ... don't draw anything an decrement counter
+        emptycount--;
+      }
+      else
+      {
+        // Reset counters and draw solid pixel
+        emptycount = empty;
+        solidcount = solid;
+        drawPixel(x0, y0, color);
+        solidcount--;
+      }
+    }
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws a circle
+
+    Based on: http://www.cs.unc.edu/~mcmillan/comp136/Lecture7/circle.html
+
+    @param[in]  xCenter
+                The horizontal center of the circle
+    @param[in]  yCenter
+                The vertical center of the circle
+    @param[in]  radius
+                The circle's radius in pixels
+    @param[in]  color
+                Color used when drawing
+*/
+/**************************************************************************/
+void drawCircle (uint16_t xCenter, uint16_t yCenter, uint16_t radius, uint16_t color)
+{
+  drawPixel(xCenter, yCenter+radius, color);
+  drawPixel(xCenter, yCenter-radius, color);
+  drawPixel(xCenter+radius, yCenter, color);
+  drawPixel(xCenter-radius, yCenter, color);
+  drawCorner(xCenter, yCenter, radius, DRAW_CORNERS_ALL, color);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws a filled circle
+
+    @param[in]  xCenter
+                The horizontal center of the circle
+    @param[in]  yCenter
+                The vertical center of the circle
+    @param[in]  radius
+                The circle's radius in pixels
+    @param[in]  color
+                Color used when drawing
+*/
+/**************************************************************************/
+void drawCircleFilled (uint16_t xCenter, uint16_t yCenter, uint16_t radius, uint16_t color)
+{
+  int16_t f = 1 - radius;
+  int16_t ddF_x = 1;
+  int16_t ddF_y = -2 * radius;
+  int16_t x = 0;
+  int16_t y = radius;
+  int16_t xc_px, yc_my, xc_mx, xc_py, yc_mx, xc_my;
+  int16_t lcdWidth = lcdGetWidth();
+
+  if (xCenter < lcdWidth) drawLine(xCenter, yCenter-radius < 0 ? 0 : yCenter-radius, xCenter, (yCenter-radius) + (2*radius), color);
+
+  while (x<y)
+  {
+    if (f >= 0)
+    {
+      y--;
+      ddF_y += 2;
+      f += ddF_y;
+    }
+    x++;
+    ddF_x += 2;
+    f += ddF_x;
+
+    xc_px = xCenter+x;
+    xc_mx = xCenter-x;
+    xc_py = xCenter+y;
+    xc_my = xCenter-y;
+    yc_mx = yCenter-x;
+    yc_my = yCenter-y;
+
+    // Make sure X positions are not negative or too large or the pixels will
+    // overflow.  Y overflow is handled in drawLine().
+    if ((xc_px < lcdWidth) && (xc_px >= 0)) drawLine(xc_px, yc_my, xc_px, yc_my + 2*y, color);
+    if ((xc_mx < lcdWidth) && (xc_mx >= 0)) drawLine(xc_mx, yc_my, xc_mx, yc_my + 2*y, color);
+    if ((xc_py < lcdWidth) && (xc_py >= 0)) drawLine(xc_py, yc_mx, xc_py, yc_mx + 2*x, color);
+    if ((xc_my < lcdWidth) && (xc_my >= 0)) drawLine(xc_my, yc_mx, xc_my, yc_mx + 2*x, color);
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws a single 1-pixel wide corner
+
+    @note   Code courtesy Adafruit's excellent GFX lib:
+            https://github.com/adafruit/Adafruit-GFX-Library
+
+    @param[in]  xCenter
+                The horizontal center of the circle
+    @param[in]  yCenter
+                The vertical center of the circle
+    @param[in]  r
+                The corner radius
+    @param[in]  corner
+                The drawCorners_t representing the corner(s) to draw
+    @param[in]  color
+                Color used when drawing
+
+    @section EXAMPLE
+
+    @code
+
+    // Draw a top-left corner with a 10 pixel radius, centered at 20, 20
+    drawCorner(20, 20, 10, DRAW_CORNER_TOPLEFT, COLOR_GRAY_128);
+
+    @endcode
+*/
+/**************************************************************************/
+void drawCorner (uint16_t xCenter, uint16_t yCenter, uint16_t r, drawCorners_t corner, uint16_t color)
+{
+  int16_t f     = 1 - r;
+  int16_t ddF_x = 1;
+  int16_t ddF_y = -2 * r;
+  int16_t x     = 0;
+  int16_t y     = r;
+
+  while (x<y)
+  {
+    if (f >= 0)
+    {
+      y--;
+      ddF_y += 2;
+      f     += ddF_y;
+    }
+    x++;
+    ddF_x += 2;
+    f     += ddF_x;
+    if (corner & DRAW_CORNERS_BOTTOMRIGHT)
+    {
+      drawPixel(xCenter + x, yCenter + y, color);
+      drawPixel(xCenter + y, yCenter + x, color);
+    }
+    if (corner & DRAW_CORNERS_TOPRIGHT)
+    {
+      drawPixel(xCenter + x, yCenter - y, color);
+      drawPixel(xCenter + y, yCenter - x, color);
+    }
+    if (corner & DRAW_CORNERS_BOTTOMLEFT)
+    {
+      drawPixel(xCenter - y, yCenter + x, color);
+      drawPixel(xCenter - x, yCenter + y, color);
+    }
+    if (corner & DRAW_CORNERS_TOPLEFT)
+    {
+      drawPixel(xCenter - y, yCenter - x, color);
+      drawPixel(xCenter - x, yCenter - y, color);
+    }
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws a filled rounded corner
+
+    @param[in]  xCenter
+                The horizontal center of the circle
+    @param[in]  yCenter
+                The vertical center of the circle
+    @param[in]  radius
+                The circle's radius in pixels
+    @param[in]  position
+                The position of the corner, which affects how it will
+                be rendered
+    @param[in]  color
+                Color used when drawing
+*/
+/**************************************************************************/
+void drawCornerFilled (uint16_t xCenter, uint16_t yCenter, uint16_t radius, drawCorners_t position, uint16_t color)
+{
+  int16_t f = 1 - radius;
+  int16_t ddF_x = 1;
+  int16_t ddF_y = -2 * radius;
+  int16_t x = 0;
+  int16_t y = radius;
+  int16_t xc_px, yc_my, xc_mx, xc_py, yc_mx, xc_my;
+  int16_t lcdWidth = lcdGetWidth();
+
+
+  if ((position & DRAW_CORNERS_TOPRIGHT) || (position & DRAW_CORNERS_TOPLEFT))
+  {
+    if (xCenter < lcdWidth) drawLine(xCenter, yCenter-radius < 0 ? 0 : yCenter-radius, xCenter, yCenter, color);
+  }
+  if ((position & DRAW_CORNERS_BOTTOMRIGHT) || (position & DRAW_CORNERS_BOTTOMLEFT))
+  {
+    if (xCenter < lcdWidth) drawLine(xCenter, yCenter-radius < 0 ? 0 : yCenter, xCenter, (yCenter-radius) + (2*radius), color);
+  }
+
+  while (x<y)
+  {
+    if (f >= 0)
+    {
+      y--;
+      ddF_y += 2;
+      f += ddF_y;
+    }
+    x++;
+    ddF_x += 2;
+    f += ddF_x;
+
+    xc_px = xCenter+x;
+    xc_mx = xCenter-x;
+    xc_py = xCenter+y;
+    xc_my = xCenter-y;
+    yc_mx = yCenter-x;
+    yc_my = yCenter-y;
+
+
+    if (position & DRAW_CORNERS_TOPRIGHT)
+    {
+        if ((xc_px < lcdWidth) && (xc_px >= 0)) drawLine(xc_px, yc_my, xc_px, yCenter, color);
+        if ((xc_py < lcdWidth) && (xc_py >= 0)) drawLine(xc_py, yc_mx, xc_py, yCenter, color);
+    }
+    if (position & DRAW_CORNERS_BOTTOMRIGHT)
+    {
+        if ((xc_px < lcdWidth) && (xc_px >= 0)) drawLine(xc_px, yCenter, xc_px, yc_my + 2*y, color);
+        if ((xc_py < lcdWidth) && (xc_py >= 0)) drawLine(xc_py, yCenter, xc_py, yc_mx + 2*x, color);
+    }
+    if (position & DRAW_CORNERS_TOPLEFT)
+    {
+        if ((xc_mx < lcdWidth) && (xc_mx >= 0)) drawLine(xc_mx, yc_my, xc_mx, yCenter, color);
+        if ((xc_my < lcdWidth) && (xc_my >= 0)) drawLine(xc_my, yc_mx, xc_my, yCenter, color);
+    }
+    if (position & DRAW_CORNERS_BOTTOMLEFT)
+    {
+        if ((xc_mx < lcdWidth) && (xc_mx >= 0)) drawLine(xc_mx, yCenter, xc_mx, yc_my + 2*y, color);
+        if ((xc_my < lcdWidth) && (xc_my >= 0)) drawLine(xc_my, yCenter, xc_my, yc_mx + 2*x, color);
+    }
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws a simple arrow of the specified width
+
+    @param[in]  x
+                X co-ordinate of the smallest point of the arrow
+    @param[in]  y
+                Y co-ordinate of the smallest point of the arrow
+    @param[in]  size
+                Total width/height of the arrow in pixels
+    @param[in]  direction
+                The direction that the arrow is pointing
+    @param[in]  color
+                Color used when drawing
+*/
+/**************************************************************************/
+void drawArrow(uint16_t x, uint16_t y, uint16_t size, drawDirection_t direction, uint16_t color)
+{
+  drawPixel(x, y, color);
+
+  if (size == 1)
+  {
+    return;
+  }
+
+  uint32_t i;
+  switch (direction)
+  {
+    case DRAW_DIRECTION_LEFT:
+      for (i = 1; i<size; i++)
+      {
+        drawLine(x+i, y-i, x+i, y+i, color);
+      }
+      break;
+    case DRAW_DIRECTION_RIGHT:
+      for (i = 1; i<size; i++)
+      {
+        drawLine(x-i, y-i, x-i, y+i, color);
+      }
+      break;
+    case DRAW_DIRECTION_UP:
+      for (i = 1; i<size; i++)
+      {
+        drawLine(x-i, y+i, x+i, y+i, color);
+      }
+      break;
+    case DRAW_DIRECTION_DOWN:
+      for (i = 1; i<size; i++)
+      {
+        drawLine(x-i, y-i, x+i, y-i, color);
+      }
+      break;
+    default:
+      break;
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws a simple (empty) rectangle
+
+    @param[in]  x0
+                Starting x co-ordinate
+    @param[in]  y0
+                Starting y co-ordinate
+    @param[in]  x1
+                Ending x co-ordinate
+    @param[in]  y1
+                Ending y co-ordinate
+    @param[in]  color
+                Color used when drawing
+*/
+/**************************************************************************/
+void drawRectangle ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color)
+{
+  uint16_t x, y;
+
+  if (y1 < y0)
+  {
+    // Switch y1 and y0
+    y = y1;
+    y1 = y0;
+    y0 = y;
+  }
+
+  if (x1 < x0)
+  {
+    // Switch x1 and x0
+    x = x1;
+    x1 = x0;
+    x0 = x;
+  }
+
+  drawLine (x0, y0, x1, y0, color);
+  drawLine (x1, y0, x1, y1, color);
+  drawLine (x1, y1, x0, y1, color);
+  drawLine (x0, y1, x0, y0, color);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws a filled rectangle
+
+    @param[in]  x0
+                Starting x co-ordinate
+    @param[in]  y0
+                Starting y co-ordinate
+    @param[in]  x1
+                Ending x co-ordinate
+    @param[in]  y1
+                Ending y co-ordinate
+    @param[in]  color
+                Color used when drawing
+*/
+/**************************************************************************/
+void drawRectangleFilled ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color)
+{
+  int height;
+  uint16_t x, y;
+
+  if (y1 < y0)
+  {
+    // Switch y1 and y0
+    y = y1;
+    y1 = y0;
+    y0 = y;
+  }
+
+  if (x1 < x0)
+  {
+    // Switch x1 and x0
+    x = x1;
+    x1 = x0;
+    x0 = x;
+  }
+
+  height = y1 - y0;
+  for (height = y0; y1 > height - 1; ++height)
+  {
+    drawLine(x0, height, x1, height, color);
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws a rectangle with rounded corners
+
+    @param[in]  x0
+                Starting x co-ordinate
+    @param[in]  y0
+                Starting y co-ordinate
+    @param[in]  x1
+                Ending x co-ordinate
+    @param[in]  y1
+                Ending y co-ordinate
+    @param[in]  color
+                Color used when drawing
+    @param[in]  radius
+                Corner radius in pixels
+    @param[in]  corners
+                Which corners to round
+
+    @section    EXAMPLE
+    @code
+
+    drawRoundedRectangle ( 10, 10, 200, 200, COLOR_BLACK, 10, DRAW_CORNERS_ALL );
+
+    @endcode
+
+*/
+/**************************************************************************/
+void drawRoundedRectangle ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color, uint16_t radius, drawCorners_t corners )
+{
+  int height;
+  uint16_t y;
+
+  if (corners == DRAW_CORNERS_NONE)
+  {
+    drawRectangle(x0, y0, x1, y1, color);
+    return;
+  }
+
+  // Calculate height
+  if (y1 < y0)
+  {
+    y = y1;
+    y1 = y0;
+    y0 = y;
+  }
+  height = y1 - y0;
+
+  // Check radius
+  if (radius > height / 2)
+  {
+    radius = height / 2;
+  }
+  radius -= 1;
+
+  switch (corners)
+  {
+    case DRAW_CORNERS_ALL:
+      drawCorner(x0 + radius, y0 + radius, radius, DRAW_CORNERS_TOPLEFT, color);
+      drawCorner(x1 - radius, y0 + radius, radius, DRAW_CORNERS_TOPRIGHT, color);
+      drawCorner(x0 + radius, y1 - radius, radius, DRAW_CORNERS_BOTTOMLEFT, color);
+      drawCorner(x1 - radius, y1 - radius, radius, DRAW_CORNERS_BOTTOMRIGHT, color);
+      if (radius*2+1 < height)
+      {
+        drawLine(x0, y0+radius, x0, y1-radius, color);
+        drawLine(x1, y0+radius, x1, y1-radius, color);
+      }
+      drawLine(x0+radius, y0, x1-radius, y0, color);
+      drawLine(x0+radius, y1, x1-radius, y1, color);
+      break;
+    case DRAW_CORNERS_TOP:
+      drawCorner(x0 + radius, y0 + radius, radius, DRAW_CORNERS_TOPLEFT, color);
+      drawCorner(x1 - radius, y0 + radius, radius, DRAW_CORNERS_TOPRIGHT, color);
+      drawLine(x0, y0+radius, x0, y1, color);
+      drawLine(x0, y1, x1, y1, color);
+      drawLine(x1, y1, x1, y0+radius, color);
+      drawLine(x0+radius, y0, x1-radius, y0, color);
+      break;
+    case DRAW_CORNERS_BOTTOM:
+      drawCorner(x0 + radius, y1 - radius, radius, DRAW_CORNERS_BOTTOMLEFT, color);
+      drawCorner(x1 - radius, y1 - radius, radius, DRAW_CORNERS_BOTTOMRIGHT, color);
+      drawLine(x0, y0, x1, y0, color);
+      drawLine(x1, y0, x1, y1-radius, color );
+      drawLine(x1-radius, y1, x0+radius, y1, color);
+      drawLine(x0, y1-radius, x0, y0, color);
+      break;
+    case DRAW_CORNERS_LEFT:
+      drawCorner(x0 + radius, y0 + radius, radius, DRAW_CORNERS_TOPLEFT, color);
+      drawCorner(x0 + radius, y1 - radius, radius, DRAW_CORNERS_BOTTOMLEFT, color);
+      if (radius*2+1 < height)
+      {
+        drawLine(x0, y0+radius, x0, y1-radius, color);
+      }
+      drawLine(x1, y0, x1, y1, color);
+      drawLine(x0+radius, y0, x1, y0, color);
+      drawLine(x0+radius, y1, x1, y1, color);
+      break;
+    case DRAW_CORNERS_RIGHT:
+      drawCorner(x1 - radius, y0 + radius, radius, DRAW_CORNERS_TOPRIGHT, color);
+      drawCorner(x1 - radius, y1 - radius, radius, DRAW_CORNERS_BOTTOMRIGHT, color);
+      if (radius*2+1 < height)
+      {
+        drawLine(x1, y0+radius, x1, y1-radius, color);
+      }
+      drawLine(x0, y0, x0, y1, color);
+      drawLine(x0, y0, x1-radius, y0, color);
+      drawLine(x0, y1, x1-radius, y1, color);
+      break;
+    default:
+      break;
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws a filled rectangle with rounded corners
+
+    @param[in]  x0
+                Starting x co-ordinate
+    @param[in]  y0
+                Starting y co-ordinate
+    @param[in]  x1
+                Ending x co-ordinate
+    @param[in]  y1
+                Ending y co-ordinate
+    @param[in]  color
+                Color used when drawing
+    @param[in]  radius
+                Corner radius in pixels
+    @param[in]  corners
+                Which corners to round
+*/
+/**************************************************************************/
+void drawRoundedRectangleFilled ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color, uint16_t radius, drawCorners_t corners )
+{
+  int height;
+  uint16_t y;
+
+  if (corners == DRAW_CORNERS_NONE)
+  {
+    drawRectangleFilled(x0, y0, x1, y1, color);
+    return;
+  }
+
+  // Calculate height
+  if (y1 < y0)
+  {
+    y = y1;
+    y1 = y0;
+    y0 = y;
+  }
+  height = y1 - y0;
+
+  // Check radius
+  if (radius > height / 2)
+  {
+    radius = height / 2;
+  }
+  radius -= 1;
+
+  // Draw body
+  drawRectangleFilled(x0 + radius, y0, x1 - radius, y1, color);
+
+  switch (corners)
+  {
+    case DRAW_CORNERS_ALL:
+      drawCornerFilled(x0 + radius, y0 + radius, radius, DRAW_CORNERS_TOPLEFT, color);
+      drawCornerFilled(x1 - radius, y0 + radius, radius, DRAW_CORNERS_TOPRIGHT, color);
+      drawCornerFilled(x0 + radius, y1 - radius, radius, DRAW_CORNERS_BOTTOMLEFT, color);
+      drawCornerFilled(x1 - radius, y1 - radius, radius, DRAW_CORNERS_BOTTOMRIGHT, color);
+      if (radius*2+1 < height)
+      {
+        drawRectangleFilled(x0, y0 + radius, x0 + radius, y1 - radius, color);
+        drawRectangleFilled(x1 - radius, y0 + radius, x1, y1 - radius, color);
+      }
+      break;
+    case DRAW_CORNERS_TOP:
+      drawCornerFilled(x0 + radius, y0 + radius, radius, DRAW_CORNERS_TOPLEFT, color);
+      drawCornerFilled(x1 - radius, y0 + radius, radius, DRAW_CORNERS_TOPRIGHT, color);
+      drawRectangleFilled(x0, y0 + radius, x0 + radius, y1, color);
+      drawRectangleFilled(x1 - radius, y0 + radius, x1, y1, color);
+      break;
+    case DRAW_CORNERS_BOTTOM:
+      drawCornerFilled(x0 + radius, y1 - radius, radius, DRAW_CORNERS_BOTTOMLEFT, color);
+      drawCornerFilled(x1 - radius, y1 - radius, radius, DRAW_CORNERS_BOTTOMRIGHT, color);
+      drawRectangleFilled(x0, y0, x0 + radius, y1 - radius, color);
+      drawRectangleFilled(x1 - radius, y0, x1, y1 - radius, color);
+      break;
+    case DRAW_CORNERS_LEFT:
+      drawCornerFilled(x0 + radius, y0 + radius, radius, DRAW_CORNERS_TOPLEFT, color);
+      drawCornerFilled(x0 + radius, y1 - radius, radius, DRAW_CORNERS_BOTTOMLEFT, color);
+      if (radius*2+1 < height)
+      {
+        drawRectangleFilled(x0, y0 + radius, x0 + radius, y1 - radius, color);
+      }
+      drawRectangleFilled(x1 - radius, y0, x1, y1, color);
+      break;
+    case DRAW_CORNERS_RIGHT:
+      drawCornerFilled(x1 - radius, y0 + radius, radius, DRAW_CORNERS_TOPRIGHT, color);
+      drawCornerFilled(x1 - radius, y1 - radius, radius, DRAW_CORNERS_BOTTOMRIGHT, color);
+      if (radius*2+1 < height)
+      {
+        drawRectangleFilled(x1 - radius, y0 + radius, x1, y1 - radius, color);
+      }
+      drawRectangleFilled(x0, y0, x0 + radius, y1, color);
+      break;
+    default:
+      break;
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws a gradient-filled rectangle
+
+    @param[in]  x0
+                Starting x co-ordinate
+    @param[in]  y0
+                Starting y co-ordinate
+    @param[in]  x1
+                Ending x co-ordinate
+    @param[in]  y1
+                Ending y co-ordinate
+    @param[in]  startColor
+                The color at the start of the gradient
+    @param[in]  endColor
+                The color at the end of the gradient
+
+    @section EXAMPLE
+
+    @code
+
+    #include "drivers/displays/graphic/drawing.h"
+    #include "drivers/displays/graphic/aafonts.h"
+    #include "drivers/displays/graphic/aafonts/aa2/DejaVuSansCondensed14_AA2.h"
+
+    // Draw a gradient-filled rectangle with anti-aliased text inside it
+
+    uint16_t btnWidth, btnHeight, btnX, btnY;
+    uint16_t fntX, fntY;
+
+    btnWidth = 200;
+    btnHeight = 20;
+    btnX = 10;
+    btnY = 30;
+
+    lcdFillRGB(0xFFFF);
+
+    drawRectangle(btnX-1, btnY-1, btnX+btnWidth+1, btnY+btnHeight+1, COLOR_GRAY_80);
+    drawGradient(btnX, btnY, btnX+btnWidth, btnY+btnHeight, COLOR_WHITE, COLOR_GRAY_128);
+
+    // Center text vertically and horizontally
+    fntY = btnY + ((btnHeight - DejaVuSansCondensed14_AA2.fontHeight) / 2);
+    fntX = btnX + ((btnWidth - aafontsGetStringWidth(&DejaVuSansCondensed14_AA2, "Click to continue"))/2);
+    aafontsDrawString(fntX, fntY, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensed14_AA2, "Click to continue");
+
+    @endcode
+*/
+/**************************************************************************/
+void drawGradient ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t startColor, uint16_t endColor)
+{
+  int height;
+  uint16_t x, y;
+  uint8_t r, g, b;
+  int16_t rDelta, gDelta, bDelta;
+
+  // Clear gradient steps, etc.
+  r = g = b = 0;
+  rDelta = gDelta = bDelta = 0;
+
+  if (y1 < y0)
+  {
+    // Switch y1 and y0
+    y = y1;
+    y1 = y0;
+    y0 = y;
+  }
+
+  if (x1 < x0)
+  {
+    // Switch x1 and x0
+    x = x1;
+    x1 = x0;
+    x0 = x;
+  }
+
+  height = y1 - y0;
+
+  // Calculate global r/g/b changes between start and end colors
+  rDelta = ((endColor >> 11) & 0x1F) - ((startColor >> 11) & 0x1F);
+  gDelta = ((endColor >> 5) & 0x3F) - ((startColor >> 5) & 0x3F);
+  bDelta = (endColor & 0x1F) - (startColor & 0x1F);
+
+  // Calculate interpolation deltas to 2 decimal places (fixed point)
+  rDelta = (rDelta * 100) / height;
+  gDelta = (gDelta * 100) / height;
+  bDelta = (bDelta * 100) / height;
+
+  // Draw individual lines
+  for (height = y0; y1 > height - 1; ++height)
+  {
+    // Calculate new rgb values based on: start color + (line number * interpolation delta)
+    r = ((startColor >> 11) & 0x1F) + ((rDelta * (height - y0)) / 100);
+    g = ((startColor >> 5) & 0x3F) + ((gDelta * (height - y0)) / 100);
+    b = (startColor & 0x1F) + ((bDelta * (height - y0)) / 100);
+    drawLine(x0, height, x1, height, ((r & 0x1F) << 11) | ((g & 0x3F) << 5) | (b & 0x1F));
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws a triangle
+
+    @param[in]  x0
+                x co-ordinate for point 0
+    @param[in]  y0
+                y co-ordinate for point 0
+    @param[in]  x1
+                x co-ordinate for point 1
+    @param[in]  y1
+                y co-ordinate for point 1
+    @param[in]  x2
+                x co-ordinate for point 2
+    @param[in]  y2
+                y co-ordinate for point 2
+    @param[in]  color
+                Color used when drawing
+*/
+/**************************************************************************/
+void drawTriangle ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
+{
+  drawLine(x0, y0, x1, y1, color);
+  drawLine(x1, y1, x2, y2, color);
+  drawLine(x2, y2, x0, y0, color);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws a filled triangle
+
+    @param[in]  x0
+                x co-ordinate for point 0
+    @param[in]  y0
+                y co-ordinate for point 0
+    @param[in]  x1
+                x co-ordinate for point 1
+    @param[in]  y1
+                y co-ordinate for point 1
+    @param[in]  x2
+                x co-ordinate for point 2
+    @param[in]  y2
+                y co-ordinate for point 2
+    @param[in]  color
+                Fill color
+
+    @section Example
+
+    @code
+
+    // Draw a white triangle
+    drawTriangleFilled ( 100, 10, 20, 120, 230, 290, COLOR_WHITE);
+    // Draw black circles at each point of the triangle
+    drawCircleFilled(100, 10, 2, COLOR_BLACK);
+    drawCircleFilled(20, 120, 2, COLOR_BLACK);
+    drawCircleFilled(230, 290, 2, COLOR_BLACK);
+
+    @endcode
+*/
+/**************************************************************************/
+void drawTriangleFilled ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
+{
+  // Re-order vertices by ascending Y values (smallest first)
+  if (y0 > y1) {
+    drawSwap(y0, y1); drawSwap(x0, x1);
+  }
+  if (y1 > y2) {
+    drawSwap(y2, y1); drawSwap(x2, x1);
+  }
+  if (y0 > y1) {
+    drawSwap(y0, y1); drawSwap(x0, x1);
+  }
+
+  int32_t dx1, dx2, dx3;    // Interpolation deltas
+  int32_t sx1, sx2, sy;     // Scanline co-ordinates
+
+  sx1=sx2=x0 * 1000;        // Use fixed point math for x axis values
+  sy=y0;
+
+  // Calculate interpolation deltas
+  if (y1-y0 > 0) dx1=((x1-x0)*1000)/(y1-y0);
+    else dx1=0;
+  if (y2-y0 > 0) dx2=((x2-x0)*1000)/(y2-y0);
+    else dx2=0;
+  if (y2-y1 > 0) dx3=((x2-x1)*1000)/(y2-y1);
+    else dx3=0;
+
+  // Render scanlines (horizontal lines are the fastest rendering method)
+  if (dx1 > dx2)
+  {
+    for(; sy<=y1; sy++, sx1+=dx2, sx2+=dx1)
+    {
+      drawLine(sx1/1000, sy, sx2/1000, sy, color);
+    }
+    sx2 = x1*1000;
+    sy = y1;
+    for(; sy<=y2; sy++, sx1+=dx2, sx2+=dx3)
+    {
+      drawLine(sx1/1000, sy, sx2/1000, sy, color);
+    }
+  }
+  else
+  {
+    for(; sy<=y1; sy++, sx1+=dx1, sx2+=dx2)
+    {
+      drawLine(sx1/1000, sy, sx2/1000, sy, color);
+    }
+    sx1 = x1*1000;
+    sy = y1;
+    for(; sy<=y2; sy++, sx1+=dx3, sx2+=dx2)
+    {
+      drawLine(sx1/1000, sy, sx2/1000, sy, color);
+    }
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Renders a 16x16 monochrome icon using the supplied uint16_t
+            array.
+
+    @param[in]  x
+                The horizontal location to start rendering from
+    @param[in]  y
+                The vertical location to start rendering from
+    @param[in]  color
+                The RGB565 color to use when rendering the icon
+    @param[in]  icon
+                The uint16_t array containing the 16x16 image data
+
+    @section Example
+
+    @code
+
+    #include "drivers/displays/graphic/drawing.h"
+    #include "drivers/displays/icons16.h"
+
+    // Renders the info icon, which has two seperate parts ... the exterior
+    // and a seperate interior mask if you want to fill the contents with a
+    // different color
+    drawIcon16(132, 202, COLOR_BLUE, icons16_info);
+    drawIcon16(132, 202, COLOR_WHITE, icons16_info_interior);
+
+    @endcode
+*/
+/**************************************************************************/
+void drawIcon16(uint16_t x, uint16_t y, uint16_t color, uint16_t icon[])
+{
+  int i;
+  for (i = 0; i<16; i++)
+  {
+    if (icon[i] & (0X8000)) drawPixel(x, y+i, color);
+    if (icon[i] & (0X4000)) drawPixel(x+1, y+i, color);
+    if (icon[i] & (0X2000)) drawPixel(x+2, y+i, color);
+    if (icon[i] & (0X1000)) drawPixel(x+3, y+i, color);
+    if (icon[i] & (0X0800)) drawPixel(x+4, y+i, color);
+    if (icon[i] & (0X0400)) drawPixel(x+5, y+i, color);
+    if (icon[i] & (0X0200)) drawPixel(x+6, y+i, color);
+    if (icon[i] & (0X0100)) drawPixel(x+7, y+i, color);
+    if (icon[i] & (0X0080)) drawPixel(x+8, y+i, color);
+    if (icon[i] & (0x0040)) drawPixel(x+9, y+i, color);
+    if (icon[i] & (0X0020)) drawPixel(x+10, y+i, color);
+    if (icon[i] & (0X0010)) drawPixel(x+11, y+i, color);
+    if (icon[i] & (0X0008)) drawPixel(x+12, y+i, color);
+    if (icon[i] & (0X0004)) drawPixel(x+13, y+i, color);
+    if (icon[i] & (0X0002)) drawPixel(x+14, y+i, color);
+    if (icon[i] & (0X0001)) drawPixel(x+15, y+i, color);
+  }
+}
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/drawing.h b/reform2-lpc-fw/src/drivers/displays/graphic/drawing.h
new file mode 100644
index 0000000000000000000000000000000000000000..2543e6e562009484782d90ede040d1af33cf7551
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/drawing.h
@@ -0,0 +1,107 @@
+/**************************************************************************/
+/*! 
+    @file     drawing.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __DRAWING_H__
+#define __DRAWING_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "lcd.h"
+#include "colors.h"
+#include "theme.h"
+
+#if CFG_TFTLCD_USEAAFONTS
+  #include "aafonts.h"
+#else
+  #include "fonts.h"
+#endif
+
+#if CFG_TFTLCD_INCLUDESMALLFONTS
+  #include "drivers/displays/smallfonts.h"
+#endif
+
+typedef enum
+{
+  DRAW_CORNERS_NONE        = 0x00,
+  DRAW_CORNERS_TOPLEFT     = 0x01,
+  DRAW_CORNERS_TOPRIGHT    = 0x02,
+  DRAW_CORNERS_BOTTOMLEFT  = 0x04,
+  DRAW_CORNERS_BOTTOMRIGHT = 0x08,
+  DRAW_CORNERS_ALL         = 0x0F, // 0x01 + 0x02 + 0x04 + 0x08
+  DRAW_CORNERS_TOP         = 0x03, // 0x01 + 0x02
+  DRAW_CORNERS_BOTTOM      = 0x0C, // 0x04 + 0x08
+  DRAW_CORNERS_LEFT        = 0x05, // 0x01 + 0x04
+  DRAW_CORNERS_RIGHT       = 0x0A  // 0x02 + 0x08
+} drawCorners_t;
+
+typedef enum
+{
+  DRAW_DIRECTION_LEFT,
+  DRAW_DIRECTION_RIGHT,
+  DRAW_DIRECTION_UP,
+  DRAW_DIRECTION_DOWN
+} drawDirection_t;
+
+void      drawTestPattern      ( void );
+void      drawPixel            ( uint16_t x, uint16_t y, uint16_t color );
+void      drawFill             ( uint16_t color );
+void      drawLine             ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color );
+void      drawLineDotted       ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t space, uint16_t solid, uint16_t color );
+void      drawCircle           ( uint16_t xCenter, uint16_t yCenter, uint16_t radius, uint16_t color );
+void      drawCircleFilled     ( uint16_t xCenter, uint16_t yCenter, uint16_t radius, uint16_t color );
+void      drawCorner           ( uint16_t xCenter, uint16_t yCenter, uint16_t r, drawCorners_t corner, uint16_t color );
+void      drawCornerFilled     ( uint16_t xCenter, uint16_t yCenter, uint16_t radius, drawCorners_t position, uint16_t color );
+void      drawArrow            ( uint16_t x, uint16_t y, uint16_t size, drawDirection_t, uint16_t color );
+void      drawRectangle        ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color );
+void      drawRectangleFilled  ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color );
+void      drawRoundedRectangle ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color, uint16_t radius, drawCorners_t corners );
+void      drawRoundedRectangleFilled ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color, uint16_t radius, drawCorners_t corners );
+void      drawGradient         ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t startColor, uint16_t endColor );
+void      drawTriangle         ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color );
+void      drawTriangleFilled   ( uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color );
+void      drawIcon16           ( uint16_t x, uint16_t y, uint16_t color, uint16_t icon[] );
+
+#if CFG_TFTLCD_INCLUDESMALLFONTS
+void      drawStringSmall      ( uint16_t x, uint16_t y, uint16_t color, char* text, struct FONT_DEF font );
+#endif
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts.c b/reform2-lpc-fw/src/drivers/displays/graphic/fonts.c
new file mode 100644
index 0000000000000000000000000000000000000000..3f8551fca8c3a9ea0d3b2a7485f76bbd048a648f
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts.c
@@ -0,0 +1,219 @@
+/**************************************************************************/
+/*! 
+    @file     aafonts.c
+    @author   K. Townsend (microBuilder.eu)
+
+    drawString based on an example from Eran Duchan:
+    http://www.pavius.net/downloads/tools/53-the-dot-factory
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "fonts.h"
+#include "lcd.h"
+#include "drawing.h"
+
+/**************************************************************************/
+/*                                                                        */
+/* ----------------------- Private Methods ------------------------------ */
+/*                                                                        */
+/**************************************************************************/
+
+/**************************************************************************/
+/*!
+    @brief  Draws a single bitmap character
+*/
+/**************************************************************************/
+void fontsDrawCharBitmap(const uint16_t xPixel, const uint16_t yPixel, uint16_t color, const char *glyph, uint8_t cols, uint8_t rows)
+{
+  uint16_t currentY, currentX, indexIntoGlyph;
+  uint16_t _row, _col, _colPages;
+
+  // set initial current y
+  currentY = yPixel;
+  currentX = xPixel;
+
+  // Figure out how many columns worth of data we have
+  if (cols % 8)
+    _colPages = cols / 8 + 1;
+  else
+    _colPages = cols / 8;
+
+  for (_row = 0; _row < rows; _row++)
+  {
+    for (_col = 0; _col < _colPages; _col++)
+    {
+      if (_row == 0)
+        indexIntoGlyph = _col;
+      else
+        indexIntoGlyph = (_row * _colPages) + _col;
+
+      currentY = yPixel + _row;
+      currentX = xPixel + (_col*8);
+      // send the data byte
+      if (glyph[indexIntoGlyph] & (0X80)) drawPixel(currentX, currentY, color);
+      if (glyph[indexIntoGlyph] & (0X40)) drawPixel(currentX+1, currentY, color);
+      if (glyph[indexIntoGlyph] & (0X20)) drawPixel(currentX+2, currentY, color);
+      if (glyph[indexIntoGlyph] & (0X10)) drawPixel(currentX+3, currentY, color);
+      if (glyph[indexIntoGlyph] & (0X08)) drawPixel(currentX+4, currentY, color);
+      if (glyph[indexIntoGlyph] & (0X04)) drawPixel(currentX+5, currentY, color);
+      if (glyph[indexIntoGlyph] & (0X02)) drawPixel(currentX+6, currentY, color);
+      if (glyph[indexIntoGlyph] & (0X01)) drawPixel(currentX+7, currentY, color);
+    }
+  }
+}
+
+/**************************************************************************/
+/*                                                                        */
+/* ----------------------- Public Methods ------------------------------- */
+/*                                                                        */
+/**************************************************************************/
+
+/**************************************************************************/
+/*!
+    @brief  Draws a string using the supplied font
+
+    @param[in]  x
+                Starting x co-ordinate
+    @param[in]  y
+                Starting y co-ordinate
+    @param[in]  color
+                Color to use when rendering the font
+    @param[in]  fontInfo
+                Pointer to the FONT_INFO to use when drawing the string
+    @param[in]  str
+                The string to render
+
+    @section Example
+
+    @code 
+
+    #include "drivers/displays/graphic/fonts/dejavusans9.h"
+    
+    fontsDrawString(0, 90,  COLOR_BLACK, &dejaVuSans9ptFontInfo, "DejaVu Sans 9");
+    fontsDrawString(0, 105, COLOR_BLACK, &dejaVuSans9ptFontInfo, "123456789012345678901234567890");
+
+    @endcode
+*/
+/**************************************************************************/
+void fontsDrawString(uint16_t x, uint16_t y, uint16_t color, const FONT_INFO *fontInfo, char *str)
+{
+  uint16_t currentX, charWidth, characterToOutput;
+  const FONT_CHAR_INFO *charInfo;
+  uint16_t charOffset;
+
+  // set current x, y to that of requested
+  currentX = x;
+
+  // while not NULL
+  while (*str != '\0')
+  {
+    // get character to output
+    characterToOutput = *str;
+    
+    // get char info
+    charInfo = fontInfo->charInfo;
+    
+    // some fonts have character descriptors, some don't
+    if (charInfo != NULL)
+    {
+      // get correct char offset
+      charInfo += (characterToOutput - fontInfo->startChar);
+      
+      // get width from char info
+      charWidth = charInfo->widthBits;
+      
+      // get offset from char info
+      charOffset = charInfo->offset;
+    }        
+    else
+    {
+      // if no char info, char width is always 5
+      charWidth = 5;
+      
+      // char offset - assume 5 * letter offset
+      charOffset = (characterToOutput - fontInfo->startChar) * 5;
+    }        
+    
+    // Send individual characters
+    // We need to manually calculate width in pages since this is screwy with variable width fonts
+    //uint8_t heightPages = charWidth % 8 ? charWidth / 8 : charWidth / 8 + 1;
+    fontsDrawCharBitmap(currentX, y, color, (const char *)(&fontInfo->data[charOffset]), charWidth, fontInfo->height);
+
+    // next char X
+    currentX += charWidth + 1;
+    
+    // next char
+    str++;
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Returns the width in pixels of a string when it is rendered
+
+    This method can be used to determine whether a string will fit
+    inside a specific area, or if it needs to be broken up into multiple
+    lines to be properly rendered on the screen.
+
+    This function only applied to bitmap fonts (which can have variable
+    widths).  All smallfonts (if available) are fixed width and can
+    easily have their width calculated without costly functions like
+    this one.
+
+    @param[in]  fontInfo
+                Pointer to the FONT_INFO for the font that will be used
+    @param[in]  str
+                The string that will be rendered
+*/
+/**************************************************************************/
+uint16_t fontsGetStringWidth(const FONT_INFO *fontInfo, char *str)
+{
+  uint16_t width = 0;
+  uint32_t currChar;
+  uint32_t startChar = fontInfo->startChar;
+
+  // until termination
+  for (currChar = *str; currChar; currChar = *(++str))
+  {
+    // if char info exists for the font, use width from there
+    if (fontInfo->charInfo != NULL)
+    {
+      width += fontInfo->charInfo[currChar - startChar].widthBits + 1;
+    }
+    else
+    {
+      width += 5 + 1;
+    }
+  }
+
+  /* return the width */
+  return width > 0 ? width - 1 : width;
+}
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts.h b/reform2-lpc-fw/src/drivers/displays/graphic/fonts.h
new file mode 100644
index 0000000000000000000000000000000000000000..7fc3d249076206724dd063248c57f3a5175d4e0f
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts.h
@@ -0,0 +1,77 @@
+/**************************************************************************/
+/*! 
+    @file     fonts.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __FONTS_H__
+#define __FONTS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+/**************************************************************************/
+/*! 
+    @brief Describes a single character's display information
+*/
+/**************************************************************************/
+typedef struct
+{
+  const uint8_t widthBits;              // width, in bits (or pixels), of the character
+  const uint16_t offset;                // offset of the character's bitmap, in bytes, into the the FONT_INFO's data array
+} FONT_CHAR_INFO;	
+
+/**************************************************************************/
+/*! 
+    @brief Describes a single font
+*/
+/**************************************************************************/
+typedef struct
+{
+  const uint8_t           height;       // height of the font's characters
+  const uint8_t           startChar;    // the first character in the font (e.g. in charInfo and data)
+  const uint8_t           endChar;      // the last character in the font (e.g. in charInfo and data)
+  const FONT_CHAR_INFO*	  charInfo;     // pointer to array of char information
+  const uint8_t*          data;         // pointer to generated array of character visual representation
+} FONT_INFO;
+
+void      fontsDrawString      ( uint16_t x, uint16_t y, uint16_t color, const FONT_INFO *fontInfo, char *str );
+uint16_t  fontsGetStringWidth  ( const FONT_INFO *fontInfo, char *str ); 
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusans9.c b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusans9.c
new file mode 100644
index 0000000000000000000000000000000000000000..1c5210b94f12a481773729e1e1a1fde9e77f922c
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusans9.c
@@ -0,0 +1,1545 @@
+#include "dejavusans9.h"
+
+/* 
+**  Font data for DejaVu Sans 9pt
+*/
+
+/* Character bitmaps for DejaVu Sans 9pt */
+const uint8_t dejaVuSans9ptBitmaps[] = 
+{
+	/* @0 ' ' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @13 '!' (1 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @26 '"' (3 pixels wide) */
+	0x00, /*          */
+	0xA0, /* # #      */
+	0xA0, /* # #      */
+	0xA0, /* # #      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @39 '#' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x12, /*    #  #  */
+	0x14, /*    # #   */
+	0x7F, /*  ####### */
+	0x24, /*   #  #   */
+	0x24, /*   #  #   */
+	0xFE, /* #######  */
+	0x28, /*   # #    */
+	0x48, /*  #  #    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @52 '$' (5 pixels wide) */
+	0x00, /*          */
+	0x20, /*   #      */
+	0x70, /*  ###     */
+	0xA8, /* # # #    */
+	0xA0, /* # #      */
+	0xE0, /* ###      */
+	0x38, /*   ###    */
+	0x28, /*   # #    */
+	0xA8, /* # # #    */
+	0x70, /*  ###     */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x00, /*          */
+
+	/* @65 '%' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x61, 0x00, /*  ##    #         */
+	0x92, 0x00, /* #  #  #          */
+	0x92, 0x00, /* #  #  #          */
+	0x94, 0x00, /* #  # #           */
+	0x6D, 0x80, /*  ## ## ##        */
+	0x0A, 0x40, /*     # #  #       */
+	0x12, 0x40, /*    #  #  #       */
+	0x12, 0x40, /*    #  #  #       */
+	0x21, 0x80, /*   #    ##        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @91 '&' (8 pixels wide) */
+	0x00, /*          */
+	0x30, /*   ##     */
+	0x48, /*  #  #    */
+	0x40, /*  #       */
+	0x60, /*  ##      */
+	0x51, /*  # #   # */
+	0x89, /* #   #  # */
+	0x86, /* #    ##  */
+	0xC4, /* ##   #   */
+	0x7B, /*  #### ## */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @104 ''' (1 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @117 '(' (3 pixels wide) */
+	0x60, /*  ##      */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x60, /*  ##      */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @130 ')' (3 pixels wide) */
+	0xC0, /* ##       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @143 '*' (5 pixels wide) */
+	0x00, /*          */
+	0x20, /*   #      */
+	0xA8, /* # # #    */
+	0x70, /*  ###     */
+	0x70, /*  ###     */
+	0xA8, /* # # #    */
+	0x20, /*   #      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @156 '+' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0xFE, /* #######  */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @169 ',' (1 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @182 '-' (3 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xE0, /* ###      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @195 '.' (1 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @208 '/' (4 pixels wide) */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @221 '0' (6 pixels wide) */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x48, /*  #  #    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x48, /*  #  #    */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @234 '1' (5 pixels wide) */
+	0x00, /*          */
+	0xE0, /* ###      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @247 '2' (6 pixels wide) */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x8C, /* #   ##   */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x08, /*     #    */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0xFC, /* ######   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @260 '3' (6 pixels wide) */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x84, /* #    #   */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x38, /*   ###    */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x84, /* #    #   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @273 '4' (6 pixels wide) */
+	0x00, /*          */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x28, /*   # #    */
+	0x48, /*  #  #    */
+	0x48, /*  #  #    */
+	0x88, /* #   #    */
+	0xFC, /* ######   */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @286 '5' (6 pixels wide) */
+	0x00, /*          */
+	0xF8, /* #####    */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xF8, /* #####    */
+	0x0C, /*     ##   */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x8C, /* #   ##   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @299 '6' (6 pixels wide) */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x44, /*  #   #   */
+	0x80, /* #        */
+	0xB8, /* # ###    */
+	0xCC, /* ##  ##   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x4C, /*  #  ##   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @312 '7' (6 pixels wide) */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0x04, /*      #   */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @325 '8' (6 pixels wide) */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x78, /*  ####    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @338 '9' (6 pixels wide) */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0xC8, /* ##  #    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0xCC, /* ##  ##   */
+	0x74, /*  ### #   */
+	0x04, /*      #   */
+	0x88, /* #   #    */
+	0x70, /*  ###     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @351 ':' (1 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @364 ';' (1 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @377 '<' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x03, /*       ## */
+	0x1E, /*    ####  */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0x1E, /*    ####  */
+	0x03, /*       ## */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @390 '=' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xFF, /* ######## */
+	0x00, /*          */
+	0xFF, /* ######## */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @403 '>' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0x78, /*  ####    */
+	0x07, /*      ### */
+	0x07, /*      ### */
+	0x78, /*  ####    */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @416 '?' (5 pixels wide) */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0x88, /* #   #    */
+	0x08, /*     #    */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x00, /*          */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @429 '@' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0x00, /*    #####         */
+	0x20, 0xC0, /*   #     ##       */
+	0x40, 0x40, /*  #       #       */
+	0x8F, 0x20, /* #   ####  #      */
+	0x91, 0x20, /* #  #   #  #      */
+	0x91, 0x20, /* #  #   #  #      */
+	0x91, 0x40, /* #  #   # #       */
+	0x8F, 0x80, /* #   #####        */
+	0x40, 0x00, /*  #               */
+	0x20, 0x80, /*   #     #        */
+	0x1F, 0x00, /*    #####         */
+	0x00, 0x00, /*                  */
+
+	/* @455 'A' (8 pixels wide) */
+	0x00, /*          */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x24, /*   #  #   */
+	0x24, /*   #  #   */
+	0x24, /*   #  #   */
+	0x42, /*  #    #  */
+	0x7E, /*  ######  */
+	0x42, /*  #    #  */
+	0x81, /* #      # */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @468 'B' (6 pixels wide) */
+	0x00, /*          */
+	0xF8, /* #####    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0xF8, /* #####    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @481 'C' (6 pixels wide) */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x44, /*  #   #   */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x44, /*  #   #   */
+	0x38, /*   ###    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @494 'D' (7 pixels wide) */
+	0x00, /*          */
+	0xF8, /* #####    */
+	0x84, /* #    #   */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x84, /* #    #   */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @507 'E' (6 pixels wide) */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xFC, /* ######   */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xFC, /* ######   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @520 'F' (5 pixels wide) */
+	0x00, /*          */
+	0xF8, /* #####    */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xF8, /* #####    */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @533 'G' (7 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x42, /*  #    #  */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x8E, /* #   ###  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x42, /*  #    #  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @546 'H' (7 pixels wide) */
+	0x00, /*          */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0xFE, /* #######  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @559 'I' (1 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @572 'J' (3 pixels wide) */
+	0x00, /*          */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0xC0, /* ##       */
+	0x00, /*          */
+
+	/* @585 'K' (6 pixels wide) */
+	0x00, /*          */
+	0x84, /* #    #   */
+	0x88, /* #   #    */
+	0x90, /* #  #     */
+	0xA0, /* # #      */
+	0xC0, /* ##       */
+	0xA0, /* # #      */
+	0x90, /* #  #     */
+	0x88, /* #   #    */
+	0x84, /* #    #   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @598 'L' (5 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @611 'M' (8 pixels wide) */
+	0x00, /*          */
+	0x81, /* #      # */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xA5, /* # #  # # */
+	0xA5, /* # #  # # */
+	0x99, /* #  ##  # */
+	0x99, /* #  ##  # */
+	0x81, /* #      # */
+	0x81, /* #      # */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @624 'N' (7 pixels wide) */
+	0x00, /*          */
+	0xC2, /* ##    #  */
+	0xC2, /* ##    #  */
+	0xA2, /* # #   #  */
+	0xA2, /* # #   #  */
+	0x92, /* #  #  #  */
+	0x8A, /* #   # #  */
+	0x8A, /* #   # #  */
+	0x86, /* #    ##  */
+	0x86, /* #    ##  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @637 'O' (7 pixels wide) */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x44, /*  #   #   */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x44, /*  #   #   */
+	0x38, /*   ###    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @650 'P' (6 pixels wide) */
+	0x00, /*          */
+	0xF8, /* #####    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0xF8, /* #####    */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @663 'Q' (7 pixels wide) */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x44, /*  #   #   */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x44, /*  #   #   */
+	0x38, /*   ###    */
+	0x08, /*     #    */
+	0x04, /*      #   */
+	0x00, /*          */
+
+	/* @676 'R' (7 pixels wide) */
+	0x00, /*          */
+	0xF8, /* #####    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0xF8, /* #####    */
+	0x88, /* #   #    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x82, /* #     #  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @689 'S' (6 pixels wide) */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x84, /* #    #   */
+	0x80, /* #        */
+	0xC0, /* ##       */
+	0x78, /*  ####    */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x84, /* #    #   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @702 'T' (7 pixels wide) */
+	0x00, /*          */
+	0xFE, /* #######  */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @715 'U' (7 pixels wide) */
+	0x00, /*          */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0xC6, /* ##   ##  */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @728 'V' (8 pixels wide) */
+	0x00, /*          */
+	0x81, /* #      # */
+	0x81, /* #      # */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x24, /*   #  #   */
+	0x24, /*   #  #   */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @741 'W' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x84, 0x20, /* #    #    #      */
+	0x44, 0x40, /*  #   #   #       */
+	0x44, 0x40, /*  #   #   #       */
+	0x4A, 0x40, /*  #  # #  #       */
+	0x2A, 0x80, /*   # # # #        */
+	0x2A, 0x80, /*   # # # #        */
+	0x2A, 0x80, /*   # # # #        */
+	0x11, 0x00, /*    #   #         */
+	0x11, 0x00, /*    #   #         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @767 'X' (7 pixels wide) */
+	0x00, /*          */
+	0xC6, /* ##   ##  */
+	0x44, /*  #   #   */
+	0x28, /*   # #    */
+	0x28, /*   # #    */
+	0x10, /*    #     */
+	0x28, /*   # #    */
+	0x28, /*   # #    */
+	0x44, /*  #   #   */
+	0x82, /* #     #  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @780 'Y' (7 pixels wide) */
+	0x00, /*          */
+	0x82, /* #     #  */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x28, /*   # #    */
+	0x28, /*   # #    */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @793 'Z' (7 pixels wide) */
+	0x00, /*          */
+	0xFE, /* #######  */
+	0x02, /*       #  */
+	0x04, /*      #   */
+	0x08, /*     #    */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0x80, /* #        */
+	0xFE, /* #######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @806 '[' (2 pixels wide) */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xC0, /* ##       */
+	0x00, /*          */
+
+	/* @819 '\' (4 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @832 ']' (2 pixels wide) */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0xC0, /* ##       */
+	0x00, /*          */
+
+	/* @845 '^' (6 pixels wide) */
+	0x00, /*          */
+	0x30, /*   ##     */
+	0x48, /*  #  #    */
+	0x84, /* #    #   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @858 '_' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xFC, /* ######   */
+
+	/* @871 '`' (2 pixels wide) */
+	0x80, /* #        */
+	0x40, /*  #       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @884 'a' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x84, /* #    #   */
+	0x04, /*      #   */
+	0x7C, /*  #####   */
+	0x84, /* #    #   */
+	0x8C, /* #   ##   */
+	0x74, /*  ### #   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @897 'b' (6 pixels wide) */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xF8, /* #####    */
+	0xCC, /* ##  ##   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0xCC, /* ##  ##   */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @910 'c' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0xC8, /* ##  #    */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xC8, /* ##  #    */
+	0x70, /*  ###     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @923 'd' (6 pixels wide) */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x7C, /*  #####   */
+	0xCC, /* ##  ##   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0xCC, /* ##  ##   */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @936 'e' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0xCC, /* ##  ##   */
+	0x84, /* #    #   */
+	0xFC, /* ######   */
+	0x80, /* #        */
+	0xC4, /* ##   #   */
+	0x38, /*   ###    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @949 'f' (4 pixels wide) */
+	0x30, /*   ##     */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0xF0, /* ####     */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @962 'g' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0xCC, /* ##  ##   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0xCC, /* ##  ##   */
+	0x7C, /*  #####   */
+	0x04, /*      #   */
+	0x4C, /*  #  ##   */
+	0x38, /*   ###    */
+
+	/* @975 'h' (6 pixels wide) */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xB8, /* # ###    */
+	0xC4, /* ##   #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @988 'i' (1 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1001 'j' (2 pixels wide) */
+	0x00, /*          */
+	0x40, /*  #       */
+	0x00, /*          */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0xC0, /* ##       */
+
+	/* @1014 'k' (5 pixels wide) */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x88, /* #   #    */
+	0x90, /* #  #     */
+	0xA0, /* # #      */
+	0xC0, /* ##       */
+	0xA0, /* # #      */
+	0x90, /* #  #     */
+	0x88, /* #   #    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1027 'l' (1 pixels wide) */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1040 'm' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xF7, 0x00, /* #### ###         */
+	0x88, 0x80, /* #   #   #        */
+	0x88, 0x80, /* #   #   #        */
+	0x88, 0x80, /* #   #   #        */
+	0x88, 0x80, /* #   #   #        */
+	0x88, 0x80, /* #   #   #        */
+	0x88, 0x80, /* #   #   #        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1066 'n' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xB8, /* # ###    */
+	0xC4, /* ##   #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1079 'o' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0xCC, /* ##  ##   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0xCC, /* ##  ##   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1092 'p' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xF8, /* #####    */
+	0xCC, /* ##  ##   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0xCC, /* ##  ##   */
+	0xF8, /* #####    */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+
+	/* @1105 'q' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0xCC, /* ##  ##   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0xCC, /* ##  ##   */
+	0x7C, /*  #####   */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x04, /*      #   */
+
+	/* @1118 'r' (4 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xB0, /* # ##     */
+	0xC0, /* ##       */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1131 's' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0x88, /* #   #    */
+	0x80, /* #        */
+	0x70, /*  ###     */
+	0x08, /*     #    */
+	0x88, /* #   #    */
+	0x70, /*  ###     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1144 't' (4 pixels wide) */
+	0x00, /*          */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0xF0, /* ####     */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x70, /*  ###     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1157 'u' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x8C, /* #   ##   */
+	0x74, /*  ### #   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1170 'v' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x48, /*  #  #    */
+	0x48, /*  #  #    */
+	0x48, /*  #  #    */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1183 'w' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x88, 0x80, /* #   #   #        */
+	0x88, 0x80, /* #   #   #        */
+	0x55, 0x00, /*  # # # #         */
+	0x55, 0x00, /*  # # # #         */
+	0x55, 0x00, /*  # # # #         */
+	0x22, 0x00, /*   #   #          */
+	0x22, 0x00, /*   #   #          */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1209 'x' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x84, /* #    #   */
+	0x48, /*  #  #    */
+	0x48, /*  #  #    */
+	0x30, /*   ##     */
+	0x48, /*  #  #    */
+	0x48, /*  #  #    */
+	0x84, /* #    #   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1222 'y' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x48, /*  #  #    */
+	0x48, /*  #  #    */
+	0x28, /*   # #    */
+	0x30, /*   ##     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0xC0, /* ##       */
+
+	/* @1235 'z' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xF8, /* #####    */
+	0x08, /*     #    */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0x80, /* #        */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1248 '{' (5 pixels wide) */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0xC0, /* ##       */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x38, /*   ###    */
+	0x00, /*          */
+
+	/* @1261 '|' (1 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+
+	/* @1274 '}' (5 pixels wide) */
+	0x00, /*          */
+	0xE0, /* ###      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x18, /*    ##    */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0xE0, /* ###      */
+	0x00, /*          */
+
+	/* @1287 '~' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x71, /*  ###   # */
+	0x8E, /* #   ###  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+};
+
+/* Character descriptors for DejaVu Sans 9pt */
+/* { [Char width in bits], [Offset into dejaVuSans9ptCharBitmaps in bytes] } */
+const FONT_CHAR_INFO dejaVuSans9ptDescriptors[] = 
+{
+	{5, 0}, 		/*   */ 
+	{1, 13}, 		/* ! */ 
+	{3, 26}, 		/* " */ 
+	{8, 39}, 		/* # */ 
+	{5, 52}, 		/* $ */ 
+	{10, 65}, 		/* % */ 
+	{8, 91}, 		/* & */ 
+	{1, 104}, 		/* ' */ 
+	{3, 117}, 		/* ( */ 
+	{3, 130}, 		/* ) */ 
+	{5, 143}, 		/* * */ 
+	{7, 156}, 		/* + */ 
+	{1, 169}, 		/* , */ 
+	{3, 182}, 		/* - */ 
+	{1, 195}, 		/* . */ 
+	{4, 208}, 		/* / */ 
+	{6, 221}, 		/* 0 */ 
+	{5, 234}, 		/* 1 */ 
+	{6, 247}, 		/* 2 */ 
+	{6, 260}, 		/* 3 */ 
+	{6, 273}, 		/* 4 */ 
+	{6, 286}, 		/* 5 */ 
+	{6, 299}, 		/* 6 */ 
+	{6, 312}, 		/* 7 */ 
+	{6, 325}, 		/* 8 */ 
+	{6, 338}, 		/* 9 */ 
+	{1, 351}, 		/* : */ 
+	{1, 364}, 		/* ; */ 
+	{8, 377}, 		/* < */ 
+	{8, 390}, 		/* = */ 
+	{8, 403}, 		/* > */ 
+	{5, 416}, 		/* ? */ 
+	{11, 429}, 		/* @ */ 
+	{8, 455}, 		/* A */ 
+	{6, 468}, 		/* B */ 
+	{6, 481}, 		/* C */ 
+	{7, 494}, 		/* D */ 
+	{6, 507}, 		/* E */ 
+	{5, 520}, 		/* F */ 
+	{7, 533}, 		/* G */ 
+	{7, 546}, 		/* H */ 
+	{1, 559}, 		/* I */ 
+	{3, 572}, 		/* J */ 
+	{6, 585}, 		/* K */ 
+	{5, 598}, 		/* L */ 
+	{8, 611}, 		/* M */ 
+	{7, 624}, 		/* N */ 
+	{7, 637}, 		/* O */ 
+	{6, 650}, 		/* P */ 
+	{7, 663}, 		/* Q */ 
+	{7, 676}, 		/* R */ 
+	{6, 689}, 		/* S */ 
+	{7, 702}, 		/* T */ 
+	{7, 715}, 		/* U */ 
+	{8, 728}, 		/* V */ 
+	{11, 741}, 		/* W */ 
+	{7, 767}, 		/* X */ 
+	{7, 780}, 		/* Y */ 
+	{7, 793}, 		/* Z */ 
+	{2, 806}, 		/* [ */ 
+	{4, 819}, 		/* \ */ 
+	{2, 832}, 		/* ] */ 
+	{6, 845}, 		/* ^ */ 
+	{6, 858}, 		/* _ */ 
+	{2, 871}, 		/* ` */ 
+	{6, 884}, 		/* a */ 
+	{6, 897}, 		/* b */ 
+	{5, 910}, 		/* c */ 
+	{6, 923}, 		/* d */ 
+	{6, 936}, 		/* e */ 
+	{4, 949}, 		/* f */ 
+	{6, 962}, 		/* g */ 
+	{6, 975}, 		/* h */ 
+	{1, 988}, 		/* i */ 
+	{2, 1001}, 		/* j */ 
+	{5, 1014}, 		/* k */ 
+	{1, 1027}, 		/* l */ 
+	{9, 1040}, 		/* m */ 
+	{6, 1066}, 		/* n */ 
+	{6, 1079}, 		/* o */ 
+	{6, 1092}, 		/* p */ 
+	{6, 1105}, 		/* q */ 
+	{4, 1118}, 		/* r */ 
+	{5, 1131}, 		/* s */ 
+	{4, 1144}, 		/* t */ 
+	{6, 1157}, 		/* u */ 
+	{6, 1170}, 		/* v */ 
+	{9, 1183}, 		/* w */ 
+	{6, 1209}, 		/* x */ 
+	{6, 1222}, 		/* y */ 
+	{5, 1235}, 		/* z */ 
+	{5, 1248}, 		/* { */ 
+	{1, 1261}, 		/* | */ 
+	{5, 1274}, 		/* } */ 
+	{8, 1287}, 		/* ~ */ 
+};
+
+/* Font information for DejaVu Sans 9pt */
+const FONT_INFO dejaVuSans9ptFontInfo =
+{
+	13, /*  Character height */
+	' ', /*  Start character */
+	'~', /*  End character */
+	dejaVuSans9ptDescriptors, /*  Character descriptor array */
+	dejaVuSans9ptBitmaps, /*  Character bitmap array */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusans9.h b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusans9.h
new file mode 100644
index 0000000000000000000000000000000000000000..c63a4f02ac90ecb82b535294b80c36a561d88461
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusans9.h
@@ -0,0 +1,18 @@
+#ifndef __DEJA_VU_SANS_9__
+#define __DEJA_VU_SANS_9__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../fonts.h"
+
+extern const uint8_t dejaVuSans9ptCharBitmaps[];
+extern const FONT_CHAR_INFO dejaVuSans9ptCharDescriptors[];
+extern const FONT_INFO dejaVuSans9ptFontInfo;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusansbold9.c b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusansbold9.c
new file mode 100644
index 0000000000000000000000000000000000000000..bd186374da8cc62ccefc294dae946802c7e15c1a
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusansbold9.c
@@ -0,0 +1,1545 @@
+#include "dejavusansbold9.h"
+
+/* 
+**  Font data for DejaVu Sans Bold 9pt
+*/
+
+/* Character bitmaps for DejaVu Sans Bold 9pt */
+const uint8_t dejaVuSansBold9ptBitmaps[] = 
+{
+	/* @0 ' ' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @13 '!' (2 pixels wide) */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @26 '"' (3 pixels wide) */
+	0x00, /*          */
+	0xA0, /* # #      */
+	0xA0, /* # #      */
+	0xA0, /* # #      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @39 '#' (8 pixels wide) */
+	0x00, /*          */
+	0x12, /*    #  #  */
+	0x16, /*    # ##  */
+	0x7F, /*  ####### */
+	0x24, /*   #  #   */
+	0x24, /*   #  #   */
+	0xFE, /* #######  */
+	0x68, /*  ## #    */
+	0x68, /*  ## #    */
+	0x48, /*  #  #    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @52 '$' (7 pixels wide) */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x7C, /*  #####   */
+	0xD0, /* ## #     */
+	0xF0, /* ####     */
+	0xFC, /* ######   */
+	0x7E, /*  ######  */
+	0x1E, /*    ####  */
+	0x16, /*    # ##  */
+	0xFC, /* ######   */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+
+	/* @65 '%' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x71, 0x00, /*  ###   #         */
+	0x89, 0x00, /* #   #  #         */
+	0x8A, 0x00, /* #   # #          */
+	0x8E, 0x00, /* #   ###          */
+	0x75, 0xC0, /*  ### # ###       */
+	0x0E, 0x20, /*     ###   #      */
+	0x0A, 0x20, /*     # #   #      */
+	0x12, 0x20, /*    #  #   #      */
+	0x11, 0xC0, /*    #   ###       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @91 '&' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x38, 0x00, /*   ###            */
+	0x64, 0x00, /*  ##  #           */
+	0x60, 0x00, /*  ##              */
+	0x30, 0x00, /*   ##             */
+	0x79, 0x80, /*  ####  ##        */
+	0xDD, 0x80, /* ## ### ##        */
+	0xCF, 0x00, /* ##  ####         */
+	0xC7, 0x00, /* ##   ###         */
+	0x7D, 0x80, /*  ##### ##        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @117 ''' (1 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @130 '(' (4 pixels wide) */
+	0x70, /*  ###     */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x70, /*  ###     */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @143 ')' (4 pixels wide) */
+	0xE0, /* ###      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0xE0, /* ###      */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @156 '*' (5 pixels wide) */
+	0x00, /*          */
+	0x20, /*   #      */
+	0xA8, /* # # #    */
+	0x70, /*  ###     */
+	0x70, /*  ###     */
+	0xA8, /* # # #    */
+	0x20, /*   #      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @169 '+' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0xFE, /* #######  */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @182 ',' (3 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x40, /*  #       */
+	0x80, /* #        */
+	0x00, /*          */
+
+	/* @195 '-' (4 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @208 '.' (2 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @221 '/' (4 pixels wide) */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x30, /*   ##     */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0xC0, /* ##       */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @234 '0' (7 pixels wide) */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x6C, /*  ## ##   */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0x6C, /*  ## ##   */
+	0x38, /*   ###    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @247 '1' (6 pixels wide) */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0xFC, /* ######   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @260 '2' (7 pixels wide) */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x86, /* #    ##  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x0C, /*     ##   */
+	0x18, /*    ##    */
+	0x30, /*   ##     */
+	0x60, /*  ##      */
+	0xFE, /* #######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @273 '3' (7 pixels wide) */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x86, /* #    ##  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x3C, /*   ####   */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x86, /* #    ##  */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @286 '4' (7 pixels wide) */
+	0x00, /*          */
+	0x1C, /*    ###   */
+	0x3C, /*   ####   */
+	0x2C, /*   # ##   */
+	0x4C, /*  #  ##   */
+	0xCC, /* ##  ##   */
+	0x8C, /* #   ##   */
+	0xFE, /* #######  */
+	0x0C, /*     ##   */
+	0x0C, /*     ##   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @299 '5' (7 pixels wide) */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xFC, /* ######   */
+	0x0E, /*     ###  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x0E, /*     ###  */
+	0xFC, /* ######   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @312 '6' (7 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x60, /*  ##      */
+	0xC0, /* ##       */
+	0xFC, /* ######   */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0x46, /*  #   ##  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @325 '7' (7 pixels wide) */
+	0x00, /*          */
+	0xFE, /* #######  */
+	0x06, /*      ##  */
+	0x0C, /*     ##   */
+	0x0C, /*     ##   */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x60, /*  ##      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @338 '8' (7 pixels wide) */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0x38, /*   ###    */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @351 '9' (7 pixels wide) */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0xC4, /* ##   #   */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0x7E, /*  ######  */
+	0x06, /*      ##  */
+	0x0C, /*     ##   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @364 ':' (2 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @377 ';' (3 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x40, /*  #       */
+	0x80, /* #        */
+	0x00, /*          */
+
+	/* @390 '<' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x01, /*        # */
+	0x0F, /*     #### */
+	0x78, /*  ####    */
+	0xC0, /* ##       */
+	0x78, /*  ####    */
+	0x0F, /*     #### */
+	0x01, /*        # */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @403 '=' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xFF, /* ######## */
+	0x00, /*          */
+	0xFF, /* ######## */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @416 '>' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x80, /* #        */
+	0xF0, /* ####     */
+	0x1E, /*    ####  */
+	0x03, /*       ## */
+	0x1E, /*    ####  */
+	0xF0, /* ####     */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @429 '?' (5 pixels wide) */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x30, /*   ##     */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x00, /*          */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @442 '@' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1E, 0x00, /*    ####          */
+	0x21, 0x80, /*   #    ##        */
+	0x40, 0x80, /*  #      #        */
+	0x8E, 0x40, /* #   ###  #       */
+	0x92, 0x40, /* #  #  #  #       */
+	0x92, 0x40, /* #  #  #  #       */
+	0x92, 0xC0, /* #  #  # ##       */
+	0x8F, 0x80, /* #   #####        */
+	0x40, 0x00, /*  #               */
+	0x21, 0x00, /*   #    #         */
+	0x1F, 0x00, /*    #####         */
+	0x00, 0x00, /*                  */
+
+	/* @468 'A' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1C, 0x00, /*    ###           */
+	0x1C, 0x00, /*    ###           */
+	0x36, 0x00, /*   ## ##          */
+	0x36, 0x00, /*   ## ##          */
+	0x36, 0x00, /*   ## ##          */
+	0x63, 0x00, /*  ##   ##         */
+	0x7F, 0x00, /*  #######         */
+	0x63, 0x00, /*  ##   ##         */
+	0xC1, 0x80, /* ##     ##        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @494 'B' (7 pixels wide) */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xFC, /* ######   */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xFC, /* ######   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @507 'C' (7 pixels wide) */
+	0x00, /*          */
+	0x3E, /*   #####  */
+	0x62, /*  ##   #  */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x62, /*  ##   #  */
+	0x3E, /*   #####  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @520 'D' (8 pixels wide) */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0xC6, /* ##   ##  */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC6, /* ##   ##  */
+	0xFC, /* ######   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @533 'E' (6 pixels wide) */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xFC, /* ######   */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xFC, /* ######   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @546 'F' (6 pixels wide) */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xFC, /* ######   */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @559 'G' (8 pixels wide) */
+	0x00, /*          */
+	0x3F, /*   ###### */
+	0x61, /*  ##    # */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC7, /* ##   ### */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0x63, /*  ##   ## */
+	0x3F, /*   ###### */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @572 'H' (8 pixels wide) */
+	0x00, /*          */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xFF, /* ######## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @585 'I' (2 pixels wide) */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @598 'J' (4 pixels wide) */
+	0x00, /*          */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0xE0, /* ###      */
+	0x00, /*          */
+
+	/* @611 'K' (8 pixels wide) */
+	0x00, /*          */
+	0xC3, /* ##    ## */
+	0xC6, /* ##   ##  */
+	0xCC, /* ##  ##   */
+	0xD8, /* ## ##    */
+	0xF0, /* ####     */
+	0xD8, /* ## ##    */
+	0xCC, /* ##  ##   */
+	0xC6, /* ##   ##  */
+	0xC3, /* ##    ## */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @624 'L' (6 pixels wide) */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xFC, /* ######   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @637 'M' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xE1, 0xC0, /* ###    ###       */
+	0xE1, 0xC0, /* ###    ###       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xD2, 0xC0, /* ## #  # ##       */
+	0xDE, 0xC0, /* ## #### ##       */
+	0xCC, 0xC0, /* ##  ##  ##       */
+	0xCC, 0xC0, /* ##  ##  ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @663 'N' (8 pixels wide) */
+	0x00, /*          */
+	0xE3, /* ###   ## */
+	0xE3, /* ###   ## */
+	0xF3, /* ####  ## */
+	0xD3, /* ## #  ## */
+	0xDB, /* ## ## ## */
+	0xCB, /* ##  # ## */
+	0xCF, /* ##  #### */
+	0xC7, /* ##   ### */
+	0xC7, /* ##   ### */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @676 'O' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x3E, 0x00, /*   #####          */
+	0x63, 0x00, /*  ##   ##         */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0x63, 0x00, /*  ##   ##         */
+	0x3E, 0x00, /*   #####          */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @702 'P' (7 pixels wide) */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xFC, /* ######   */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @715 'Q' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x3E, 0x00, /*   #####          */
+	0x63, 0x00, /*  ##   ##         */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0x63, 0x00, /*  ##   ##         */
+	0x3E, 0x00, /*   #####          */
+	0x06, 0x00, /*      ##          */
+	0x03, 0x00, /*       ##         */
+	0x00, 0x00, /*                  */
+
+	/* @741 'R' (8 pixels wide) */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xFC, /* ######   */
+	0xCC, /* ##  ##   */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC3, /* ##    ## */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @754 'S' (7 pixels wide) */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0xC4, /* ##   #   */
+	0xC0, /* ##       */
+	0xF0, /* ####     */
+	0x7C, /*  #####   */
+	0x0E, /*     ###  */
+	0x06, /*      ##  */
+	0x86, /* #    ##  */
+	0xFC, /* ######   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @767 'T' (8 pixels wide) */
+	0x00, /*          */
+	0xFF, /* ######## */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @780 'U' (8 pixels wide) */
+	0x00, /*          */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0x7E, /*  ######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @793 'V' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xC1, 0x80, /* ##     ##        */
+	0x63, 0x00, /*  ##   ##         */
+	0x63, 0x00, /*  ##   ##         */
+	0x63, 0x00, /*  ##   ##         */
+	0x36, 0x00, /*   ## ##          */
+	0x36, 0x00, /*   ## ##          */
+	0x36, 0x00, /*   ## ##          */
+	0x1C, 0x00, /*    ###           */
+	0x1C, 0x00, /*    ###           */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @819 'W' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xC6, 0x30, /* ##   ##   ##     */
+	0xC6, 0x30, /* ##   ##   ##     */
+	0x6F, 0x60, /*  ## #### ##      */
+	0x6F, 0x60, /*  ## #### ##      */
+	0x69, 0x60, /*  ## #  # ##      */
+	0x79, 0xE0, /*  ####  ####      */
+	0x39, 0xC0, /*   ###  ###       */
+	0x30, 0xC0, /*   ##    ##       */
+	0x30, 0xC0, /*   ##    ##       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @845 'X' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xC1, 0x80, /* ##     ##        */
+	0x63, 0x00, /*  ##   ##         */
+	0x36, 0x00, /*   ## ##          */
+	0x36, 0x00, /*   ## ##          */
+	0x1C, 0x00, /*    ###           */
+	0x36, 0x00, /*   ## ##          */
+	0x36, 0x00, /*   ## ##          */
+	0x63, 0x00, /*  ##   ##         */
+	0xC1, 0x80, /* ##     ##        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @871 'Y' (8 pixels wide) */
+	0x00, /*          */
+	0xC3, /* ##    ## */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x3C, /*   ####   */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @884 'Z' (8 pixels wide) */
+	0x00, /*          */
+	0xFF, /* ######## */
+	0x03, /*       ## */
+	0x06, /*      ##  */
+	0x0C, /*     ##   */
+	0x18, /*    ##    */
+	0x30, /*   ##     */
+	0x60, /*  ##      */
+	0xC0, /* ##       */
+	0xFF, /* ######## */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @897 '[' (4 pixels wide) */
+	0xF0, /* ####     */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @910 '\' (4 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0xC0, /* ##       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x30, /*   ##     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @923 ']' (4 pixels wide) */
+	0xF0, /* ####     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @936 '^' (6 pixels wide) */
+	0x00, /*          */
+	0x30, /*   ##     */
+	0x78, /*  ####    */
+	0x84, /* #    #   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @949 '_' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xFC, /* ######   */
+
+	/* @962 '`' (3 pixels wide) */
+	0xC0, /* ##       */
+	0x60, /*  ##      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @975 'a' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x46, /*  #   ##  */
+	0x06, /*      ##  */
+	0x7E, /*  ######  */
+	0xC6, /* ##   ##  */
+	0xCE, /* ##  ###  */
+	0x7E, /*  ######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @988 'b' (7 pixels wide) */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xFC, /* ######   */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xFC, /* ######   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1001 'c' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x64, /*  ##  #   */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x64, /*  ##  #   */
+	0x38, /*   ###    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1014 'd' (7 pixels wide) */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x7E, /*  ######  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0x7E, /*  ######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1027 'e' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x64, /*  ##  #   */
+	0xC6, /* ##   ##  */
+	0xFE, /* #######  */
+	0xC0, /* ##       */
+	0x62, /*  ##   #  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1040 'f' (5 pixels wide) */
+	0x38, /*   ###    */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0xF8, /* #####    */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1053 'g' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x7E, /*  ######  */
+	0xE6, /* ###  ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0x7E, /*  ######  */
+	0x06, /*      ##  */
+	0x46, /*  #   ##  */
+	0x3C, /*   ####   */
+
+	/* @1066 'h' (7 pixels wide) */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xFC, /* ######   */
+	0xE6, /* ###  ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1079 'i' (2 pixels wide) */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1092 'j' (3 pixels wide) */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x00, /*          */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0xC0, /* ##       */
+
+	/* @1105 'k' (7 pixels wide) */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xCC, /* ##  ##   */
+	0xD8, /* ## ##    */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xD8, /* ## ##    */
+	0xCC, /* ##  ##   */
+	0xC6, /* ##   ##  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1118 'l' (2 pixels wide) */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1131 'm' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xFF, 0x80, /* #########        */
+	0xCC, 0xC0, /* ##  ##  ##       */
+	0xCC, 0xC0, /* ##  ##  ##       */
+	0xCC, 0xC0, /* ##  ##  ##       */
+	0xCC, 0xC0, /* ##  ##  ##       */
+	0xCC, 0xC0, /* ##  ##  ##       */
+	0xCC, 0xC0, /* ##  ##  ##       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1157 'n' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0xE6, /* ###  ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1170 'o' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1183 'p' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xFC, /* ######   */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+
+	/* @1196 'q' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x7E, /*  ######  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0x7E, /*  ######  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+
+	/* @1209 'r' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xF8, /* #####    */
+	0xE0, /* ###      */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1222 's' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0xC4, /* ##   #   */
+	0xC0, /* ##       */
+	0x78, /*  ####    */
+	0x0C, /*     ##   */
+	0x8C, /* #   ##   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1235 't' (5 pixels wide) */
+	0x00, /*          */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0xF8, /* #####    */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1248 'u' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xCE, /* ##  ###  */
+	0x7E, /*  ######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1261 'v' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0x6C, /*  ## ##   */
+	0x6C, /*  ## ##   */
+	0x6C, /*  ## ##   */
+	0x38, /*   ###    */
+	0x38, /*   ###    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1274 'w' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xCC, 0xC0, /* ##  ##  ##       */
+	0xCC, 0xC0, /* ##  ##  ##       */
+	0xDE, 0xC0, /* ## #### ##       */
+	0x5E, 0x80, /*  # #### #        */
+	0x73, 0x80, /*  ###  ###        */
+	0x73, 0x80, /*  ###  ###        */
+	0x33, 0x00, /*   ##  ##         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1300 'x' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xC6, /* ##   ##  */
+	0x6C, /*  ## ##   */
+	0x38, /*   ###    */
+	0x38, /*   ###    */
+	0x38, /*   ###    */
+	0x6C, /*  ## ##   */
+	0xC6, /* ##   ##  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1313 'y' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0x6C, /*  ## ##   */
+	0x6C, /*  ## ##   */
+	0x3C, /*   ####   */
+	0x38, /*   ###    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x30, /*   ##     */
+	0x60, /*  ##      */
+
+	/* @1326 'z' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0x0C, /*     ##   */
+	0x18, /*    ##    */
+	0x30, /*   ##     */
+	0x60, /*  ##      */
+	0xC0, /* ##       */
+	0xFC, /* ######   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1339 '{' (6 pixels wide) */
+	0x1C, /*    ###   */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0xE0, /* ###      */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x1C, /*    ###   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1352 '|' (1 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+
+	/* @1365 '}' (6 pixels wide) */
+	0xE0, /* ###      */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x1C, /*    ###   */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0xE0, /* ###      */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1378 '~' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x71, /*  ###   # */
+	0x8E, /* #   ###  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+};
+
+/* Character descriptors for DejaVu Sans Bold 9pt */
+/* { [Char width in bits], [Offset into dejaVuSans9ptCharBitmaps in bytes] } */
+const FONT_CHAR_INFO dejaVuSansBold9ptDescriptors[] = 
+{
+	{5, 0}, 		/*   */ 
+	{2, 13}, 		/* ! */ 
+	{3, 26}, 		/* " */ 
+	{8, 39}, 		/* # */ 
+	{7, 52}, 		/* $ */ 
+	{11, 65}, 		/* % */ 
+	{9, 91}, 		/* & */ 
+	{1, 117}, 		/* ' */ 
+	{4, 130}, 		/* ( */ 
+	{4, 143}, 		/* ) */ 
+	{5, 156}, 		/* * */ 
+	{7, 169}, 		/* + */ 
+	{3, 182}, 		/* , */ 
+	{4, 195}, 		/* - */ 
+	{2, 208}, 		/* . */ 
+	{4, 221}, 		/* / */ 
+	{7, 234}, 		/* 0 */ 
+	{6, 247}, 		/* 1 */ 
+	{7, 260}, 		/* 2 */ 
+	{7, 273}, 		/* 3 */ 
+	{7, 286}, 		/* 4 */ 
+	{7, 299}, 		/* 5 */ 
+	{7, 312}, 		/* 6 */ 
+	{7, 325}, 		/* 7 */ 
+	{7, 338}, 		/* 8 */ 
+	{7, 351}, 		/* 9 */ 
+	{2, 364}, 		/* : */ 
+	{3, 377}, 		/* ; */ 
+	{8, 390}, 		/* < */ 
+	{8, 403}, 		/* = */ 
+	{8, 416}, 		/* > */ 
+	{5, 429}, 		/* ? */ 
+	{10, 442}, 		/* @ */ 
+	{9, 468}, 		/* A */ 
+	{7, 494}, 		/* B */ 
+	{7, 507}, 		/* C */ 
+	{8, 520}, 		/* D */ 
+	{6, 533}, 		/* E */ 
+	{6, 546}, 		/* F */ 
+	{8, 559}, 		/* G */ 
+	{8, 572}, 		/* H */ 
+	{2, 585}, 		/* I */ 
+	{4, 598}, 		/* J */ 
+	{8, 611}, 		/* K */ 
+	{6, 624}, 		/* L */ 
+	{10, 637}, 		/* M */ 
+	{8, 663}, 		/* N */ 
+	{9, 676}, 		/* O */ 
+	{7, 702}, 		/* P */ 
+	{9, 715}, 		/* Q */ 
+	{8, 741}, 		/* R */ 
+	{7, 754}, 		/* S */ 
+	{8, 767}, 		/* T */ 
+	{8, 780}, 		/* U */ 
+	{9, 793}, 		/* V */ 
+	{12, 819}, 		/* W */ 
+	{9, 845}, 		/* X */ 
+	{8, 871}, 		/* Y */ 
+	{8, 884}, 		/* Z */ 
+	{4, 897}, 		/* [ */ 
+	{4, 910}, 		/* \ */ 
+	{4, 923}, 		/* ] */ 
+	{6, 936}, 		/* ^ */ 
+	{6, 949}, 		/* _ */ 
+	{3, 962}, 		/* ` */ 
+	{7, 975}, 		/* a */ 
+	{7, 988}, 		/* b */ 
+	{6, 1001}, 		/* c */ 
+	{7, 1014}, 		/* d */ 
+	{7, 1027}, 		/* e */ 
+	{5, 1040}, 		/* f */ 
+	{7, 1053}, 		/* g */ 
+	{7, 1066}, 		/* h */ 
+	{2, 1079}, 		/* i */ 
+	{3, 1092}, 		/* j */ 
+	{7, 1105}, 		/* k */ 
+	{2, 1118}, 		/* l */ 
+	{10, 1131}, 		/* m */ 
+	{7, 1157}, 		/* n */ 
+	{7, 1170}, 		/* o */ 
+	{7, 1183}, 		/* p */ 
+	{7, 1196}, 		/* q */ 
+	{5, 1209}, 		/* r */ 
+	{6, 1222}, 		/* s */ 
+	{5, 1235}, 		/* t */ 
+	{7, 1248}, 		/* u */ 
+	{7, 1261}, 		/* v */ 
+	{10, 1274}, 		/* w */ 
+	{7, 1300}, 		/* x */ 
+	{7, 1313}, 		/* y */ 
+	{6, 1326}, 		/* z */ 
+	{6, 1339}, 		/* { */ 
+	{1, 1352}, 		/* | */ 
+	{6, 1365}, 		/* } */ 
+	{8, 1378}, 		/* ~ */ 
+};
+
+/* Font information for DejaVu Sans Bold 9pt */
+const FONT_INFO dejaVuSansBold9ptFontInfo =
+{
+	13, /*  Character height */
+	' ', /*  Start character */
+	'~', /*  End character */
+	dejaVuSansBold9ptDescriptors, /*  Character descriptor array */
+	dejaVuSansBold9ptBitmaps, /*  Character bitmap array */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusansbold9.h b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusansbold9.h
new file mode 100644
index 0000000000000000000000000000000000000000..fdc3dbc0015e959164c2a35c2dfcbdf48c00b673
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusansbold9.h
@@ -0,0 +1,18 @@
+#ifndef __DEJA_VU_SANS_BOLD_9__
+#define __DEJA_VU_SANS_BOLD_9__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../fonts.h"
+
+extern const uint8_t dejaVuSansBold9ptCharBitmaps[];
+extern const FONT_CHAR_INFO dejaVuSansBold9ptCharDescriptors[];
+extern const FONT_INFO dejaVuSansBold9ptFontInfo;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusanscondensed9.c b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusanscondensed9.c
new file mode 100644
index 0000000000000000000000000000000000000000..1f2b834fe163485ab81db5ca3dda98e703ffb6b9
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusanscondensed9.c
@@ -0,0 +1,1545 @@
+#include "dejavusanscondensed9.h"
+
+/* 
+**  Font data for DejaVu Sans Condensed 9pt
+*/
+
+/* Character bitmaps for DejaVu Sans Condensed 9pt */
+const uint8_t dejaVuSansCondensed9ptBitmaps[] = 
+{
+	/* @0 ' ' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @13 '!' (1 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @26 '"' (3 pixels wide) */
+	0x00, /*          */
+	0xA0, /* # #      */
+	0xA0, /* # #      */
+	0xA0, /* # #      */
+	0xA0, /* # #      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @39 '#' (7 pixels wide) */
+	0x00, /*          */
+	0x14, /*    # #   */
+	0x24, /*   #  #   */
+	0x24, /*   #  #   */
+	0xFE, /* #######  */
+	0x28, /*   # #    */
+	0x28, /*   # #    */
+	0xFE, /* #######  */
+	0x48, /*  #  #    */
+	0x50, /*  # #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @52 '$' (5 pixels wide) */
+	0x00, /*          */
+	0x20, /*   #      */
+	0x70, /*  ###     */
+	0xA8, /* # # #    */
+	0xA0, /* # #      */
+	0xE0, /* ###      */
+	0x38, /*   ###    */
+	0x28, /*   # #    */
+	0x28, /*   # #    */
+	0xF0, /* ####     */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x00, /*          */
+
+	/* @65 '%' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xE2, 0x00, /* ###   #          */
+	0xA4, 0x00, /* # #  #           */
+	0xA4, 0x00, /* # #  #           */
+	0xA8, 0x00, /* # # #            */
+	0xCA, 0x00, /* ##  # #          */
+	0x15, 0x00, /*    # # #         */
+	0x14, 0x80, /*    # #  #        */
+	0x24, 0x80, /*   #  #  #        */
+	0x43, 0x00, /*  #    ##         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @91 '&' (7 pixels wide) */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0xA2, /* # #   #  */
+	0x94, /* #  # #   */
+	0x8C, /* #   ##   */
+	0x8C, /* #   ##   */
+	0x7E, /*  ######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @104 ''' (1 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @117 '(' (2 pixels wide) */
+	0x00, /*          */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x00, /*          */
+
+	/* @130 ')' (2 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+
+	/* @143 '*' (5 pixels wide) */
+	0x00, /*          */
+	0x20, /*   #      */
+	0xA8, /* # # #    */
+	0x70, /*  ###     */
+	0x70, /*  ###     */
+	0x28, /*   # #    */
+	0x20, /*   #      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @156 '+' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0xFE, /* #######  */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @169 ',' (1 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @182 '-' (2 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @195 '.' (1 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @208 '/' (4 pixels wide) */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @221 '0' (5 pixels wide) */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0x98, /* #  ##    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x70, /*  ###     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @234 '1' (5 pixels wide) */
+	0x00, /*          */
+	0x60, /*  ##      */
+	0xA0, /* # #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @247 '2' (5 pixels wide) */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0x98, /* #  ##    */
+	0x08, /*     #    */
+	0x18, /*    ##    */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0xC0, /* ##       */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @260 '3' (5 pixels wide) */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0x18, /*    ##    */
+	0x08, /*     #    */
+	0x18, /*    ##    */
+	0x70, /*  ###     */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @273 '4' (5 pixels wide) */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x30, /*   ##     */
+	0x50, /*  # #     */
+	0x50, /*  # #     */
+	0x90, /* #  #     */
+	0x90, /* #  #     */
+	0xF8, /* #####    */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @286 '5' (5 pixels wide) */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xE0, /* ###      */
+	0x18, /*    ##    */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0x18, /*    ##    */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @299 '6' (5 pixels wide) */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x40, /*  #       */
+	0x80, /* #        */
+	0xB0, /* # ##     */
+	0xC8, /* ##  #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x70, /*  ###     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @312 '7' (5 pixels wide) */
+	0x00, /*          */
+	0xF8, /* #####    */
+	0x08, /*     #    */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @325 '8' (5 pixels wide) */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x70, /*  ###     */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @338 '9' (5 pixels wide) */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0x98, /* #  ##    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x98, /* #  ##    */
+	0x78, /*  ####    */
+	0x08, /*     #    */
+	0x18, /*    ##    */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @351 ':' (1 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @364 ';' (1 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @377 '<' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x02, /*       #  */
+	0x1C, /*    ###   */
+	0x60, /*  ##      */
+	0xC0, /* ##       */
+	0x38, /*   ###    */
+	0x06, /*      ##  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @390 '=' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xFE, /* #######  */
+	0x00, /*          */
+	0xFE, /* #######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @403 '>' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x80, /* #        */
+	0x70, /*  ###     */
+	0x0C, /*     ##   */
+	0x06, /*      ##  */
+	0x38, /*   ###    */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @416 '?' (4 pixels wide) */
+	0x00, /*          */
+	0xE0, /* ###      */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x60, /*  ##      */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x00, /*          */
+	0x40, /*  #       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @429 '@' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x3E, 0x00, /*   #####          */
+	0x41, 0x00, /*  #     #         */
+	0x9A, 0x80, /* #  ## # #        */
+	0xA6, 0x80, /* # #  ## #        */
+	0xA2, 0x80, /* # #   # #        */
+	0xA2, 0x80, /* # #   # #        */
+	0x97, 0x00, /* #  # ###         */
+	0x88, 0x00, /* #   #            */
+	0x40, 0x00, /*  #               */
+	0x3E, 0x00, /*   #####          */
+	0x00, 0x00, /*                  */
+
+	/* @455 'A' (7 pixels wide) */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x18, /*    ##    */
+	0x28, /*   # #    */
+	0x28, /*   # #    */
+	0x24, /*   #  #   */
+	0x44, /*  #   #   */
+	0x7C, /*  #####   */
+	0x42, /*  #    #  */
+	0x82, /* #     #  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @468 'B' (6 pixels wide) */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0xF8, /* #####    */
+	0x88, /* #   #    */
+	0x84, /* #    #   */
+	0x88, /* #   #    */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @481 'C' (6 pixels wide) */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0xC4, /* ##   #   */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xC0, /* ##       */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @494 'D' (7 pixels wide) */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0x8C, /* #   ##   */
+	0x84, /* #    #   */
+	0x86, /* #    ##  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x84, /* #    #   */
+	0x8C, /* #   ##   */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @507 'E' (5 pixels wide) */
+	0x00, /*          */
+	0xF8, /* #####    */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xF8, /* #####    */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @520 'F' (5 pixels wide) */
+	0x00, /*          */
+	0xF8, /* #####    */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xF0, /* ####     */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @533 'G' (6 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0xC4, /* ##   #   */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x8C, /* #   ##   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0xC4, /* ##   #   */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @546 'H' (6 pixels wide) */
+	0x00, /*          */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0xFC, /* ######   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @559 'I' (1 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @572 'J' (3 pixels wide) */
+	0x00, /*          */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0xE0, /* ###      */
+	0x00, /*          */
+
+	/* @585 'K' (6 pixels wide) */
+	0x00, /*          */
+	0x8C, /* #   ##   */
+	0x98, /* #  ##    */
+	0x90, /* #  #     */
+	0xA0, /* # #      */
+	0xC0, /* ##       */
+	0xA0, /* # #      */
+	0x90, /* #  #     */
+	0x88, /* #   #    */
+	0x8C, /* #   ##   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @598 'L' (5 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @611 'M' (7 pixels wide) */
+	0x00, /*          */
+	0xC2, /* ##    #  */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xAA, /* # # # #  */
+	0xAA, /* # # # #  */
+	0xAA, /* # # # #  */
+	0x92, /* #  #  #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @624 'N' (6 pixels wide) */
+	0x00, /*          */
+	0xC4, /* ##   #   */
+	0xC4, /* ##   #   */
+	0xE4, /* ###  #   */
+	0xA4, /* # #  #   */
+	0xB4, /* # ## #   */
+	0x94, /* #  # #   */
+	0x94, /* #  # #   */
+	0x8C, /* #   ##   */
+	0x8C, /* #   ##   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @637 'O' (7 pixels wide) */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0xC4, /* ##   #   */
+	0x86, /* #    ##  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x86, /* #    ##  */
+	0xC4, /* ##   #   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @650 'P' (5 pixels wide) */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0x98, /* #  ##    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x98, /* #  ##    */
+	0xE0, /* ###      */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @663 'Q' (7 pixels wide) */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0xC4, /* ##   #   */
+	0x86, /* #    ##  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x86, /* #    ##  */
+	0xC4, /* ##   #   */
+	0x78, /*  ####    */
+	0x08, /*     #    */
+	0x04, /*      #   */
+	0x00, /*          */
+
+	/* @676 'R' (6 pixels wide) */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0x98, /* #  ##    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0xF0, /* ####     */
+	0x98, /* #  ##    */
+	0x88, /* #   #    */
+	0x8C, /* #   ##   */
+	0x84, /* #    #   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @689 'S' (5 pixels wide) */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x88, /* #   #    */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x70, /*  ###     */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @702 'T' (7 pixels wide) */
+	0x00, /*          */
+	0xFE, /* #######  */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @715 'U' (6 pixels wide) */
+	0x00, /*          */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x8C, /* #   ##   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @728 'V' (7 pixels wide) */
+	0x00, /*          */
+	0x82, /* #     #  */
+	0x42, /*  #    #  */
+	0x46, /*  #   ##  */
+	0x44, /*  #   #   */
+	0x24, /*   #  #   */
+	0x28, /*   # #    */
+	0x28, /*   # #    */
+	0x18, /*    ##    */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @741 'W' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x84, 0x40, /* #    #   #       */
+	0x4C, 0x40, /*  #  ##   #       */
+	0x4C, 0x40, /*  #  ##   #       */
+	0x4A, 0x40, /*  #  # #  #       */
+	0x4A, 0x80, /*  #  # # #        */
+	0x32, 0x80, /*   ##  # #        */
+	0x32, 0x80, /*   ##  # #        */
+	0x31, 0x80, /*   ##   ##        */
+	0x31, 0x00, /*   ##   #         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @767 'X' (6 pixels wide) */
+	0x00, /*          */
+	0x84, /* #    #   */
+	0xC8, /* ##  #    */
+	0x58, /*  # ##    */
+	0x30, /*   ##     */
+	0x20, /*   #      */
+	0x70, /*  ###     */
+	0x58, /*  # ##    */
+	0x88, /* #   #    */
+	0x84, /* #    #   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @780 'Y' (6 pixels wide) */
+	0x00, /*          */
+	0x84, /* #    #   */
+	0x44, /*  #   #   */
+	0x48, /*  #  #    */
+	0x28, /*   # #    */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @793 'Z' (7 pixels wide) */
+	0x00, /*          */
+	0x7E, /*  ######  */
+	0x06, /*      ##  */
+	0x04, /*      #   */
+	0x08, /*     #    */
+	0x10, /*    #     */
+	0x30, /*   ##     */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0xFE, /* #######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @806 '[' (2 pixels wide) */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xC0, /* ##       */
+	0x00, /*          */
+
+	/* @819 '\' (3 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @832 ']' (2 pixels wide) */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0xC0, /* ##       */
+	0x00, /*          */
+
+	/* @845 '^' (7 pixels wide) */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x28, /*   # #    */
+	0x44, /*  #   #   */
+	0x82, /* #     #  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @858 '_' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xFC, /* ######   */
+
+	/* @871 '`' (2 pixels wide) */
+	0x80, /* #        */
+	0x40, /*  #       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @884 'a' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x60, /*  ##      */
+	0x90, /* #  #     */
+	0x08, /*     #    */
+	0xF8, /* #####    */
+	0x88, /* #   #    */
+	0x98, /* #  ##    */
+	0xE8, /* ### #    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @897 'b' (5 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xB0, /* # ##     */
+	0xC8, /* ##  #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @910 'c' (4 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0xC0, /* ##       */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x70, /*  ###     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @923 'd' (5 pixels wide) */
+	0x00, /*          */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0x68, /*  ## #    */
+	0x98, /* #  ##    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @936 'e' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0x98, /* #  ##    */
+	0x88, /* #   #    */
+	0xF8, /* #####    */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @949 'f' (4 pixels wide) */
+	0x00, /*          */
+	0x30, /*   ##     */
+	0x40, /*  #       */
+	0xF0, /* ####     */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @962 'g' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x68, /*  ## #    */
+	0x98, /* #  ##    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x98, /* #  ##    */
+	0x68, /*  ## #    */
+	0x08, /*     #    */
+	0x90, /* #  #     */
+	0x60, /*  ##      */
+
+	/* @975 'h' (5 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xB0, /* # ##     */
+	0xD8, /* ## ##    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @988 'i' (1 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1001 'j' (2 pixels wide) */
+	0x00, /*          */
+	0x40, /*  #       */
+	0x00, /*          */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x80, /* #        */
+
+	/* @1014 'k' (5 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x88, /* #   #    */
+	0x90, /* #  #     */
+	0xA0, /* # #      */
+	0xC0, /* ##       */
+	0xA0, /* # #      */
+	0x90, /* #  #     */
+	0x98, /* #  ##    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1027 'l' (1 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1040 'm' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xB3, 0x00, /* # ##  ##         */
+	0xDD, 0x00, /* ## ### #         */
+	0x88, 0x80, /* #   #   #        */
+	0x88, 0x80, /* #   #   #        */
+	0x88, 0x80, /* #   #   #        */
+	0x88, 0x80, /* #   #   #        */
+	0x88, 0x80, /* #   #   #        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1066 'n' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xB0, /* # ##     */
+	0xD8, /* ## ##    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1079 'o' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x60, /*  ##      */
+	0x98, /* #  ##    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x70, /*  ###     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1092 'p' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xB0, /* # ##     */
+	0xC8, /* ##  #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0xF0, /* ####     */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+
+	/* @1105 'q' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x68, /*  ## #    */
+	0x98, /* #  ##    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0xF8, /* #####    */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0x08, /*     #    */
+
+	/* @1118 'r' (3 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xA0, /* # #      */
+	0xC0, /* ##       */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1131 's' (4 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x60, /*  ##      */
+	0x90, /* #  #     */
+	0x80, /* #        */
+	0xE0, /* ###      */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1144 't' (4 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x40, /*  #       */
+	0xF0, /* ####     */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x70, /*  ###     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1157 'u' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1170 'v' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x84, /* #    #   */
+	0x44, /*  #   #   */
+	0x48, /*  #  #    */
+	0x48, /*  #  #    */
+	0x28, /*   # #    */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1183 'w' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x89, /* #   #  # */
+	0x49, /*  #  #  # */
+	0x59, /*  # ##  # */
+	0x55, /*  # # # # */
+	0x56, /*  # # ##  */
+	0x26, /*   #  ##  */
+	0x22, /*   #   #  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1196 'x' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x88, /* #   #    */
+	0x90, /* #  #     */
+	0x70, /*  ###     */
+	0x20, /*   #      */
+	0x60, /*  ##      */
+	0x90, /* #  #     */
+	0x88, /* #   #    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1209 'y' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x84, /* #    #   */
+	0x44, /*  #   #   */
+	0x48, /*  #  #    */
+	0x48, /*  #  #    */
+	0x28, /*   # #    */
+	0x30, /*   ##     */
+	0x10, /*    #     */
+	0x30, /*   ##     */
+	0x20, /*   #      */
+	0x40, /*  #       */
+
+	/* @1222 'z' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x08, /*     #    */
+	0x10, /*    #     */
+	0x30, /*   ##     */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1235 '{' (5 pixels wide) */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0xC0, /* ##       */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x38, /*   ###    */
+	0x00, /*          */
+
+	/* @1248 '|' (1 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+
+	/* @1261 '}' (5 pixels wide) */
+	0x00, /*          */
+	0xE0, /* ###      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x18, /*    ##    */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0xC0, /* ##       */
+	0x00, /*          */
+
+	/* @1274 '~' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x60, /*  ##      */
+	0x9E, /* #  ####  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+};
+
+/* Character descriptors for DejaVu Sans Condensed 9pt */
+/* { [Char width in bits], [Offset into dejaVuSansCondensed9ptCharBitmaps in bytes] } */
+const FONT_CHAR_INFO dejaVuSansCondensed9ptDescriptors[] = 
+{
+	{5, 0}, 		/*   */ 
+	{1, 13}, 		/* ! */ 
+	{3, 26}, 		/* " */ 
+	{7, 39}, 		/* # */ 
+	{5, 52}, 		/* $ */ 
+	{9, 65}, 		/* % */ 
+	{7, 91}, 		/* & */ 
+	{1, 104}, 		/* ' */ 
+	{2, 117}, 		/* ( */ 
+	{2, 130}, 		/* ) */ 
+	{5, 143}, 		/* * */ 
+	{7, 156}, 		/* + */ 
+	{1, 169}, 		/* , */ 
+	{2, 182}, 		/* - */ 
+	{1, 195}, 		/* . */ 
+	{4, 208}, 		/* / */ 
+	{5, 221}, 		/* 0 */ 
+	{5, 234}, 		/* 1 */ 
+	{5, 247}, 		/* 2 */ 
+	{5, 260}, 		/* 3 */ 
+	{5, 273}, 		/* 4 */ 
+	{5, 286}, 		/* 5 */ 
+	{5, 299}, 		/* 6 */ 
+	{5, 312}, 		/* 7 */ 
+	{5, 325}, 		/* 8 */ 
+	{5, 338}, 		/* 9 */ 
+	{1, 351}, 		/* : */ 
+	{1, 364}, 		/* ; */ 
+	{7, 377}, 		/* < */ 
+	{7, 390}, 		/* = */ 
+	{7, 403}, 		/* > */ 
+	{4, 416}, 		/* ? */ 
+	{9, 429}, 		/* @ */ 
+	{7, 455}, 		/* A */ 
+	{6, 468}, 		/* B */ 
+	{6, 481}, 		/* C */ 
+	{7, 494}, 		/* D */ 
+	{5, 507}, 		/* E */ 
+	{5, 520}, 		/* F */ 
+	{6, 533}, 		/* G */ 
+	{6, 546}, 		/* H */ 
+	{1, 559}, 		/* I */ 
+	{3, 572}, 		/* J */ 
+	{6, 585}, 		/* K */ 
+	{5, 598}, 		/* L */ 
+	{7, 611}, 		/* M */ 
+	{6, 624}, 		/* N */ 
+	{7, 637}, 		/* O */ 
+	{5, 650}, 		/* P */ 
+	{7, 663}, 		/* Q */ 
+	{6, 676}, 		/* R */ 
+	{5, 689}, 		/* S */ 
+	{7, 702}, 		/* T */ 
+	{6, 715}, 		/* U */ 
+	{7, 728}, 		/* V */ 
+	{10, 741}, 		/* W */ 
+	{6, 767}, 		/* X */ 
+	{6, 780}, 		/* Y */ 
+	{7, 793}, 		/* Z */ 
+	{2, 806}, 		/* [ */ 
+	{3, 819}, 		/* \ */ 
+	{2, 832}, 		/* ] */ 
+	{7, 845}, 		/* ^ */ 
+	{6, 858}, 		/* _ */ 
+	{2, 871}, 		/* ` */ 
+	{5, 884}, 		/* a */ 
+	{5, 897}, 		/* b */ 
+	{4, 910}, 		/* c */ 
+	{5, 923}, 		/* d */ 
+	{5, 936}, 		/* e */ 
+	{4, 949}, 		/* f */ 
+	{5, 962}, 		/* g */ 
+	{5, 975}, 		/* h */ 
+	{1, 988}, 		/* i */ 
+	{2, 1001}, 		/* j */ 
+	{5, 1014}, 		/* k */ 
+	{1, 1027}, 		/* l */ 
+	{9, 1040}, 		/* m */ 
+	{5, 1066}, 		/* n */ 
+	{5, 1079}, 		/* o */ 
+	{5, 1092}, 		/* p */ 
+	{5, 1105}, 		/* q */ 
+	{3, 1118}, 		/* r */ 
+	{4, 1131}, 		/* s */ 
+	{4, 1144}, 		/* t */ 
+	{5, 1157}, 		/* u */ 
+	{6, 1170}, 		/* v */ 
+	{8, 1183}, 		/* w */ 
+	{5, 1196}, 		/* x */ 
+	{6, 1209}, 		/* y */ 
+	{5, 1222}, 		/* z */ 
+	{5, 1235}, 		/* { */ 
+	{1, 1248}, 		/* | */ 
+	{5, 1261}, 		/* } */ 
+	{7, 1274}, 		/* ~ */ 
+};
+
+/* Font information for DejaVu Sans Condensed 9pt */
+const FONT_INFO dejaVuSansCondensed9ptFontInfo =
+{
+	13, /*  Character height */
+	' ', /*  Start character */
+	'~', /*  End character */
+	dejaVuSansCondensed9ptDescriptors, /*  Character descriptor array */
+	dejaVuSansCondensed9ptBitmaps, /*  Character bitmap array */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusanscondensed9.h b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusanscondensed9.h
new file mode 100644
index 0000000000000000000000000000000000000000..b6753641b6cf9851ab0e219f568b271d8a31e3e5
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusanscondensed9.h
@@ -0,0 +1,18 @@
+#ifndef __DEJA_VU_SANS_CONDENSED_9__
+#define __DEJA_VU_SANS_CONDENSED_9__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../fonts.h"
+
+extern const uint8_t dejaVuSansCondensed9ptCharBitmaps[];
+extern const FONT_CHAR_INFO dejaVuSansCondensed9ptCharDescriptors[];
+extern const FONT_INFO dejaVuSansCondensed9ptFontInfo;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusansmono8.c b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusansmono8.c
new file mode 100644
index 0000000000000000000000000000000000000000..13dccb99b531bc10f2c89e2395dbda3553a56392
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusansmono8.c
@@ -0,0 +1,1450 @@
+#include "dejavusansmono8.h"
+
+/* 
+**  Font data for DejaVu Sans Mono 8pt
+*/
+
+/* Character bitmaps for DejaVu Sans Mono 8pt */
+const uint8_t dejaVuSansMono8ptBitmaps[] = 
+{
+	/* @0 ' ' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @12 '!' (8 pixels wide) */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @24 '"' (8 pixels wide) */
+	0x00, /*          */
+	0x28, /*   # #    */
+	0x28, /*   # #    */
+	0x28, /*   # #    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @36 '#' (8 pixels wide) */
+	0x00, /*          */
+	0x14, /*    # #   */
+	0x24, /*   #  #   */
+	0x7E, /*  ######  */
+	0x28, /*   # #    */
+	0x28, /*   # #    */
+	0xFC, /* ######   */
+	0x48, /*  #  #    */
+	0x50, /*  # #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @48 '$' (8 pixels wide) */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x3C, /*   ####   */
+	0x50, /*  # #     */
+	0x50, /*  # #     */
+	0x38, /*   ###    */
+	0x14, /*    # #   */
+	0x14, /*    # #   */
+	0x78, /*  ####    */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+
+	/* @60 '%' (8 pixels wide) */
+	0x00, /*          */
+	0xE0, /* ###      */
+	0xA0, /* # #      */
+	0xE4, /* ###  #   */
+	0x18, /*    ##    */
+	0x20, /*   #      */
+	0xDC, /* ## ###   */
+	0x14, /*    # #   */
+	0x1C, /*    ###   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @72 '&' (8 pixels wide) */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x30, /*   ##     */
+	0x5A, /*  # ## #  */
+	0x4A, /*  #  # #  */
+	0x44, /*  #   #   */
+	0x3E, /*   #####  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @84 ''' (8 pixels wide) */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @96 '(' (8 pixels wide) */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @108 ')' (8 pixels wide) */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @120 '*' (8 pixels wide) */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x54, /*  # # #   */
+	0x38, /*   ###    */
+	0x38, /*   ###    */
+	0x54, /*  # # #   */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @132 '+' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x7C, /*  #####   */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @144 ',' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @156 '-' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @168 '.' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @180 '/' (8 pixels wide) */
+	0x00, /*          */
+	0x04, /*      #   */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @192 '0' (8 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x66, /*  ##  ##  */
+	0x42, /*  #    #  */
+	0x4A, /*  #  # #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x66, /*  ##  ##  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @204 '1' (8 pixels wide) */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @216 '2' (8 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x42, /*  #    #  */
+	0x02, /*       #  */
+	0x06, /*      ##  */
+	0x0C, /*     ##   */
+	0x18, /*    ##    */
+	0x20, /*   #      */
+	0x7E, /*  ######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @228 '3' (8 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x42, /*  #    #  */
+	0x02, /*       #  */
+	0x3C, /*   ####   */
+	0x06, /*      ##  */
+	0x02, /*       #  */
+	0x42, /*  #    #  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @240 '4' (8 pixels wide) */
+	0x00, /*          */
+	0x0C, /*     ##   */
+	0x0C, /*     ##   */
+	0x14, /*    # #   */
+	0x24, /*   #  #   */
+	0x64, /*  ##  #   */
+	0x7E, /*  ######  */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @252 '5' (8 pixels wide) */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x7C, /*  #####   */
+	0x06, /*      ##  */
+	0x02, /*       #  */
+	0x02, /*       #  */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @264 '6' (8 pixels wide) */
+	0x00, /*          */
+	0x1E, /*    ####  */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0x5C, /*  # ###   */
+	0x62, /*  ##   #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @276 '7' (8 pixels wide) */
+	0x00, /*          */
+	0x7E, /*  ######  */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @288 '8' (8 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x3C, /*   ####   */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @300 '9' (8 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x3E, /*   #####  */
+	0x02, /*       #  */
+	0x04, /*      #   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @312 ':' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @324 ';' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @336 '<' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x02, /*       #  */
+	0x1C, /*    ###   */
+	0x60, /*  ##      */
+	0x18, /*    ##    */
+	0x06, /*      ##  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @348 '=' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @360 '>' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x40, /*  #       */
+	0x38, /*   ###    */
+	0x06, /*      ##  */
+	0x18, /*    ##    */
+	0x60, /*  ##      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @372 '?' (8 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x04, /*      #   */
+	0x0C, /*     ##   */
+	0x18, /*    ##    */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @384 '@' (8 pixels wide) */
+	0x00, /*          */
+	0x1C, /*    ###   */
+	0x26, /*   #  ##  */
+	0x42, /*  #    #  */
+	0x4E, /*  #  ###  */
+	0x52, /*  # #  #  */
+	0x52, /*  # #  #  */
+	0x4E, /*  #  ###  */
+	0x60, /*  ##      */
+	0x20, /*   #      */
+	0x1C, /*    ###   */
+	0x00, /*          */
+
+	/* @396 'A' (8 pixels wide) */
+	0x00, /*          */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x24, /*   #  #   */
+	0x24, /*   #  #   */
+	0x3C, /*   ####   */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @408 'B' (8 pixels wide) */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x7C, /*  #####   */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @420 'C' (8 pixels wide) */
+	0x00, /*          */
+	0x1C, /*    ###   */
+	0x22, /*   #   #  */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x22, /*   #   #  */
+	0x1C, /*    ###   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @432 'D' (8 pixels wide) */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x44, /*  #   #   */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x44, /*  #   #   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @444 'E' (8 pixels wide) */
+	0x00, /*          */
+	0x7E, /*  ######  */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x7E, /*  ######  */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x7E, /*  ######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @456 'F' (8 pixels wide) */
+	0x00, /*          */
+	0x7E, /*  ######  */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x7E, /*  ######  */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @468 'G' (8 pixels wide) */
+	0x00, /*          */
+	0x1C, /*    ###   */
+	0x22, /*   #   #  */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x46, /*  #   ##  */
+	0x42, /*  #    #  */
+	0x22, /*   #   #  */
+	0x1C, /*    ###   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @480 'H' (8 pixels wide) */
+	0x00, /*          */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x7E, /*  ######  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @492 'I' (8 pixels wide) */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @504 'J' (8 pixels wide) */
+	0x00, /*          */
+	0x1C, /*    ###   */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x44, /*  #   #   */
+	0x38, /*   ###    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @516 'K' (8 pixels wide) */
+	0x00, /*          */
+	0x44, /*  #   #   */
+	0x48, /*  #  #    */
+	0x50, /*  # #     */
+	0x60, /*  ##      */
+	0x50, /*  # #     */
+	0x48, /*  #  #    */
+	0x44, /*  #   #   */
+	0x42, /*  #    #  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @528 'L' (8 pixels wide) */
+	0x00, /*          */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x7E, /*  ######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @540 'M' (8 pixels wide) */
+	0x00, /*          */
+	0x42, /*  #    #  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x5A, /*  # ## #  */
+	0x5A, /*  # ## #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @552 'N' (8 pixels wide) */
+	0x00, /*          */
+	0x42, /*  #    #  */
+	0x62, /*  ##   #  */
+	0x52, /*  # #  #  */
+	0x52, /*  # #  #  */
+	0x4A, /*  #  # #  */
+	0x4A, /*  #  # #  */
+	0x46, /*  #   ##  */
+	0x42, /*  #    #  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @564 'O' (8 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x66, /*  ##  ##  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x66, /*  ##  ##  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @576 'P' (8 pixels wide) */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x7C, /*  #####   */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @588 'Q' (8 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x66, /*  ##  ##  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x66, /*  ##  ##  */
+	0x3C, /*   ####   */
+	0x06, /*      ##  */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @600 'R' (8 pixels wide) */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x7C, /*  #####   */
+	0x44, /*  #   #   */
+	0x42, /*  #    #  */
+	0x41, /*  #     # */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @612 'S' (8 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x42, /*  #    #  */
+	0x40, /*  #       */
+	0x78, /*  ####    */
+	0x06, /*      ##  */
+	0x02, /*       #  */
+	0x42, /*  #    #  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @624 'T' (8 pixels wide) */
+	0x00, /*          */
+	0xFE, /* #######  */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @636 'U' (8 pixels wide) */
+	0x00, /*          */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @648 'V' (8 pixels wide) */
+	0x00, /*          */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x24, /*   #  #   */
+	0x24, /*   #  #   */
+	0x24, /*   #  #   */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @660 'W' (8 pixels wide) */
+	0x00, /*          */
+	0x82, /* #     #  */
+	0x92, /* #  #  #  */
+	0x92, /* #  #  #  */
+	0xAA, /* # # # #  */
+	0x6C, /*  ## ##   */
+	0x6C, /*  ## ##   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @672 'X' (8 pixels wide) */
+	0x00, /*          */
+	0x42, /*  #    #  */
+	0x24, /*   #  #   */
+	0x24, /*   #  #   */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x24, /*   #  #   */
+	0x24, /*   #  #   */
+	0x42, /*  #    #  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @684 'Y' (8 pixels wide) */
+	0x00, /*          */
+	0xC6, /* ##   ##  */
+	0x44, /*  #   #   */
+	0x28, /*   # #    */
+	0x38, /*   ###    */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @696 'Z' (8 pixels wide) */
+	0x00, /*          */
+	0x7E, /*  ######  */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x08, /*     #    */
+	0x10, /*    #     */
+	0x30, /*   ##     */
+	0x20, /*   #      */
+	0x7E, /*  ######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @708 '[' (8 pixels wide) */
+	0x30, /*   ##     */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x30, /*   ##     */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @720 '\' (8 pixels wide) */
+	0x00, /*          */
+	0x40, /*  #       */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0x04, /*      #   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @732 ']' (8 pixels wide) */
+	0x30, /*   ##     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x30, /*   ##     */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @744 '^' (8 pixels wide) */
+	0x00, /*          */
+	0x30, /*   ##     */
+	0x48, /*  #  #    */
+	0x84, /* #    #   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @756 '_' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xFE, /* #######  */
+
+	/* @768 '`' (8 pixels wide) */
+	0x10, /*    #     */
+	0x08, /*     #    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @780 'a' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x04, /*      #   */
+	0x3C, /*   ####   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @792 'b' (8 pixels wide) */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x78, /*  ####    */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @804 'c' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x60, /*  ##      */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x60, /*  ##      */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @816 'd' (8 pixels wide) */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x3C, /*   ####   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @828 'e' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x44, /*  #   #   */
+	0x7C, /*  #####   */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @840 'f' (8 pixels wide) */
+	0x0C, /*     ##   */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x7C, /*  #####   */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @852 'g' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x3C, /*   ####   */
+	0x04, /*      #   */
+	0x38, /*   ###    */
+	0x00, /*          */
+
+	/* @864 'h' (8 pixels wide) */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x58, /*  # ##    */
+	0x64, /*  ##  #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @876 'i' (8 pixels wide) */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @888 'j' (8 pixels wide) */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x60, /*  ##      */
+	0x00, /*          */
+
+	/* @900 'k' (8 pixels wide) */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x48, /*  #  #    */
+	0x50, /*  # #     */
+	0x60, /*  ##      */
+	0x50, /*  # #     */
+	0x48, /*  #  #    */
+	0x44, /*  #   #   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @912 'l' (8 pixels wide) */
+	0xE0, /* ###      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x18, /*    ##    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @924 'm' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x54, /*  # # #   */
+	0x54, /*  # # #   */
+	0x54, /*  # # #   */
+	0x54, /*  # # #   */
+	0x54, /*  # # #   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @936 'n' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x58, /*  # ##    */
+	0x64, /*  ##  #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @948 'o' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x38, /*   ###    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @960 'p' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x78, /*  ####    */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x00, /*          */
+
+	/* @972 'q' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x3C, /*   ####   */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x00, /*          */
+
+	/* @984 'r' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x24, /*   #  #   */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @996 's' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x40, /*  #       */
+	0x70, /*  ###     */
+	0x0C, /*     ##   */
+	0x04, /*      #   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1008 't' (8 pixels wide) */
+	0x00, /*          */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0xF8, /* #####    */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x38, /*   ###    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1020 'u' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1032 'v' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x28, /*   # #    */
+	0x28, /*   # #    */
+	0x28, /*   # #    */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1044 'w' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x54, /*  # # #   */
+	0x54, /*  # # #   */
+	0x28, /*   # #    */
+	0x28, /*   # #    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1056 'x' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x6C, /*  ## ##   */
+	0x28, /*   # #    */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x28, /*   # #    */
+	0x6C, /*  ## ##   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1068 'y' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x44, /*  #   #   */
+	0x48, /*  #  #    */
+	0x28, /*   # #    */
+	0x28, /*   # #    */
+	0x30, /*   ##     */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x60, /*  ##      */
+	0x00, /*          */
+
+	/* @1080 'z' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x08, /*     #    */
+	0x18, /*    ##    */
+	0x30, /*   ##     */
+	0x20, /*   #      */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1092 '{' (8 pixels wide) */
+	0x1C, /*    ###   */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x60, /*  ##      */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x1C, /*    ###   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1104 '|' (8 pixels wide) */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+
+	/* @1116 '}' (8 pixels wide) */
+	0x70, /*  ###     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x0C, /*     ##   */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x70, /*  ###     */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1128 '~' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0x0E, /*     ###  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+};
+
+/* Character descriptors for DejaVu Sans Mono 8pt */
+/* { [Char width in bits], [Offset into dejaVuSansMono8ptCharBitmaps in bytes] } */
+const FONT_CHAR_INFO dejaVuSansMono8ptDescriptors[] = 
+{
+	{8, 0}, 		/*   */ 
+	{8, 12}, 		/* ! */ 
+	{8, 24}, 		/* " */ 
+	{8, 36}, 		/* # */ 
+	{8, 48}, 		/* $ */ 
+	{8, 60}, 		/* % */ 
+	{8, 72}, 		/* & */ 
+	{8, 84}, 		/* ' */ 
+	{8, 96}, 		/* ( */ 
+	{8, 108}, 		/* ) */ 
+	{8, 120}, 		/* * */ 
+	{8, 132}, 		/* + */ 
+	{8, 144}, 		/* , */ 
+	{8, 156}, 		/* - */ 
+	{8, 168}, 		/* . */ 
+	{8, 180}, 		/* / */ 
+	{8, 192}, 		/* 0 */ 
+	{8, 204}, 		/* 1 */ 
+	{8, 216}, 		/* 2 */ 
+	{8, 228}, 		/* 3 */ 
+	{8, 240}, 		/* 4 */ 
+	{8, 252}, 		/* 5 */ 
+	{8, 264}, 		/* 6 */ 
+	{8, 276}, 		/* 7 */ 
+	{8, 288}, 		/* 8 */ 
+	{8, 300}, 		/* 9 */ 
+	{8, 312}, 		/* : */ 
+	{8, 324}, 		/* ; */ 
+	{8, 336}, 		/* < */ 
+	{8, 348}, 		/* = */ 
+	{8, 360}, 		/* > */ 
+	{8, 372}, 		/* ? */ 
+	{8, 384}, 		/* @ */ 
+	{8, 396}, 		/* A */ 
+	{8, 408}, 		/* B */ 
+	{8, 420}, 		/* C */ 
+	{8, 432}, 		/* D */ 
+	{8, 444}, 		/* E */ 
+	{8, 456}, 		/* F */ 
+	{8, 468}, 		/* G */ 
+	{8, 480}, 		/* H */ 
+	{8, 492}, 		/* I */ 
+	{8, 504}, 		/* J */ 
+	{8, 516}, 		/* K */ 
+	{8, 528}, 		/* L */ 
+	{8, 540}, 		/* M */ 
+	{8, 552}, 		/* N */ 
+	{8, 564}, 		/* O */ 
+	{8, 576}, 		/* P */ 
+	{8, 588}, 		/* Q */ 
+	{8, 600}, 		/* R */ 
+	{8, 612}, 		/* S */ 
+	{8, 624}, 		/* T */ 
+	{8, 636}, 		/* U */ 
+	{8, 648}, 		/* V */ 
+	{8, 660}, 		/* W */ 
+	{8, 672}, 		/* X */ 
+	{8, 684}, 		/* Y */ 
+	{8, 696}, 		/* Z */ 
+	{8, 708}, 		/* [ */ 
+	{8, 720}, 		/* \ */ 
+	{8, 732}, 		/* ] */ 
+	{8, 744}, 		/* ^ */ 
+	{8, 756}, 		/* _ */ 
+	{8, 768}, 		/* ` */ 
+	{8, 780}, 		/* a */ 
+	{8, 792}, 		/* b */ 
+	{8, 804}, 		/* c */ 
+	{8, 816}, 		/* d */ 
+	{8, 828}, 		/* e */ 
+	{8, 840}, 		/* f */ 
+	{8, 852}, 		/* g */ 
+	{8, 864}, 		/* h */ 
+	{8, 876}, 		/* i */ 
+	{8, 888}, 		/* j */ 
+	{8, 900}, 		/* k */ 
+	{8, 912}, 		/* l */ 
+	{8, 924}, 		/* m */ 
+	{8, 936}, 		/* n */ 
+	{8, 948}, 		/* o */ 
+	{8, 960}, 		/* p */ 
+	{8, 972}, 		/* q */ 
+	{8, 984}, 		/* r */ 
+	{8, 996}, 		/* s */ 
+	{8, 1008}, 		/* t */ 
+	{8, 1020}, 		/* u */ 
+	{8, 1032}, 		/* v */ 
+	{8, 1044}, 		/* w */ 
+	{8, 1056}, 		/* x */ 
+	{8, 1068}, 		/* y */ 
+	{8, 1080}, 		/* z */ 
+	{8, 1092}, 		/* { */ 
+	{8, 1104}, 		/* | */ 
+	{8, 1116}, 		/* } */ 
+	{8, 1128}, 		/* ~ */ 
+};
+
+/* Font information for DejaVu Sans Mono 8pt */
+const FONT_INFO dejaVuSansMono8ptFontInfo =
+{
+	12, /*  Character height */
+	' ', /*  Start character */
+	'~', /*  End character */
+	dejaVuSansMono8ptDescriptors, /*  Character descriptor array */
+	dejaVuSansMono8ptBitmaps, /*  Character bitmap array */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusansmono8.h b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusansmono8.h
new file mode 100644
index 0000000000000000000000000000000000000000..d0145a7e5fb6b8a77dc01b37ce4f2c1bae531b65
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusansmono8.h
@@ -0,0 +1,18 @@
+#ifndef __DEJA_VU_SANS_MONO_8__
+#define __DEJA_VU_SANS_MONO_8__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../fonts.h"
+
+extern const uint8_t dejaVuSansMono8ptCharBitmaps[];
+extern const FONT_CHAR_INFO dejaVuSansMono8ptCharDescriptors[];
+extern const FONT_INFO dejaVuSansMono8ptFontInfo;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusansmonobold8.c b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusansmonobold8.c
new file mode 100644
index 0000000000000000000000000000000000000000..bc053132b93acd68d82ebf8f0182cf6aa614c9c1
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusansmonobold8.c
@@ -0,0 +1,1450 @@
+#include "dejavusansmonobold8.h"
+
+/* 
+**  Font data for DejaVu Sans Mono Bold 8pt
+*/
+
+/* Character bitmaps for DejaVu Sans Mono Bold 8pt */
+const uint8_t dejaVuSansMonoBold8ptBitmaps[] = 
+{
+	/* @0 ' ' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @12 '!' (8 pixels wide) */
+	0x00, /*          */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x00, /*          */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @24 '"' (8 pixels wide) */
+	0x00, /*          */
+	0x28, /*   # #    */
+	0x28, /*   # #    */
+	0x28, /*   # #    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @36 '#' (8 pixels wide) */
+	0x00, /*          */
+	0x14, /*    # #   */
+	0x34, /*   ## #   */
+	0x7E, /*  ######  */
+	0x28, /*   # #    */
+	0x28, /*   # #    */
+	0xFC, /* ######   */
+	0x58, /*  # ##    */
+	0x50, /*  # #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @48 '$' (8 pixels wide) */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x38, /*   ###    */
+	0x50, /*  # #     */
+	0x78, /*  ####    */
+	0x3C, /*   ####   */
+	0x14, /*    # #   */
+	0x54, /*  # # #   */
+	0x38, /*   ###    */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+
+	/* @60 '%' (8 pixels wide) */
+	0x00, /*          */
+	0xE0, /* ###      */
+	0xA0, /* # #      */
+	0xE4, /* ###  #   */
+	0x18, /*    ##    */
+	0x20, /*   #      */
+	0xDC, /* ## ###   */
+	0x14, /*    # #   */
+	0x1C, /*    ###   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @72 '&' (8 pixels wide) */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x10, /*    #     */
+	0x7A, /*  #### #  */
+	0x6A, /*  ## # #  */
+	0x6E, /*  ## ###  */
+	0x3E, /*   #####  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @84 ''' (8 pixels wide) */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @96 '(' (8 pixels wide) */
+	0x08, /*     #    */
+	0x18, /*    ##    */
+	0x10, /*    #     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x10, /*    #     */
+	0x18, /*    ##    */
+	0x08, /*     #    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @108 ')' (8 pixels wide) */
+	0x20, /*   #      */
+	0x30, /*   ##     */
+	0x10, /*    #     */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x10, /*    #     */
+	0x30, /*   ##     */
+	0x20, /*   #      */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @120 '*' (8 pixels wide) */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x54, /*  # # #   */
+	0x38, /*   ###    */
+	0x38, /*   ###    */
+	0x54, /*  # # #   */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @132 '+' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x7C, /*  #####   */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @144 ',' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0x00, /*          */
+
+	/* @156 '-' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x38, /*   ###    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @168 '.' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @180 '/' (8 pixels wide) */
+	0x00, /*          */
+	0x04, /*      #   */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @192 '0' (8 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x6E, /*  ## ###  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @204 '1' (8 pixels wide) */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x7E, /*  ######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @216 '2' (8 pixels wide) */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x0C, /*     ##   */
+	0x08, /*     #    */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x7E, /*  ######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @228 '3' (8 pixels wide) */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x38, /*   ###    */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @240 '4' (8 pixels wide) */
+	0x00, /*          */
+	0x0C, /*     ##   */
+	0x1C, /*    ###   */
+	0x3C, /*   ####   */
+	0x2C, /*   # ##   */
+	0x4C, /*  #  ##   */
+	0x7E, /*  ######  */
+	0x0C, /*     ##   */
+	0x0C, /*     ##   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @252 '5' (8 pixels wide) */
+	0x00, /*          */
+	0x7E, /*  ######  */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x7C, /*  #####   */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @264 '6' (8 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x30, /*   ##     */
+	0x60, /*  ##      */
+	0x7C, /*  #####   */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @276 '7' (8 pixels wide) */
+	0x00, /*          */
+	0x7E, /*  ######  */
+	0x06, /*      ##  */
+	0x0C, /*     ##   */
+	0x0C, /*     ##   */
+	0x1C, /*    ###   */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x30, /*   ##     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @288 '8' (8 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x18, /*    ##    */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @300 '9' (8 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x3E, /*   #####  */
+	0x06, /*      ##  */
+	0x0E, /*     ###  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @312 ':' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x00, /*          */
+	0x00, /*          */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @324 ';' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x00, /*          */
+	0x00, /*          */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0x00, /*          */
+
+	/* @336 '<' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x02, /*       #  */
+	0x1E, /*    ####  */
+	0x70, /*  ###     */
+	0x70, /*  ###     */
+	0x1E, /*    ####  */
+	0x02, /*       #  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @348 '=' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x7E, /*  ######  */
+	0x00, /*          */
+	0x7E, /*  ######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @360 '>' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x40, /*  #       */
+	0x78, /*  ####    */
+	0x0E, /*     ###  */
+	0x0E, /*     ###  */
+	0x78, /*  ####    */
+	0x40, /*  #       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @372 '?' (8 pixels wide) */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x58, /*  # ##    */
+	0x18, /*    ##    */
+	0x20, /*   #      */
+	0x30, /*   ##     */
+	0x00, /*          */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @384 '@' (8 pixels wide) */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x44, /*  #   #   */
+	0x9C, /* #  ###   */
+	0xA4, /* # #  #   */
+	0xA4, /* # #  #   */
+	0xA4, /* # #  #   */
+	0x9C, /* #  ###   */
+	0x44, /*  #   #   */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @396 'A' (8 pixels wide) */
+	0x00, /*          */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x3C, /*   ####   */
+	0x3C, /*   ####   */
+	0x24, /*   #  #   */
+	0x3C, /*   ####   */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @408 'B' (8 pixels wide) */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x78, /*  ####    */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @420 'C' (8 pixels wide) */
+	0x00, /*          */
+	0x1C, /*    ###   */
+	0x32, /*   ##  #  */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x32, /*   ##  #  */
+	0x1C, /*    ###   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @432 'D' (8 pixels wide) */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @444 'E' (8 pixels wide) */
+	0x00, /*          */
+	0x7E, /*  ######  */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x7C, /*  #####   */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x7E, /*  ######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @456 'F' (8 pixels wide) */
+	0x00, /*          */
+	0x7E, /*  ######  */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x7C, /*  #####   */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @468 'G' (8 pixels wide) */
+	0x00, /*          */
+	0x1C, /*    ###   */
+	0x32, /*   ##  #  */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x6E, /*  ## ###  */
+	0x66, /*  ##  ##  */
+	0x36, /*   ## ##  */
+	0x1E, /*    ####  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @480 'H' (8 pixels wide) */
+	0x00, /*          */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x7E, /*  ######  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @492 'I' (8 pixels wide) */
+	0x00, /*          */
+	0x7E, /*  ######  */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x7E, /*  ######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @504 'J' (8 pixels wide) */
+	0x00, /*          */
+	0x1E, /*    ####  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x46, /*  #   ##  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @516 'K' (8 pixels wide) */
+	0x00, /*          */
+	0x66, /*  ##  ##  */
+	0x6C, /*  ## ##   */
+	0x68, /*  ## #    */
+	0x78, /*  ####    */
+	0x78, /*  ####    */
+	0x6C, /*  ## ##   */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @528 'L' (8 pixels wide) */
+	0x00, /*          */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x7E, /*  ######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @540 'M' (8 pixels wide) */
+	0x00, /*          */
+	0x42, /*  #    #  */
+	0x66, /*  ##  ##  */
+	0x7E, /*  ######  */
+	0x7E, /*  ######  */
+	0x7E, /*  ######  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @552 'N' (8 pixels wide) */
+	0x00, /*          */
+	0x66, /*  ##  ##  */
+	0x76, /*  ### ##  */
+	0x76, /*  ### ##  */
+	0x76, /*  ### ##  */
+	0x6E, /*  ## ###  */
+	0x6E, /*  ## ###  */
+	0x6E, /*  ## ###  */
+	0x66, /*  ##  ##  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @564 'O' (8 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @576 'P' (8 pixels wide) */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x7C, /*  #####   */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @588 'Q' (8 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x3C, /*   ####   */
+	0x04, /*      #   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @600 'R' (8 pixels wide) */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x78, /*  ####    */
+	0x64, /*  ##  #   */
+	0x66, /*  ##  ##  */
+	0x63, /*  ##   ## */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @612 'S' (8 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x62, /*  ##   #  */
+	0x60, /*  ##      */
+	0x78, /*  ####    */
+	0x1E, /*    ####  */
+	0x06, /*      ##  */
+	0x46, /*  #   ##  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @624 'T' (8 pixels wide) */
+	0x00, /*          */
+	0x7E, /*  ######  */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @636 'U' (8 pixels wide) */
+	0x00, /*          */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @648 'V' (8 pixels wide) */
+	0x00, /*          */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x24, /*   #  #   */
+	0x24, /*   #  #   */
+	0x3C, /*   ####   */
+	0x3C, /*   ####   */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @660 'W' (8 pixels wide) */
+	0x00, /*          */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0xD6, /* ## # ##  */
+	0xD6, /* ## # ##  */
+	0x6C, /*  ## ##   */
+	0x6C, /*  ## ##   */
+	0x6C, /*  ## ##   */
+	0x6C, /*  ## ##   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @672 'X' (8 pixels wide) */
+	0x00, /*          */
+	0x66, /*  ##  ##  */
+	0x24, /*   #  #   */
+	0x3C, /*   ####   */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x3C, /*   ####   */
+	0x24, /*   #  #   */
+	0x66, /*  ##  ##  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @684 'Y' (8 pixels wide) */
+	0x00, /*          */
+	0x66, /*  ##  ##  */
+	0x24, /*   #  #   */
+	0x3C, /*   ####   */
+	0x3C, /*   ####   */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @696 'Z' (8 pixels wide) */
+	0x00, /*          */
+	0x7E, /*  ######  */
+	0x06, /*      ##  */
+	0x0C, /*     ##   */
+	0x18, /*    ##    */
+	0x10, /*    #     */
+	0x30, /*   ##     */
+	0x60, /*  ##      */
+	0x7E, /*  ######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @708 '[' (8 pixels wide) */
+	0x38, /*   ###    */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x38, /*   ###    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @720 '\' (8 pixels wide) */
+	0x00, /*          */
+	0x40, /*  #       */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0x04, /*      #   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @732 ']' (8 pixels wide) */
+	0x38, /*   ###    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x38, /*   ###    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @744 '^' (8 pixels wide) */
+	0x00, /*          */
+	0x30, /*   ##     */
+	0x78, /*  ####    */
+	0xCC, /* ##  ##   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @756 '_' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xFE, /* #######  */
+
+	/* @768 '`' (8 pixels wide) */
+	0x60, /*  ##      */
+	0x30, /*   ##     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @780 'a' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x06, /*      ##  */
+	0x3E, /*   #####  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x3E, /*   #####  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @792 'b' (8 pixels wide) */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x7C, /*  #####   */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @804 'c' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x3E, /*   #####  */
+	0x70, /*  ###     */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x70, /*  ###     */
+	0x3E, /*   #####  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @816 'd' (8 pixels wide) */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x3E, /*   #####  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x3E, /*   #####  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @828 'e' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x66, /*  ##  ##  */
+	0x7E, /*  ######  */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x3E, /*   #####  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @840 'f' (8 pixels wide) */
+	0x1C, /*    ###   */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x7C, /*  #####   */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @852 'g' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x3E, /*   #####  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x3E, /*   #####  */
+	0x06, /*      ##  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+
+	/* @864 'h' (8 pixels wide) */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x7C, /*  #####   */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @876 'i' (8 pixels wide) */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x7E, /*  ######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @888 'j' (8 pixels wide) */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x70, /*  ###     */
+	0x00, /*          */
+
+	/* @900 'k' (8 pixels wide) */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x6C, /*  ## ##   */
+	0x68, /*  ## #    */
+	0x78, /*  ####    */
+	0x68, /*  ## #    */
+	0x6C, /*  ## ##   */
+	0x66, /*  ##  ##  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @912 'l' (8 pixels wide) */
+	0xF0, /* ####     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x1C, /*    ###   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @924 'm' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x7E, /*  ######  */
+	0x6A, /*  ## # #  */
+	0x6A, /*  ## # #  */
+	0x6A, /*  ## # #  */
+	0x6A, /*  ## # #  */
+	0x6A, /*  ## # #  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @936 'n' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @948 'o' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @960 'p' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x7C, /*  #####   */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x00, /*          */
+
+	/* @972 'q' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x3E, /*   #####  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x3E, /*   #####  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x00, /*          */
+
+	/* @984 'r' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x3E, /*   #####  */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @996 's' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x62, /*  ##   #  */
+	0x78, /*  ####    */
+	0x1E, /*    ####  */
+	0x46, /*  #   ##  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1008 't' (8 pixels wide) */
+	0x00, /*          */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0xFC, /* ######   */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1020 'u' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x3E, /*   #####  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1032 'v' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x66, /*  ##  ##  */
+	0x66, /*  ##  ##  */
+	0x24, /*   #  #   */
+	0x3C, /*   ####   */
+	0x3C, /*   ####   */
+	0x18, /*    ##    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1044 'w' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xC6, /* ##   ##  */
+	0xC6, /* ##   ##  */
+	0x54, /*  # # #   */
+	0x6C, /*  ## ##   */
+	0x6C, /*  ## ##   */
+	0x6C, /*  ## ##   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1056 'x' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x66, /*  ##  ##  */
+	0x3C, /*   ####   */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x3C, /*   ####   */
+	0x66, /*  ##  ##  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1068 'y' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x66, /*  ##  ##  */
+	0x24, /*   #  #   */
+	0x2C, /*   # ##   */
+	0x3C, /*   ####   */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x10, /*    #     */
+	0x70, /*  ###     */
+	0x00, /*          */
+
+	/* @1080 'z' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x7E, /*  ######  */
+	0x06, /*      ##  */
+	0x0C, /*     ##   */
+	0x30, /*   ##     */
+	0x60, /*  ##      */
+	0x7E, /*  ######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1092 '{' (8 pixels wide) */
+	0x1E, /*    ####  */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x60, /*  ##      */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x1E, /*    ####  */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1104 '|' (8 pixels wide) */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+
+	/* @1116 '}' (8 pixels wide) */
+	0x78, /*  ####    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x06, /*      ##  */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1128 '~' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0x0E, /*     ###  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+};
+
+/* Character descriptors for DejaVu Sans Mono Bold 8pt */
+/* { [Char width in bits], [Offset into dejaVuSansMono8ptCharBitmaps in bytes] } */
+const FONT_CHAR_INFO dejaVuSansMonoBold8ptDescriptors[] = 
+{
+	{8, 0}, 		/*   */ 
+	{8, 12}, 		/* ! */ 
+	{8, 24}, 		/* " */ 
+	{8, 36}, 		/* # */ 
+	{8, 48}, 		/* $ */ 
+	{8, 60}, 		/* % */ 
+	{8, 72}, 		/* & */ 
+	{8, 84}, 		/* ' */ 
+	{8, 96}, 		/* ( */ 
+	{8, 108}, 		/* ) */ 
+	{8, 120}, 		/* * */ 
+	{8, 132}, 		/* + */ 
+	{8, 144}, 		/* , */ 
+	{8, 156}, 		/* - */ 
+	{8, 168}, 		/* . */ 
+	{8, 180}, 		/* / */ 
+	{8, 192}, 		/* 0 */ 
+	{8, 204}, 		/* 1 */ 
+	{8, 216}, 		/* 2 */ 
+	{8, 228}, 		/* 3 */ 
+	{8, 240}, 		/* 4 */ 
+	{8, 252}, 		/* 5 */ 
+	{8, 264}, 		/* 6 */ 
+	{8, 276}, 		/* 7 */ 
+	{8, 288}, 		/* 8 */ 
+	{8, 300}, 		/* 9 */ 
+	{8, 312}, 		/* : */ 
+	{8, 324}, 		/* ; */ 
+	{8, 336}, 		/* < */ 
+	{8, 348}, 		/* = */ 
+	{8, 360}, 		/* > */ 
+	{8, 372}, 		/* ? */ 
+	{8, 384}, 		/* @ */ 
+	{8, 396}, 		/* A */ 
+	{8, 408}, 		/* B */ 
+	{8, 420}, 		/* C */ 
+	{8, 432}, 		/* D */ 
+	{8, 444}, 		/* E */ 
+	{8, 456}, 		/* F */ 
+	{8, 468}, 		/* G */ 
+	{8, 480}, 		/* H */ 
+	{8, 492}, 		/* I */ 
+	{8, 504}, 		/* J */ 
+	{8, 516}, 		/* K */ 
+	{8, 528}, 		/* L */ 
+	{8, 540}, 		/* M */ 
+	{8, 552}, 		/* N */ 
+	{8, 564}, 		/* O */ 
+	{8, 576}, 		/* P */ 
+	{8, 588}, 		/* Q */ 
+	{8, 600}, 		/* R */ 
+	{8, 612}, 		/* S */ 
+	{8, 624}, 		/* T */ 
+	{8, 636}, 		/* U */ 
+	{8, 648}, 		/* V */ 
+	{8, 660}, 		/* W */ 
+	{8, 672}, 		/* X */ 
+	{8, 684}, 		/* Y */ 
+	{8, 696}, 		/* Z */ 
+	{8, 708}, 		/* [ */ 
+	{8, 720}, 		/* \ */ 
+	{8, 732}, 		/* ] */ 
+	{8, 744}, 		/* ^ */ 
+	{8, 756}, 		/* _ */ 
+	{8, 768}, 		/* ` */ 
+	{8, 780}, 		/* a */ 
+	{8, 792}, 		/* b */ 
+	{8, 804}, 		/* c */ 
+	{8, 816}, 		/* d */ 
+	{8, 828}, 		/* e */ 
+	{8, 840}, 		/* f */ 
+	{8, 852}, 		/* g */ 
+	{8, 864}, 		/* h */ 
+	{8, 876}, 		/* i */ 
+	{8, 888}, 		/* j */ 
+	{8, 900}, 		/* k */ 
+	{8, 912}, 		/* l */ 
+	{8, 924}, 		/* m */ 
+	{8, 936}, 		/* n */ 
+	{8, 948}, 		/* o */ 
+	{8, 960}, 		/* p */ 
+	{8, 972}, 		/* q */ 
+	{8, 984}, 		/* r */ 
+	{8, 996}, 		/* s */ 
+	{8, 1008}, 		/* t */ 
+	{8, 1020}, 		/* u */ 
+	{8, 1032}, 		/* v */ 
+	{8, 1044}, 		/* w */ 
+	{8, 1056}, 		/* x */ 
+	{8, 1068}, 		/* y */ 
+	{8, 1080}, 		/* z */ 
+	{8, 1092}, 		/* { */ 
+	{8, 1104}, 		/* | */ 
+	{8, 1116}, 		/* } */ 
+	{8, 1128}, 		/* ~ */ 
+};
+
+/* Font information for DejaVu Sans Mono Bold 8pt */
+const FONT_INFO dejaVuSansMonoBold8ptFontInfo =
+{
+	12, /*  Character height */
+	' ', /*  Start character */
+	'~', /*  End character */
+	dejaVuSansMonoBold8ptDescriptors, /*  Character descriptor array */
+	dejaVuSansMonoBold8ptBitmaps, /*  Character bitmap array */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusansmonobold8.h b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusansmonobold8.h
new file mode 100644
index 0000000000000000000000000000000000000000..67b4b37d17c93160ddd85adbcfdab396a3c1750f
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/dejavusansmonobold8.h
@@ -0,0 +1,18 @@
+#ifndef __DEJA_VU_SANS_MONO_BOLD_8__
+#define __DEJA_VU_SANS_MONO_BOLD_8__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../fonts.h"
+
+extern const uint8_t dejaVuSansMonoBold8ptCharBitmaps[];
+extern const FONT_CHAR_INFO dejaVuSansMonoBold8ptCharDescriptors[];
+extern const FONT_INFO dejaVuSansMonoBold8ptFontInfo;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramono11.c b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramono11.c
new file mode 100644
index 0000000000000000000000000000000000000000..5a33a24ab51f29b24398a6dd81f575a08a35a16c
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramono11.c
@@ -0,0 +1,1165 @@
+#include "veramono11.h"
+
+/* 
+**  Font data for Bitstream Vera Sans Mono 11pt
+*/
+
+/* Character bitmaps for Bitstream Vera Sans Mono 11pt */
+const uint8_t bitstreamVeraSansMono11ptCharBitmaps[] = 
+{
+	/* @0 ' ' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @18 '!' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x0C, 0xFE, /*     ##  #######  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @36 '"' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x1E, /*            ####  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x1E, /*            ####  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @54 '#' (9 pixels wide) */
+	0x01, 0x00, /*        #         */
+	0x09, 0x10, /*     #  #   #     */
+	0x07, 0xD0, /*      ##### #     */
+	0x01, 0x7C, /*        # #####   */
+	0x0D, 0x16, /*     ## #   # ##  */
+	0x07, 0xD0, /*      ##### #     */
+	0x01, 0x7C, /*        # #####   */
+	0x01, 0x16, /*        #   # ##  */
+	0x00, 0x10, /*            #     */
+
+	/* @72 '$' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x04, 0x38, /*      #    ###    */
+	0x08, 0x4C, /*     #    #  ##   */
+	0x08, 0x44, /*     #    #   #   */
+	0x3F, 0xFF, /*   ############## */
+	0x08, 0x84, /*     #   #    #   */
+	0x08, 0x84, /*     #   #    #   */
+	0x07, 0x08, /*      ###    #    */
+	0x00, 0x00, /*                  */
+
+	/* @90 '%' (9 pixels wide) */
+	0x00, 0x1C, /*            ###   */
+	0x00, 0xA2, /*         # #   #  */
+	0x00, 0xA2, /*         # #   #  */
+	0x00, 0x62, /*          ##   #  */
+	0x07, 0x5C, /*      ### # ###   */
+	0x08, 0xC0, /*     #   ##       */
+	0x08, 0xA0, /*     #   # #      */
+	0x08, 0xA0, /*     #   # #      */
+	0x07, 0x00, /*      ###         */
+
+	/* @108 '&' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xC0, /*       ####       */
+	0x04, 0x7C, /*      #   #####   */
+	0x08, 0x32, /*     #     ##  #  */
+	0x08, 0x62, /*     #    ##   #  */
+	0x09, 0x82, /*     #  ##     #  */
+	0x07, 0x02, /*      ###      #  */
+	0x09, 0xC0, /*     #  ###       */
+	0x00, 0x00, /*                  */
+
+	/* @126 ''' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x1E, /*            ####  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @144 '(' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x07, 0xF0, /*      #######     */
+	0x18, 0x0C, /*    ##       ##   */
+	0x20, 0x02, /*   #           #  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @162 ')' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x20, 0x02, /*   #           #  */
+	0x18, 0x0C, /*    ##       ##   */
+	0x07, 0xF0, /*      #######     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @180 '*' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x24, /*           #  #   */
+	0x00, 0x28, /*           # #    */
+	0x00, 0x18, /*            ##    */
+	0x00, 0x7E, /*          ######  */
+	0x00, 0x18, /*            ##    */
+	0x00, 0x28, /*           # #    */
+	0x00, 0x24, /*           #  #   */
+	0x00, 0x00, /*                  */
+
+	/* @198 '+' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x80, /*         #        */
+	0x00, 0x80, /*         #        */
+	0x00, 0x80, /*         #        */
+	0x07, 0xF0, /*      #######     */
+	0x00, 0x80, /*         #        */
+	0x00, 0x80, /*         #        */
+	0x00, 0x80, /*         #        */
+	0x00, 0x00, /*                  */
+
+	/* @216 ',' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x20, 0x00, /*   #              */
+	0x1C, 0x00, /*    ###           */
+	0x0C, 0x00, /*     ##           */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @234 '-' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x80, /*         #        */
+	0x00, 0x80, /*         #        */
+	0x00, 0x80, /*         #        */
+	0x00, 0x80, /*         #        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @252 '.' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x0C, 0x00, /*     ##           */
+	0x0C, 0x00, /*     ##           */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @270 '/' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x10, 0x00, /*    #             */
+	0x0C, 0x00, /*     ##           */
+	0x03, 0x00, /*       ##         */
+	0x00, 0xC0, /*         ##       */
+	0x00, 0x30, /*           ##     */
+	0x00, 0x0C, /*             ##   */
+	0x00, 0x02, /*               #  */
+	0x00, 0x00, /*                  */
+
+	/* @288 '0' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xF8, /*       #######    */
+	0x04, 0x04, /*      #       #   */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x62, /*     #    ##   #  */
+	0x08, 0x62, /*     #    ##   #  */
+	0x04, 0x04, /*      #       #   */
+	0x03, 0xF8, /*       #######    */
+	0x00, 0x00, /*                  */
+
+	/* @306 '1' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x08, 0x04, /*     #        #   */
+	0x08, 0x02, /*     #         #  */
+	0x0F, 0xFE, /*     ###########  */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @324 '2' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x08, 0x0C, /*     #       ##   */
+	0x0C, 0x06, /*     ##       ##  */
+	0x0A, 0x02, /*     # #       #  */
+	0x09, 0x02, /*     #  #      #  */
+	0x08, 0x82, /*     #   #     #  */
+	0x08, 0x44, /*     #    #   #   */
+	0x08, 0x3C, /*     #     ####   */
+	0x00, 0x00, /*                  */
+
+	/* @342 '3' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x04, 0x04, /*      #       #   */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x0C, 0xA4, /*     ##  # #  #   */
+	0x07, 0xBC, /*      #### ####   */
+	0x00, 0x00, /*                  */
+
+	/* @360 '4' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x01, 0x80, /*        ##        */
+	0x01, 0x60, /*        # ##      */
+	0x01, 0x30, /*        #  ##     */
+	0x01, 0x0C, /*        #    ##   */
+	0x01, 0x06, /*        #     ##  */
+	0x0F, 0xFE, /*     ###########  */
+	0x01, 0x00, /*        #         */
+	0x00, 0x00, /*                  */
+
+	/* @378 '5' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x04, 0x7E, /*      #   ######  */
+	0x08, 0x22, /*     #     #   #  */
+	0x08, 0x22, /*     #     #   #  */
+	0x08, 0x22, /*     #     #   #  */
+	0x08, 0x22, /*     #     #   #  */
+	0x04, 0x42, /*      #   #    #  */
+	0x03, 0x80, /*       ###        */
+	0x00, 0x00, /*                  */
+
+	/* @396 '6' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xF0, /*       ######     */
+	0x04, 0x4C, /*      #   #  ##   */
+	0x08, 0x26, /*     #     #  ##  */
+	0x08, 0x22, /*     #     #   #  */
+	0x08, 0x22, /*     #     #   #  */
+	0x0C, 0x62, /*     ##   ##   #  */
+	0x07, 0xC4, /*      #####   #   */
+	0x00, 0x00, /*                  */
+
+	/* @414 '7' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x02, /*               #  */
+	0x08, 0x02, /*     #         #  */
+	0x06, 0x02, /*      ##       #  */
+	0x01, 0x82, /*        ##     #  */
+	0x00, 0x62, /*          ##   #  */
+	0x00, 0x1E, /*            ####  */
+	0x00, 0x06, /*              ##  */
+	0x00, 0x00, /*                  */
+
+	/* @432 '8' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xBC, /*      #### ####   */
+	0x0C, 0xA6, /*     ##  # #  ##  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x0C, 0xA6, /*     ##  # #  ##  */
+	0x07, 0xBC, /*      #### ####   */
+	0x00, 0x00, /*                  */
+
+	/* @450 '9' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x04, 0x7C, /*      #   #####   */
+	0x08, 0xC6, /*     #   ##   ##  */
+	0x08, 0x82, /*     #   #     #  */
+	0x08, 0x82, /*     #   #     #  */
+	0x0C, 0x82, /*     ##  #     #  */
+	0x06, 0x44, /*      ##  #   #   */
+	0x01, 0xF8, /*        ######    */
+	0x00, 0x00, /*                  */
+
+	/* @468 ':' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x0C, 0x30, /*     ##    ##     */
+	0x0C, 0x30, /*     ##    ##     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @486 ';' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x20, 0x00, /*   #              */
+	0x1C, 0x30, /*    ###    ##     */
+	0x0C, 0x30, /*     ##    ##     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @504 '<' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x80, /*         #        */
+	0x01, 0xC0, /*        ###       */
+	0x01, 0x40, /*        # #       */
+	0x01, 0x40, /*        # #       */
+	0x02, 0x20, /*       #   #      */
+	0x02, 0x20, /*       #   #      */
+	0x02, 0x20, /*       #   #      */
+	0x04, 0x10, /*      #     #     */
+
+	/* @522 '=' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x01, 0x20, /*        #  #      */
+	0x01, 0x20, /*        #  #      */
+	0x01, 0x20, /*        #  #      */
+	0x01, 0x20, /*        #  #      */
+	0x01, 0x20, /*        #  #      */
+	0x01, 0x20, /*        #  #      */
+	0x01, 0x20, /*        #  #      */
+	0x01, 0x20, /*        #  #      */
+
+	/* @540 '>' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x04, 0x10, /*      #     #     */
+	0x02, 0x20, /*       #   #      */
+	0x02, 0x20, /*       #   #      */
+	0x02, 0x20, /*       #   #      */
+	0x01, 0x40, /*        # #       */
+	0x01, 0x40, /*        # #       */
+	0x01, 0xC0, /*        ###       */
+	0x00, 0x80, /*         #        */
+
+	/* @558 '?' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x04, /*              #   */
+	0x00, 0x02, /*               #  */
+	0x0D, 0xC2, /*     ## ###    #  */
+	0x00, 0x42, /*          #    #  */
+	0x00, 0x22, /*           #   #  */
+	0x00, 0x1C, /*            ###   */
+	0x00, 0x00, /*                  */
+
+	/* @576 '@' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xE0, /*      ######      */
+	0x18, 0x18, /*    ##      ##    */
+	0x10, 0x0C, /*    #        ##   */
+	0x23, 0xC4, /*   #   ####   #   */
+	0x24, 0x24, /*   #  #    #  #   */
+	0x24, 0x2C, /*   #  #    # ##   */
+	0x07, 0xF8, /*      ########    */
+	0x00, 0x00, /*                  */
+
+	/* @594 'A' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0C, 0x00, /*     ##           */
+	0x03, 0xC0, /*       ####       */
+	0x01, 0x3C, /*        #  ####   */
+	0x01, 0x02, /*        #      #  */
+	0x01, 0x3C, /*        #  ####   */
+	0x03, 0xC0, /*       ####       */
+	0x0C, 0x00, /*     ##           */
+	0x00, 0x00, /*                  */
+
+	/* @612 'B' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x0C, 0xE6, /*     ##  ###  ##  */
+	0x07, 0xBC, /*      #### ####   */
+	0x00, 0x00, /*                  */
+
+	/* @630 'C' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x01, 0xF0, /*        #####     */
+	0x06, 0x0C, /*      ##     ##   */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x02, /*     #         #  */
+	0x04, 0x04, /*      #       #   */
+	0x00, 0x00, /*                  */
+
+	/* @648 'D' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x02, /*     #         #  */
+	0x0C, 0x06, /*     ##       ##  */
+	0x06, 0x0C, /*      ##     ##   */
+	0x01, 0xF0, /*        #####     */
+	0x00, 0x00, /*                  */
+
+	/* @666 'E' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x00, 0x00, /*                  */
+
+	/* @684 'F' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x42, /*          #    #  */
+	0x00, 0x42, /*          #    #  */
+	0x00, 0x42, /*          #    #  */
+	0x00, 0x42, /*          #    #  */
+	0x00, 0x42, /*          #    #  */
+	0x00, 0x42, /*          #    #  */
+	0x00, 0x00, /*                  */
+
+	/* @702 'G' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x01, 0xF0, /*        #####     */
+	0x06, 0x0C, /*      ##     ##   */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x07, 0xC4, /*      #####   #   */
+	0x00, 0x00, /*                  */
+
+	/* @720 'H' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x40, /*          #       */
+	0x00, 0x40, /*          #       */
+	0x00, 0x40, /*          #       */
+	0x00, 0x40, /*          #       */
+	0x00, 0x40, /*          #       */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x00, /*                  */
+
+	/* @738 'I' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x02, /*     #         #  */
+	0x0F, 0xFE, /*     ###########  */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x02, /*     #         #  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @756 'J' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x04, 0x00, /*      #           */
+	0x08, 0x00, /*     #            */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x02, /*     #         #  */
+	0x0C, 0x02, /*     ##        #  */
+	0x07, 0xFE, /*      ##########  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @774 'K' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x40, /*          #       */
+	0x00, 0x20, /*           #      */
+	0x00, 0xD0, /*         ## #     */
+	0x01, 0x08, /*        #    #    */
+	0x06, 0x04, /*      ##      #   */
+	0x08, 0x02, /*     #         #  */
+	0x00, 0x00, /*                  */
+
+	/* @792 'L' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x00, 0x00, /*                  */
+
+	/* @810 'M' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x0E, /*             ###  */
+	0x00, 0x70, /*          ###     */
+	0x00, 0x80, /*         #        */
+	0x00, 0x70, /*          ###     */
+	0x00, 0x0E, /*             ###  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x00, /*                  */
+
+	/* @828 'N' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x06, /*              ##  */
+	0x00, 0x18, /*            ##    */
+	0x00, 0xE0, /*         ###      */
+	0x03, 0x00, /*       ##         */
+	0x0C, 0x00, /*     ##           */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x00, /*                  */
+
+	/* @846 'O' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xF8, /*       #######    */
+	0x04, 0x04, /*      #       #   */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x02, /*     #         #  */
+	0x04, 0x04, /*      #       #   */
+	0x03, 0xF8, /*       #######    */
+	0x00, 0x00, /*                  */
+
+	/* @864 'P' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x82, /*         #     #  */
+	0x00, 0x82, /*         #     #  */
+	0x00, 0x82, /*         #     #  */
+	0x00, 0x82, /*         #     #  */
+	0x00, 0xC6, /*         ##   ##  */
+	0x00, 0x7C, /*          #####   */
+	0x00, 0x00, /*                  */
+
+	/* @882 'Q' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xF8, /*       #######    */
+	0x04, 0x04, /*      #       #   */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x02, /*     #         #  */
+	0x18, 0x02, /*    ##         #  */
+	0x3C, 0x04, /*   ####       #   */
+	0x03, 0xF8, /*       #######    */
+	0x00, 0x00, /*                  */
+
+	/* @900 'R' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x42, /*          #    #  */
+	0x00, 0x42, /*          #    #  */
+	0x00, 0x42, /*          #    #  */
+	0x00, 0x42, /*          #    #  */
+	0x00, 0xA6, /*         # #  ##  */
+	0x07, 0x3C, /*      ###  ####   */
+	0x08, 0x00, /*     #            */
+
+	/* @918 'S' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x04, 0x3C, /*      #    ####   */
+	0x0C, 0x24, /*     ##    #  #   */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x0C, 0x86, /*     ##  #    ##  */
+	0x07, 0x84, /*      ####    #   */
+	0x00, 0x00, /*                  */
+
+	/* @936 'T' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x02, /*               #  */
+	0x00, 0x02, /*               #  */
+	0x00, 0x02, /*               #  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x02, /*               #  */
+	0x00, 0x02, /*               #  */
+	0x00, 0x02, /*               #  */
+	0x00, 0x00, /*                  */
+
+	/* @954 'U' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xFE, /*      ##########  */
+	0x0C, 0x00, /*     ##           */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x0C, 0x00, /*     ##           */
+	0x07, 0xFE, /*      ##########  */
+	0x00, 0x00, /*                  */
+
+	/* @972 'V' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x06, /*              ##  */
+	0x00, 0x78, /*          ####    */
+	0x07, 0x80, /*      ####        */
+	0x08, 0x00, /*     #            */
+	0x07, 0x80, /*      ####        */
+	0x00, 0x78, /*          ####    */
+	0x00, 0x06, /*              ##  */
+	0x00, 0x00, /*                  */
+
+	/* @990 'W' (9 pixels wide) */
+	0x00, 0x0E, /*             ###  */
+	0x03, 0xF0, /*       ######     */
+	0x0C, 0x00, /*     ##           */
+	0x03, 0xE0, /*       #####      */
+	0x00, 0x10, /*            #     */
+	0x03, 0xE0, /*       #####      */
+	0x0C, 0x00, /*     ##           */
+	0x03, 0xF0, /*       ######     */
+	0x00, 0x0E, /*             ###  */
+
+	/* @1008 'X' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x08, 0x02, /*     #         #  */
+	0x06, 0x0C, /*      ##     ##   */
+	0x01, 0xB0, /*        ## ##     */
+	0x00, 0x40, /*          #       */
+	0x01, 0xB0, /*        ## ##     */
+	0x06, 0x0C, /*      ##     ##   */
+	0x08, 0x02, /*     #         #  */
+	0x00, 0x00, /*                  */
+
+	/* @1026 'Y' (9 pixels wide) */
+	0x00, 0x02, /*               #  */
+	0x00, 0x06, /*              ##  */
+	0x00, 0x18, /*            ##    */
+	0x00, 0x30, /*           ##     */
+	0x0F, 0xC0, /*     ######       */
+	0x00, 0x20, /*           #      */
+	0x00, 0x18, /*            ##    */
+	0x00, 0x06, /*              ##  */
+	0x00, 0x02, /*               #  */
+
+	/* @1044 'Z' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0C, 0x02, /*     ##        #  */
+	0x0A, 0x02, /*     # #       #  */
+	0x09, 0x82, /*     #  ##     #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x32, /*     #     ##  #  */
+	0x08, 0x0A, /*     #       # #  */
+	0x08, 0x06, /*     #        ##  */
+	0x00, 0x00, /*                  */
+
+	/* @1062 '[' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x3F, 0xFE, /*   #############  */
+	0x20, 0x02, /*   #           #  */
+	0x20, 0x02, /*   #           #  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1080 '\' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x02, /*               #  */
+	0x00, 0x0C, /*             ##   */
+	0x00, 0x30, /*           ##     */
+	0x00, 0xC0, /*         ##       */
+	0x03, 0x00, /*       ##         */
+	0x0C, 0x00, /*     ##           */
+	0x10, 0x00, /*    #             */
+	0x00, 0x00, /*                  */
+
+	/* @1098 ']' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x20, 0x02, /*   #           #  */
+	0x20, 0x02, /*   #           #  */
+	0x3F, 0xFE, /*   #############  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1116 '^' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x10, /*            #     */
+	0x00, 0x18, /*            ##    */
+	0x00, 0x0C, /*             ##   */
+	0x00, 0x06, /*              ##  */
+	0x00, 0x06, /*              ##  */
+	0x00, 0x0C, /*             ##   */
+	0x00, 0x18, /*            ##    */
+	0x00, 0x10, /*            #     */
+
+	/* @1134 '_' (9 pixels wide) */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x00, 0x00, /*                  */
+
+	/* @1152 '`' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x01, /*                # */
+	0x00, 0x03, /*               ## */
+	0x00, 0x06, /*              ##  */
+	0x00, 0x04, /*              #   */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1170 'a' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0x00, /*      ###         */
+	0x09, 0xA0, /*     #  ## #      */
+	0x08, 0x90, /*     #   #  #     */
+	0x08, 0x90, /*     #   #  #     */
+	0x08, 0x90, /*     #   #  #     */
+	0x04, 0x90, /*      #  #  #     */
+	0x0F, 0xE0, /*     #######      */
+	0x00, 0x00, /*                  */
+
+	/* @1188 'b' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x04, 0x20, /*      #    #      */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x04, 0x20, /*      #    #      */
+	0x03, 0xC0, /*       ####       */
+	0x00, 0x00, /*                  */
+
+	/* @1206 'c' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xC0, /*       ####       */
+	0x04, 0x20, /*      #    #      */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x04, 0x20, /*      #    #      */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1224 'd' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xC0, /*       ####       */
+	0x04, 0x20, /*      #    #      */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x04, 0x20, /*      #    #      */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x00, /*                  */
+
+	/* @1242 'e' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xC0, /*       ####       */
+	0x05, 0x20, /*      # #  #      */
+	0x09, 0x10, /*     #  #   #     */
+	0x09, 0x10, /*     #  #   #     */
+	0x09, 0x10, /*     #  #   #     */
+	0x09, 0x20, /*     #  #  #      */
+	0x05, 0xC0, /*      # ###       */
+	0x00, 0x00, /*                  */
+
+	/* @1260 'f' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x0F, 0xFC, /*     ##########   */
+	0x00, 0x12, /*            #  #  */
+	0x00, 0x12, /*            #  #  */
+	0x00, 0x12, /*            #  #  */
+	0x00, 0x00, /*                  */
+
+	/* @1278 'g' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xC0, /*       ####       */
+	0x24, 0x20, /*   #  #    #      */
+	0x48, 0x10, /*  #  #      #     */
+	0x48, 0x10, /*  #  #      #     */
+	0x48, 0x10, /*  #  #      #     */
+	0x64, 0x20, /*  ##  #    #      */
+	0x3F, 0xF0, /*   ##########     */
+	0x00, 0x00, /*                  */
+
+	/* @1296 'h' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x20, /*           #      */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x30, /*           ##     */
+	0x0F, 0xE0, /*     #######      */
+	0x00, 0x00, /*                  */
+
+	/* @1314 'i' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x08, 0x00, /*     #            */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x0F, 0xF6, /*     ######## ##  */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x00, 0x00, /*                  */
+
+	/* @1332 'j' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x40, 0x00, /*  #               */
+	0x40, 0x10, /*  #         #     */
+	0x40, 0x10, /*  #         #     */
+	0x3F, 0xF6, /*   ########## ##  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1350 'k' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x80, /*         #        */
+	0x00, 0xC0, /*         ##       */
+	0x01, 0x20, /*        #  #      */
+	0x02, 0x20, /*       #   #      */
+	0x04, 0x10, /*      #     #     */
+	0x08, 0x00, /*     #            */
+	0x00, 0x00, /*                  */
+
+	/* @1368 'l' (9 pixels wide) */
+	0x00, 0x02, /*               #  */
+	0x00, 0x02, /*               #  */
+	0x00, 0x02, /*               #  */
+	0x07, 0xFE, /*      ##########  */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1386 'm' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xF0, /*     ########     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x0F, 0xF0, /*     ########     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x0F, 0xE0, /*     #######      */
+	0x00, 0x00, /*                  */
+
+	/* @1404 'n' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xF0, /*     ########     */
+	0x00, 0x20, /*           #      */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x30, /*           ##     */
+	0x0F, 0xE0, /*     #######      */
+	0x00, 0x00, /*                  */
+
+	/* @1422 'o' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xC0, /*       ####       */
+	0x04, 0x20, /*      #    #      */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x04, 0x20, /*      #    #      */
+	0x03, 0xC0, /*       ####       */
+	0x00, 0x00, /*                  */
+
+	/* @1440 'p' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x7F, 0xF0, /*  ###########     */
+	0x04, 0x20, /*      #    #      */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x04, 0x20, /*      #    #      */
+	0x03, 0xC0, /*       ####       */
+	0x00, 0x00, /*                  */
+
+	/* @1458 'q' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xC0, /*       ####       */
+	0x04, 0x20, /*      #    #      */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x04, 0x20, /*      #    #      */
+	0x7F, 0xF0, /*  ###########     */
+	0x00, 0x00, /*                  */
+
+	/* @1476 'r' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x0F, 0xF0, /*     ########     */
+	0x00, 0x20, /*           #      */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x20, /*           #      */
+
+	/* @1494 's' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x04, 0xE0, /*      #  ###      */
+	0x08, 0x90, /*     #   #  #     */
+	0x08, 0x90, /*     #   #  #     */
+	0x08, 0x90, /*     #   #  #     */
+	0x09, 0x10, /*     #  #   #     */
+	0x09, 0x10, /*     #  #   #     */
+	0x07, 0x20, /*      ###  #      */
+	0x00, 0x00, /*                  */
+
+	/* @1512 't' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x07, 0xFC, /*      #########   */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1530 'u' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xF0, /*      #######     */
+	0x0C, 0x00, /*     ##           */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x04, 0x00, /*      #           */
+	0x0F, 0xF0, /*     ########     */
+	0x00, 0x00, /*                  */
+
+	/* @1548 'v' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x10, /*            #     */
+	0x00, 0xE0, /*         ###      */
+	0x07, 0x00, /*      ###         */
+	0x08, 0x00, /*     #            */
+	0x07, 0x00, /*      ###         */
+	0x00, 0xE0, /*         ###      */
+	0x00, 0x10, /*            #     */
+	0x00, 0x00, /*                  */
+
+	/* @1566 'w' (9 pixels wide) */
+	0x00, 0x30, /*           ##     */
+	0x03, 0xC0, /*       ####       */
+	0x0C, 0x00, /*     ##           */
+	0x03, 0x00, /*       ##         */
+	0x00, 0xC0, /*         ##       */
+	0x03, 0x00, /*       ##         */
+	0x0C, 0x00, /*     ##           */
+	0x03, 0xC0, /*       ####       */
+	0x00, 0x30, /*           ##     */
+
+	/* @1584 'x' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x08, 0x10, /*     #      #     */
+	0x0C, 0x30, /*     ##    ##     */
+	0x02, 0x40, /*       #  #       */
+	0x01, 0x80, /*        ##        */
+	0x02, 0x40, /*       #  #       */
+	0x0C, 0x30, /*     ##    ##     */
+	0x08, 0x10, /*     #      #     */
+	0x00, 0x00, /*                  */
+
+	/* @1602 'y' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x10, /*            #     */
+	0x40, 0xE0, /*  #      ###      */
+	0x43, 0x00, /*  #    ##         */
+	0x3C, 0x00, /*   ####           */
+	0x07, 0x00, /*      ###         */
+	0x00, 0xE0, /*         ###      */
+	0x00, 0x10, /*            #     */
+	0x00, 0x00, /*                  */
+
+	/* @1620 'z' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0C, 0x10, /*     ##     #     */
+	0x0A, 0x10, /*     # #    #     */
+	0x09, 0x10, /*     #  #   #     */
+	0x09, 0x10, /*     #  #   #     */
+	0x08, 0x90, /*     #   #  #     */
+	0x08, 0x50, /*     #    # #     */
+	0x08, 0x30, /*     #     ##     */
+	0x00, 0x00, /*                  */
+
+	/* @1638 '{' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x80, /*         #        */
+	0x00, 0x80, /*         #        */
+	0x3F, 0x7C, /*   ###### #####   */
+	0x40, 0x02, /*  #            #  */
+	0x40, 0x02, /*  #            #  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1656 '|' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xFF, 0xFE, /* ###############  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1674 '}' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x40, 0x02, /*  #            #  */
+	0x40, 0x02, /*  #            #  */
+	0x3F, 0x7C, /*   ###### #####   */
+	0x00, 0x80, /*         #        */
+	0x00, 0x80, /*         #        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1692 '~' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x80, /*         #        */
+	0x00, 0x40, /*          #       */
+	0x00, 0x40, /*          #       */
+	0x00, 0x40, /*          #       */
+	0x00, 0x80, /*         #        */
+	0x00, 0x80, /*         #        */
+	0x00, 0x80, /*         #        */
+	0x00, 0x40, /*          #       */
+};
+
+/* Character descriptors for Bitstream Vera Sans Mono 11pt */
+/* { [Char width in bits], [Offset into bitstreamVeraSansMono11ptCharBitmaps in bytes] } */
+const FONT_CHAR_INFO bitstreamVeraSansMono11ptCharDescriptors[] =
+{
+	{9, 0}, 		/*   */
+	{9, 18}, 		/* ! */
+	{9, 36}, 		/* " */
+	{9, 54}, 		/* # */
+	{9, 72}, 		/* $ */
+	{9, 90}, 		/* % */
+	{9, 108}, 		/* & */
+	{9, 126}, 		/* ' */
+	{9, 144}, 		/* ( */
+	{9, 162}, 		/* ) */
+	{9, 180}, 		/* * */
+	{9, 198}, 		/* + */
+	{9, 216}, 		/* , */
+	{9, 234}, 		/* - */
+	{9, 252}, 		/* . */
+	{9, 270}, 		/* / */
+	{9, 288}, 		/* 0 */
+	{9, 306}, 		/* 1 */
+	{9, 324}, 		/* 2 */
+	{9, 342}, 		/* 3 */
+	{9, 360}, 		/* 4 */
+	{9, 378}, 		/* 5 */
+	{9, 396}, 		/* 6 */
+	{9, 414}, 		/* 7 */
+	{9, 432}, 		/* 8 */
+	{9, 450}, 		/* 9 */
+	{9, 468}, 		/* : */
+	{9, 486}, 		/* ; */
+	{9, 504}, 		/* < */
+	{9, 522}, 		/* = */
+	{9, 540}, 		/* > */
+	{9, 558}, 		/* ? */
+	{9, 576}, 		/* @ */
+	{9, 594}, 		/* A */
+	{9, 612}, 		/* B */
+	{9, 630}, 		/* C */
+	{9, 648}, 		/* D */
+	{9, 666}, 		/* E */
+	{9, 684}, 		/* F */
+	{9, 702}, 		/* G */
+	{9, 720}, 		/* H */
+	{9, 738}, 		/* I */
+	{9, 756}, 		/* J */
+	{9, 774}, 		/* K */
+	{9, 792}, 		/* L */
+	{9, 810}, 		/* M */
+	{9, 828}, 		/* N */
+	{9, 846}, 		/* O */
+	{9, 864}, 		/* P */
+	{9, 882}, 		/* Q */
+	{9, 900}, 		/* R */
+	{9, 918}, 		/* S */
+	{9, 936}, 		/* T */
+	{9, 954}, 		/* U */
+	{9, 972}, 		/* V */
+	{9, 990}, 		/* W */
+	{9, 1008}, 		/* X */
+	{9, 1026}, 		/* Y */
+	{9, 1044}, 		/* Z */
+	{9, 1062}, 		/* [ */
+	{9, 1080}, 		/* \ */
+	{9, 1098}, 		/* ] */
+	{9, 1116}, 		/* ^ */
+	{9, 1134}, 		/* _ */
+	{9, 1152}, 		/* ` */
+	{9, 1170}, 		/* a */
+	{9, 1188}, 		/* b */
+	{9, 1206}, 		/* c */
+	{9, 1224}, 		/* d */
+	{9, 1242}, 		/* e */
+	{9, 1260}, 		/* f */
+	{9, 1278}, 		/* g */
+	{9, 1296}, 		/* h */
+	{9, 1314}, 		/* i */
+	{9, 1332}, 		/* j */
+	{9, 1350}, 		/* k */
+	{9, 1368}, 		/* l */
+	{9, 1386}, 		/* m */
+	{9, 1404}, 		/* n */
+	{9, 1422}, 		/* o */
+	{9, 1440}, 		/* p */
+	{9, 1458}, 		/* q */
+	{9, 1476}, 		/* r */
+	{9, 1494}, 		/* s */
+	{9, 1512}, 		/* t */
+	{9, 1530}, 		/* u */
+	{9, 1548}, 		/* v */
+	{9, 1566}, 		/* w */
+	{9, 1584}, 		/* x */
+	{9, 1602}, 		/* y */
+	{9, 1620}, 		/* z */
+	{9, 1638}, 		/* { */
+	{9, 1656}, 		/* | */
+	{9, 1674}, 		/* } */
+	{9, 1692}, 		/* ~ */
+};
+
+/* Font information for Bitstream Vera Sans Mono 11pt */
+const FONT_INFO bitstreamVeraSansMono11ptFontInfo =
+{
+	2, /*  Character height */
+	' ', /*  Start character */
+	'~', /*  End character */
+	bitstreamVeraSansMono11ptCharDescriptors, /*  Character decriptor array */
+	bitstreamVeraSansMono11ptCharBitmaps, /*  Character bitmap array */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramono11.h b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramono11.h
new file mode 100644
index 0000000000000000000000000000000000000000..36cf65b50b3f15675d02f9cc1cf757d3b31c5ada
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramono11.h
@@ -0,0 +1,19 @@
+#ifndef __VERA_MONO_11__
+#define __VERA_MONO_11__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../fonts.h"
+
+/* Font data for Bitstream Vera Sans Mono 11pt */
+extern const uint8_t bitstreamVeraSansMono11ptCharBitmaps[];
+extern const FONT_CHAR_INFO bitstreamVeraSansMono11ptCharDescriptors[];
+extern const FONT_INFO bitstreamVeraSansMono11ptFontInfo;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramono9.c b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramono9.c
new file mode 100644
index 0000000000000000000000000000000000000000..1a0862ba3e3c4f481fe779cec39148d9757baea6
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramono9.c
@@ -0,0 +1,1070 @@
+#include "veramono9.h"
+
+/* 
+**  Font data for Bitstream Vera Sans Mono 9pt
+*/
+
+/* Character bitmaps for Bitstream Vera Sans Mono 9pt */
+const uint8_t bitstreamVeraSansMono9ptCharBitmaps[] = 
+{
+	/* @0 ' ' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @16 '!' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x1B, 0xF0, /*    ## ######     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @32 '"' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x70, /*          ###     */
+	0x00, 0x00, /*                  */
+	0x00, 0x70, /*          ###     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @48 '#' (8 pixels wide) */
+	0x04, 0x00, /*      #           */
+	0x1C, 0x80, /*    ###  #        */
+	0x07, 0xC0, /*      #####       */
+	0x14, 0xA0, /*    # #  # #      */
+	0x0F, 0x80, /*     #####        */
+	0x04, 0xE0, /*      #  ###      */
+	0x00, 0x80, /*         #        */
+	0x00, 0x00, /*                  */
+
+	/* @64 '$' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x09, 0xC0, /*     #  ###       */
+	0x11, 0x20, /*    #   #  #      */
+	0x7F, 0xF0, /*  ###########     */
+	0x12, 0x20, /*    #  #   #      */
+	0x0E, 0x40, /*     ###  #       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @80 '%' (8 pixels wide) */
+	0x00, 0x60, /*          ##      */
+	0x02, 0x90, /*       # #  #     */
+	0x02, 0x90, /*       # #  #     */
+	0x0D, 0x60, /*     ## # ##      */
+	0x13, 0x00, /*    #  ##         */
+	0x12, 0x80, /*    #  # #        */
+	0x0C, 0x00, /*     ##           */
+	0x00, 0x00, /*                  */
+
+	/* @96 '&' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0E, 0x00, /*     ###          */
+	0x19, 0xE0, /*    ##  ####      */
+	0x11, 0x90, /*    #   ##  #     */
+	0x16, 0x10, /*    # ##    #     */
+	0x0C, 0x10, /*     ##     #     */
+	0x16, 0x00, /*    # ##          */
+	0x00, 0x00, /*                  */
+
+	/* @112 ''' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x70, /*          ###     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @128 '(' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x07, 0xC0, /*      #####       */
+	0x38, 0x38, /*   ###     ###    */
+	0x20, 0x08, /*   #         #    */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @144 ')' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x20, 0x08, /*   #         #    */
+	0x38, 0x38, /*   ###     ###    */
+	0x07, 0xC0, /*      #####       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @160 '*' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x01, 0x20, /*        #  #      */
+	0x00, 0xC0, /*         ##       */
+	0x03, 0xF0, /*       ######     */
+	0x00, 0xC0, /*         ##       */
+	0x01, 0x20, /*        #  #      */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @176 '+' (8 pixels wide) */
+	0x02, 0x00, /*       #          */
+	0x02, 0x00, /*       #          */
+	0x02, 0x00, /*       #          */
+	0x1F, 0xC0, /*    #######       */
+	0x02, 0x00, /*       #          */
+	0x02, 0x00, /*       #          */
+	0x02, 0x00, /*       #          */
+	0x00, 0x00, /*                  */
+
+	/* @192 ',' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x20, 0x00, /*   #              */
+	0x18, 0x00, /*    ##            */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @208 '-' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x02, 0x00, /*       #          */
+	0x02, 0x00, /*       #          */
+	0x02, 0x00, /*       #          */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @224 '.' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x18, 0x00, /*    ##            */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @240 '/' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x20, 0x00, /*   #              */
+	0x18, 0x00, /*    ##            */
+	0x06, 0x00, /*      ##          */
+	0x01, 0x80, /*        ##        */
+	0x00, 0x60, /*          ##      */
+	0x00, 0x10, /*            #     */
+	0x00, 0x00, /*                  */
+
+	/* @256 '0' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xC0, /*      #####       */
+	0x18, 0x30, /*    ##     ##     */
+	0x10, 0x10, /*    #       #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x18, 0x30, /*    ##     ##     */
+	0x07, 0xC0, /*      #####       */
+	0x00, 0x00, /*                  */
+
+	/* @272 '1' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x10, 0x10, /*    #       #     */
+	0x10, 0x10, /*    #       #     */
+	0x1F, 0xF0, /*    #########     */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @288 '2' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x10, 0x20, /*    #      #      */
+	0x18, 0x10, /*    ##      #     */
+	0x14, 0x10, /*    # #     #     */
+	0x12, 0x10, /*    #  #    #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x10, 0xE0, /*    #    ###      */
+	0x00, 0x00, /*                  */
+
+	/* @304 '3' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x08, 0x20, /*     #     #      */
+	0x10, 0x10, /*    #       #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x0E, 0xE0, /*     ### ###      */
+	0x00, 0x00, /*                  */
+
+	/* @320 '4' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x06, 0x00, /*      ##          */
+	0x05, 0x80, /*      # ##        */
+	0x04, 0xC0, /*      #  ##       */
+	0x04, 0x30, /*      #    ##     */
+	0x1F, 0xF0, /*    #########     */
+	0x04, 0x00, /*      #           */
+	0x00, 0x00, /*                  */
+
+	/* @336 '5' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x08, 0xF0, /*     #   ####     */
+	0x10, 0x90, /*    #    #  #     */
+	0x10, 0x90, /*    #    #  #     */
+	0x10, 0x90, /*    #    #  #     */
+	0x19, 0x90, /*    ##  ##  #     */
+	0x0F, 0x00, /*     ####         */
+	0x00, 0x00, /*                  */
+
+	/* @352 '6' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xC0, /*      #####       */
+	0x19, 0x20, /*    ##  #  #      */
+	0x10, 0x90, /*    #    #  #     */
+	0x10, 0x90, /*    #    #  #     */
+	0x19, 0x90, /*    ##  ##  #     */
+	0x0F, 0x20, /*     ####  #      */
+	0x00, 0x00, /*                  */
+
+	/* @368 '7' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x10, /*            #     */
+	0x10, 0x10, /*    #       #     */
+	0x0C, 0x10, /*     ##     #     */
+	0x03, 0x10, /*       ##   #     */
+	0x00, 0xF0, /*         ####     */
+	0x00, 0x30, /*           ##     */
+	0x00, 0x00, /*                  */
+
+	/* @384 '8' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0E, 0xE0, /*     ### ###      */
+	0x11, 0x10, /*    #   #   #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x0E, 0xE0, /*     ### ###      */
+	0x00, 0x00, /*                  */
+
+	/* @400 '9' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x09, 0xE0, /*     #  ####      */
+	0x13, 0x30, /*    #  ##  ##     */
+	0x12, 0x10, /*    #  #    #     */
+	0x12, 0x10, /*    #  #    #     */
+	0x09, 0x30, /*     #  #  ##     */
+	0x07, 0xC0, /*      #####       */
+	0x00, 0x00, /*                  */
+
+	/* @416 ':' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x19, 0x80, /*    ##  ##        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @432 ';' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x20, 0x00, /*   #              */
+	0x19, 0x80, /*    ##  ##        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @448 '<' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0x00, /*       ##         */
+	0x03, 0x00, /*       ##         */
+	0x04, 0x80, /*      #  #        */
+	0x04, 0x80, /*      #  #        */
+	0x04, 0x80, /*      #  #        */
+	0x08, 0x40, /*     #    #       */
+	0x00, 0x00, /*                  */
+
+	/* @464 '=' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x05, 0x00, /*      # #         */
+	0x05, 0x00, /*      # #         */
+	0x05, 0x00, /*      # #         */
+	0x05, 0x00, /*      # #         */
+	0x05, 0x00, /*      # #         */
+	0x05, 0x00, /*      # #         */
+	0x00, 0x00, /*                  */
+
+	/* @480 '>' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x08, 0x40, /*     #    #       */
+	0x04, 0x80, /*      #  #        */
+	0x04, 0x80, /*      #  #        */
+	0x04, 0x80, /*      #  #        */
+	0x03, 0x00, /*       ##         */
+	0x03, 0x00, /*       ##         */
+	0x00, 0x00, /*                  */
+
+	/* @496 '?' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x20, /*           #      */
+	0x1B, 0x10, /*    ## ##   #     */
+	0x01, 0x90, /*        ##  #     */
+	0x00, 0x90, /*         #  #     */
+	0x00, 0x60, /*          ##      */
+	0x00, 0x00, /*                  */
+
+	/* @512 '@' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0x80, /*    ######        */
+	0x30, 0x40, /*   ##     #       */
+	0x46, 0x20, /*  #   ##   #      */
+	0x49, 0x20, /*  #  #  #  #      */
+	0x49, 0x60, /*  #  #  # ##      */
+	0x0F, 0xC0, /*     ######       */
+	0x00, 0x00, /*                  */
+
+	/* @528 'A' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x18, 0x00, /*    ##            */
+	0x07, 0x80, /*      ####        */
+	0x04, 0x70, /*      #   ###     */
+	0x04, 0x70, /*      #   ###     */
+	0x07, 0x80, /*      ####        */
+	0x18, 0x00, /*    ##            */
+	0x00, 0x00, /*                  */
+
+	/* @544 'B' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x11, 0x10, /*    #   #   #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x0E, 0xE0, /*     ### ###      */
+	0x00, 0x00, /*                  */
+
+	/* @560 'C' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xC0, /*      #####       */
+	0x08, 0x20, /*     #     #      */
+	0x10, 0x10, /*    #       #     */
+	0x10, 0x10, /*    #       #     */
+	0x10, 0x10, /*    #       #     */
+	0x08, 0x20, /*     #     #      */
+	0x00, 0x00, /*                  */
+
+	/* @576 'D' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x10, 0x10, /*    #       #     */
+	0x10, 0x10, /*    #       #     */
+	0x10, 0x10, /*    #       #     */
+	0x08, 0x20, /*     #     #      */
+	0x07, 0xC0, /*      #####       */
+	0x00, 0x00, /*                  */
+
+	/* @592 'E' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x11, 0x10, /*    #   #   #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x00, 0x00, /*                  */
+
+	/* @608 'F' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x01, 0x10, /*        #   #     */
+	0x01, 0x10, /*        #   #     */
+	0x01, 0x10, /*        #   #     */
+	0x01, 0x10, /*        #   #     */
+	0x01, 0x10, /*        #   #     */
+	0x00, 0x00, /*                  */
+
+	/* @624 'G' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xC0, /*      #####       */
+	0x08, 0x20, /*     #     #      */
+	0x10, 0x10, /*    #       #     */
+	0x10, 0x10, /*    #       #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x0F, 0x20, /*     ####  #      */
+	0x00, 0x00, /*                  */
+
+	/* @640 'H' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x01, 0x00, /*        #         */
+	0x01, 0x00, /*        #         */
+	0x01, 0x00, /*        #         */
+	0x01, 0x00, /*        #         */
+	0x1F, 0xF0, /*    #########     */
+	0x00, 0x00, /*                  */
+
+	/* @656 'I' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x10, 0x10, /*    #       #     */
+	0x10, 0x10, /*    #       #     */
+	0x1F, 0xF0, /*    #########     */
+	0x10, 0x10, /*    #       #     */
+	0x10, 0x10, /*    #       #     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @672 'J' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x08, 0x00, /*     #            */
+	0x10, 0x00, /*    #             */
+	0x10, 0x10, /*    #       #     */
+	0x10, 0x10, /*    #       #     */
+	0x0F, 0xF0, /*     ########     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @688 'K' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x01, 0x00, /*        #         */
+	0x01, 0x80, /*        ##        */
+	0x06, 0x40, /*      ##  #       */
+	0x0C, 0x20, /*     ##    #      */
+	0x10, 0x10, /*    #       #     */
+	0x00, 0x00, /*                  */
+
+	/* @704 'L' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x00, 0x00, /*                  */
+
+	/* @720 'M' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x00, 0x60, /*          ##      */
+	0x03, 0x80, /*       ###        */
+	0x03, 0x80, /*       ###        */
+	0x00, 0x60, /*          ##      */
+	0x1F, 0xF0, /*    #########     */
+	0x00, 0x00, /*                  */
+
+	/* @736 'N' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x00, 0x30, /*           ##     */
+	0x01, 0xC0, /*        ###       */
+	0x07, 0x00, /*      ###         */
+	0x18, 0x00, /*    ##            */
+	0x1F, 0xF0, /*    #########     */
+	0x00, 0x00, /*                  */
+
+	/* @752 'O' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xC0, /*      #####       */
+	0x18, 0x30, /*    ##     ##     */
+	0x10, 0x10, /*    #       #     */
+	0x10, 0x10, /*    #       #     */
+	0x18, 0x30, /*    ##     ##     */
+	0x07, 0xC0, /*      #####       */
+	0x00, 0x00, /*                  */
+
+	/* @768 'P' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x01, 0x10, /*        #   #     */
+	0x01, 0x10, /*        #   #     */
+	0x01, 0x10, /*        #   #     */
+	0x01, 0x10, /*        #   #     */
+	0x00, 0xE0, /*         ###      */
+	0x00, 0x00, /*                  */
+
+	/* @784 'Q' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xC0, /*      #####       */
+	0x18, 0x30, /*    ##     ##     */
+	0x10, 0x10, /*    #       #     */
+	0x10, 0x10, /*    #       #     */
+	0x78, 0x30, /*  ####     ##     */
+	0x0F, 0xC0, /*     ######       */
+	0x00, 0x00, /*                  */
+
+	/* @800 'R' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x01, 0x10, /*        #   #     */
+	0x01, 0x10, /*        #   #     */
+	0x01, 0x10, /*        #   #     */
+	0x03, 0x10, /*       ##   #     */
+	0x0C, 0xE0, /*     ##  ###      */
+	0x10, 0x00, /*    #             */
+
+	/* @816 'S' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x08, 0xE0, /*     #   ###      */
+	0x11, 0x90, /*    #   ##  #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x0E, 0x20, /*     ###   #      */
+	0x00, 0x00, /*                  */
+
+	/* @832 'T' (8 pixels wide) */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x1F, 0xF0, /*    #########     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x00, /*                  */
+
+	/* @848 'U' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xF0, /*     ########     */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x0F, 0xF0, /*     ########     */
+	0x00, 0x00, /*                  */
+
+	/* @864 'V' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x30, /*           ##     */
+	0x03, 0xC0, /*       ####       */
+	0x1C, 0x00, /*    ###           */
+	0x1C, 0x00, /*    ###           */
+	0x03, 0xC0, /*       ####       */
+	0x00, 0x30, /*           ##     */
+	0x00, 0x00, /*                  */
+
+	/* @880 'W' (8 pixels wide) */
+	0x03, 0xF0, /*       ######     */
+	0x1C, 0x00, /*    ###           */
+	0x07, 0x80, /*      ####        */
+	0x00, 0x60, /*          ##      */
+	0x07, 0x80, /*      ####        */
+	0x1C, 0x00, /*    ###           */
+	0x03, 0xF0, /*       ######     */
+	0x00, 0x00, /*                  */
+
+	/* @896 'X' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x10, 0x10, /*    #       #     */
+	0x0C, 0x60, /*     ##   ##      */
+	0x03, 0x80, /*       ###        */
+	0x03, 0x80, /*       ###        */
+	0x0C, 0x60, /*     ##   ##      */
+	0x10, 0x10, /*    #       #     */
+	0x00, 0x00, /*                  */
+
+	/* @912 'Y' (8 pixels wide) */
+	0x00, 0x10, /*            #     */
+	0x00, 0x20, /*           #      */
+	0x00, 0xC0, /*         ##       */
+	0x1F, 0x00, /*    #####         */
+	0x00, 0xC0, /*         ##       */
+	0x00, 0x20, /*           #      */
+	0x00, 0x10, /*            #     */
+	0x00, 0x00, /*                  */
+
+	/* @928 'Z' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x18, 0x10, /*    ##      #     */
+	0x1C, 0x10, /*    ###     #     */
+	0x13, 0x10, /*    #  ##   #     */
+	0x11, 0x90, /*    #   ##  #     */
+	0x10, 0x70, /*    #     ###     */
+	0x10, 0x30, /*    #      ##     */
+	0x00, 0x00, /*                  */
+
+	/* @944 '[' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x3F, 0xF8, /*   ###########    */
+	0x20, 0x08, /*   #         #    */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @960 '\' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x10, /*            #     */
+	0x00, 0x60, /*          ##      */
+	0x01, 0x80, /*        ##        */
+	0x06, 0x00, /*      ##          */
+	0x18, 0x00, /*    ##            */
+	0x20, 0x00, /*   #              */
+	0x00, 0x00, /*                  */
+
+	/* @976 ']' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x20, 0x08, /*   #         #    */
+	0x3F, 0xF8, /*   ###########    */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @992 '^' (8 pixels wide) */
+	0x00, 0x40, /*          #       */
+	0x00, 0x20, /*           #      */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x20, /*           #      */
+	0x00, 0x40, /*          #       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1008 '_' (8 pixels wide) */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1024 '`' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x08, /*             #    */
+	0x00, 0x10, /*            #     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1040 'a' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0C, 0x80, /*     ##  #        */
+	0x12, 0x40, /*    #  #  #       */
+	0x12, 0x40, /*    #  #  #       */
+	0x12, 0x40, /*    #  #  #       */
+	0x1F, 0x80, /*    ######        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1056 'b' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF8, /*    ##########    */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0x0F, 0x80, /*     #####        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1072 'c' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0x80, /*     #####        */
+	0x18, 0xC0, /*    ##   ##       */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x80, /*    #    #        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1088 'd' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0x80, /*     #####        */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0x1F, 0xF8, /*    ##########    */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1104 'e' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0x80, /*     #####        */
+	0x12, 0xC0, /*    #  # ##       */
+	0x12, 0x40, /*    #  #  #       */
+	0x12, 0x40, /*    #  #  #       */
+	0x0B, 0x80, /*     # ###        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1120 'f' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x40, /*          #       */
+	0x00, 0x40, /*          #       */
+	0x1F, 0xF0, /*    #########     */
+	0x00, 0x48, /*          #  #    */
+	0x00, 0x48, /*          #  #    */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1136 'g' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0x80, /*     #####        */
+	0x58, 0x40, /*  # ##    #       */
+	0x90, 0x40, /* #  #     #       */
+	0x90, 0x40, /* #  #     #       */
+	0x7F, 0xC0, /*  #########       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1152 'h' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF8, /*    ##########    */
+	0x00, 0x80, /*         #        */
+	0x00, 0x40, /*          #       */
+	0x00, 0x40, /*          #       */
+	0x1F, 0x80, /*    ######        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1168 'i' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0x1F, 0xC8, /*    #######  #    */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1184 'j' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x80, 0x40, /* #        #       */
+	0x80, 0x40, /* #        #       */
+	0x7F, 0xC8, /*  #########  #    */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1200 'k' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF8, /*    ##########    */
+	0x02, 0x00, /*       #          */
+	0x05, 0x00, /*      # #         */
+	0x08, 0x80, /*     #   #        */
+	0x10, 0x40, /*    #     #       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1216 'l' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x08, /*             #    */
+	0x00, 0x08, /*             #    */
+	0x0F, 0xF8, /*     #########    */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1232 'm' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xC0, /*    #######       */
+	0x00, 0x40, /*          #       */
+	0x1F, 0xC0, /*    #######       */
+	0x00, 0x40, /*          #       */
+	0x1F, 0xC0, /*    #######       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1248 'n' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xC0, /*    #######       */
+	0x00, 0x80, /*         #        */
+	0x00, 0x40, /*          #       */
+	0x00, 0x40, /*          #       */
+	0x1F, 0x80, /*    ######        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1264 'o' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0x80, /*     #####        */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0x0F, 0x80, /*     #####        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1280 'p' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xFF, 0xC0, /* ##########       */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0x0F, 0x80, /*     #####        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1296 'q' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0x80, /*     #####        */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0xFF, 0xC0, /* ##########       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1312 'r' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x1F, 0xC0, /*    #######       */
+	0x00, 0xC0, /*         ##       */
+	0x00, 0x40, /*          #       */
+	0x00, 0x40, /*          #       */
+	0x00, 0x80, /*         #        */
+	0x00, 0x00, /*                  */
+
+	/* @1328 's' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x09, 0x80, /*     #  ##        */
+	0x12, 0x40, /*    #  #  #       */
+	0x12, 0x40, /*    #  #  #       */
+	0x12, 0x40, /*    #  #  #       */
+	0x0C, 0x80, /*     ##  #        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1344 't' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x40, /*          #       */
+	0x00, 0x40, /*          #       */
+	0x1F, 0xF0, /*    #########     */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1360 'u' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xC0, /*     ######       */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x1F, 0xC0, /*    #######       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1376 'v' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0xC0, /*         ##       */
+	0x07, 0x00, /*      ###         */
+	0x18, 0x00, /*    ##            */
+	0x07, 0x00, /*      ###         */
+	0x00, 0xC0, /*         ##       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1392 'w' (8 pixels wide) */
+	0x00, 0xC0, /*         ##       */
+	0x07, 0x00, /*      ###         */
+	0x1C, 0x00, /*    ###           */
+	0x03, 0x00, /*       ##         */
+	0x1C, 0x00, /*    ###           */
+	0x07, 0x00, /*      ###         */
+	0x00, 0xC0, /*         ##       */
+	0x00, 0x00, /*                  */
+
+	/* @1408 'x' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x10, 0x40, /*    #     #       */
+	0x0D, 0x80, /*     ## ##        */
+	0x02, 0x00, /*       #          */
+	0x0D, 0x80, /*     ## ##        */
+	0x10, 0x40, /*    #     #       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1424 'y' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x80, 0xC0, /* #       ##       */
+	0xCF, 0x00, /* ##  ####         */
+	0x38, 0x00, /*   ###            */
+	0x07, 0x00, /*      ###         */
+	0x00, 0xC0, /*         ##       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1440 'z' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x18, 0x40, /*    ##    #       */
+	0x14, 0x40, /*    # #   #       */
+	0x12, 0x40, /*    #  #  #       */
+	0x11, 0x40, /*    #   # #       */
+	0x10, 0xC0, /*    #    ##       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1456 '{' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x01, 0x00, /*        #         */
+	0x01, 0x00, /*        #         */
+	0x3E, 0xF8, /*   ##### #####    */
+	0x20, 0x08, /*   #         #    */
+	0x20, 0x08, /*   #         #    */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1472 '|' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x7F, 0xF8, /*  ############    */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1488 '}' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x20, 0x08, /*   #         #    */
+	0x20, 0x08, /*   #         #    */
+	0x3E, 0xF8, /*   ##### #####    */
+	0x01, 0x00, /*        #         */
+	0x01, 0x00, /*        #         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1504 '~' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x01, 0x00, /*        #         */
+	0x01, 0x00, /*        #         */
+	0x01, 0x00, /*        #         */
+	0x02, 0x00, /*       #          */
+	0x02, 0x00, /*       #          */
+	0x02, 0x00, /*       #          */
+	0x00, 0x00, /*                  */
+};
+
+/* Character descriptors for Bitstream Vera Sans Mono 9pt */
+/* { [Char width in bits], [Offset into bitstreamVeraSansMono9ptCharBitmaps in bytes] } */
+const FONT_CHAR_INFO bitstreamVeraSansMono9ptCharDescriptors[] =
+{
+	{8, 0}, 		/*   */
+	{8, 16}, 		/* ! */
+	{8, 32}, 		/* " */
+	{8, 48}, 		/* # */
+	{8, 64}, 		/* $ */
+	{8, 80}, 		/* % */
+	{8, 96}, 		/* & */
+	{8, 112}, 		/* ' */
+	{8, 128}, 		/* ( */
+	{8, 144}, 		/* ) */
+	{8, 160}, 		/* * */
+	{8, 176}, 		/* + */
+	{8, 192}, 		/* , */
+	{8, 208}, 		/* - */
+	{8, 224}, 		/* . */
+	{8, 240}, 		/* / */
+	{8, 256}, 		/* 0 */
+	{8, 272}, 		/* 1 */
+	{8, 288}, 		/* 2 */
+	{8, 304}, 		/* 3 */
+	{8, 320}, 		/* 4 */
+	{8, 336}, 		/* 5 */
+	{8, 352}, 		/* 6 */
+	{8, 368}, 		/* 7 */
+	{8, 384}, 		/* 8 */
+	{8, 400}, 		/* 9 */
+	{8, 416}, 		/* : */
+	{8, 432}, 		/* ; */
+	{8, 448}, 		/* < */
+	{8, 464}, 		/* = */
+	{8, 480}, 		/* > */
+	{8, 496}, 		/* ? */
+	{8, 512}, 		/* @ */
+	{8, 528}, 		/* A */
+	{8, 544}, 		/* B */
+	{8, 560}, 		/* C */
+	{8, 576}, 		/* D */
+	{8, 592}, 		/* E */
+	{8, 608}, 		/* F */
+	{8, 624}, 		/* G */
+	{8, 640}, 		/* H */
+	{8, 656}, 		/* I */
+	{8, 672}, 		/* J */
+	{8, 688}, 		/* K */
+	{8, 704}, 		/* L */
+	{8, 720}, 		/* M */
+	{8, 736}, 		/* N */
+	{8, 752}, 		/* O */
+	{8, 768}, 		/* P */
+	{8, 784}, 		/* Q */
+	{8, 800}, 		/* R */
+	{8, 816}, 		/* S */
+	{8, 832}, 		/* T */
+	{8, 848}, 		/* U */
+	{8, 864}, 		/* V */
+	{8, 880}, 		/* W */
+	{8, 896}, 		/* X */
+	{8, 912}, 		/* Y */
+	{8, 928}, 		/* Z */
+	{8, 944}, 		/* [ */
+	{8, 960}, 		/* \ */
+	{8, 976}, 		/* ] */
+	{8, 992}, 		/* ^ */
+	{8, 1008}, 		/* _ */
+	{8, 1024}, 		/* ` */
+	{8, 1040}, 		/* a */
+	{8, 1056}, 		/* b */
+	{8, 1072}, 		/* c */
+	{8, 1088}, 		/* d */
+	{8, 1104}, 		/* e */
+	{8, 1120}, 		/* f */
+	{8, 1136}, 		/* g */
+	{8, 1152}, 		/* h */
+	{8, 1168}, 		/* i */
+	{8, 1184}, 		/* j */
+	{8, 1200}, 		/* k */
+	{8, 1216}, 		/* l */
+	{8, 1232}, 		/* m */
+	{8, 1248}, 		/* n */
+	{8, 1264}, 		/* o */
+	{8, 1280}, 		/* p */
+	{8, 1296}, 		/* q */
+	{8, 1312}, 		/* r */
+	{8, 1328}, 		/* s */
+	{8, 1344}, 		/* t */
+	{8, 1360}, 		/* u */
+	{8, 1376}, 		/* v */
+	{8, 1392}, 		/* w */
+	{8, 1408}, 		/* x */
+	{8, 1424}, 		/* y */
+	{8, 1440}, 		/* z */
+	{8, 1456}, 		/* { */
+	{8, 1472}, 		/* | */
+	{8, 1488}, 		/* } */
+	{8, 1504}, 		/* ~ */
+};
+
+/* Font information for Bitstream Vera Sans Mono 9pt */
+const FONT_INFO bitstreamVeraSansMono9ptFontInfo =
+{
+	2, /*  Character height */
+	' ', /*  Start character */
+	'~', /*  End character */
+	bitstreamVeraSansMono9ptCharDescriptors, /*  Character decriptor array */
+	bitstreamVeraSansMono9ptCharBitmaps, /*  Character bitmap array */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramono9.h b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramono9.h
new file mode 100644
index 0000000000000000000000000000000000000000..63af9b26f004d359a9bdefc4f65b0b0752c71529
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramono9.h
@@ -0,0 +1,19 @@
+#ifndef __VERA_MONO_9__
+#define __VERA_MONO_9__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../fonts.h"
+
+/* Font data for Bitstream Vera Sans Mono 9pt */
+extern const uint8_t bitstreamVeraSansMono9ptCharBitmaps[];
+extern const FONT_CHAR_INFO bitstreamVeraSansMono9ptCharDescriptors[];
+extern const FONT_INFO bitstreamVeraSansMono9ptFontInfo;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramonobold11.c b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramonobold11.c
new file mode 100644
index 0000000000000000000000000000000000000000..43b380f685ec39ed750db46b39d881b392284114
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramonobold11.c
@@ -0,0 +1,1165 @@
+#include "veramonobold11.h"
+
+/* 
+**  Font data for Bitstream Vera Sans Mono Bold 11pt
+*/
+
+/* Character bitmaps for Bitstream Vera Sans Mono Bold 11pt */
+const uint8_t bitstreamVeraSansMonoBold11ptCharBitmaps[] = 
+{
+	/* @0 ' ' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @18 '!' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x0D, 0xFE, /*     ## ########  */
+	0x0D, 0xFE, /*     ## ########  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @36 '"' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x1E, /*            ####  */
+	0x00, 0x1E, /*            ####  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x1E, /*            ####  */
+	0x00, 0x1E, /*            ####  */
+	0x00, 0x00, /*                  */
+
+	/* @54 '#' (9 pixels wide) */
+	0x01, 0x00, /*        #         */
+	0x0F, 0x10, /*     ####   #     */
+	0x0F, 0xF0, /*     ########     */
+	0x01, 0xFE, /*        ########  */
+	0x0D, 0x1E, /*     ## #   ####  */
+	0x0F, 0xF0, /*     ########     */
+	0x01, 0xFC, /*        #######   */
+	0x01, 0x1E, /*        #   ####  */
+	0x00, 0x10, /*            #     */
+
+	/* @72 '$' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x04, 0x38, /*      #    ###    */
+	0x0C, 0x7C, /*     ##   #####   */
+	0x08, 0x64, /*     #    ##  #   */
+	0x3F, 0xFF, /*   ############## */
+	0x08, 0xC4, /*     #   ##   #   */
+	0x0F, 0xCC, /*     ######  ##   */
+	0x07, 0x80, /*      ####        */
+	0x00, 0x00, /*                  */
+
+	/* @90 '%' (9 pixels wide) */
+	0x00, 0x9C, /*         #  ###   */
+	0x00, 0xA2, /*         # #   #  */
+	0x00, 0xA2, /*         # #   #  */
+	0x00, 0x62, /*          ##   #  */
+	0x07, 0x5C, /*      ### # ###   */
+	0x08, 0xC0, /*     #   ##       */
+	0x08, 0xC0, /*     #   ##       */
+	0x08, 0xA0, /*     #   # #      */
+	0x07, 0x20, /*      ###  #      */
+
+	/* @108 '&' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0x80, /*      ####        */
+	0x0F, 0xEC, /*     ####### ##   */
+	0x0C, 0x7E, /*     ##   ######  */
+	0x0B, 0xE2, /*     # #####   #  */
+	0x0F, 0x82, /*     #####     #  */
+	0x0F, 0xC0, /*     ######       */
+	0x09, 0xC0, /*     #  ###       */
+	0x00, 0x00, /*                  */
+
+	/* @126 ''' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x1E, /*            ####  */
+	0x00, 0x1E, /*            ####  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @144 '(' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x07, 0xF0, /*      #######     */
+	0x1F, 0xFC, /*    ###########   */
+	0x38, 0x0E, /*   ###       ###  */
+	0x20, 0x02, /*   #           #  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @162 ')' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x20, 0x02, /*   #           #  */
+	0x38, 0x0E, /*   ###       ###  */
+	0x1F, 0xFC, /*    ###########   */
+	0x07, 0xF0, /*      #######     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @180 '*' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x24, /*           #  #   */
+	0x00, 0x3C, /*           ####   */
+	0x00, 0x18, /*            ##    */
+	0x00, 0x7E, /*          ######  */
+	0x00, 0x18, /*            ##    */
+	0x00, 0x3C, /*           ####   */
+	0x00, 0x24, /*           #  #   */
+	0x00, 0x00, /*                  */
+
+	/* @198 '+' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0xC0, /*         ##       */
+	0x00, 0xC0, /*         ##       */
+	0x00, 0xC0, /*         ##       */
+	0x07, 0xF8, /*      ########    */
+	0x07, 0xF8, /*      ########    */
+	0x00, 0xC0, /*         ##       */
+	0x00, 0xC0, /*         ##       */
+	0x00, 0xC0, /*         ##       */
+
+	/* @216 ',' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x20, 0x00, /*   #              */
+	0x3E, 0x00, /*   #####          */
+	0x1E, 0x00, /*    ####          */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @234 '-' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x01, 0x80, /*        ##        */
+	0x01, 0x80, /*        ##        */
+	0x01, 0x80, /*        ##        */
+	0x01, 0x80, /*        ##        */
+	0x01, 0x80, /*        ##        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @252 '.' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x0E, 0x00, /*     ###          */
+	0x0E, 0x00, /*     ###          */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @270 '/' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x10, 0x00, /*    #             */
+	0x1C, 0x00, /*    ###           */
+	0x0F, 0x00, /*     ####         */
+	0x03, 0xC0, /*       ####       */
+	0x00, 0xF0, /*         ####     */
+	0x00, 0x3C, /*           ####   */
+	0x00, 0x0E, /*             ###  */
+	0x00, 0x02, /*               #  */
+
+	/* @288 '0' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xF8, /*       #######    */
+	0x07, 0xFC, /*      #########   */
+	0x0C, 0x06, /*     ##       ##  */
+	0x08, 0x62, /*     #    ##   #  */
+	0x0C, 0x06, /*     ##       ##  */
+	0x07, 0xFC, /*      #########   */
+	0x03, 0xF8, /*       #######    */
+	0x00, 0x00, /*                  */
+
+	/* @306 '1' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x08, 0x04, /*     #        #   */
+	0x08, 0x02, /*     #         #  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x00, 0x00, /*                  */
+
+	/* @324 '2' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0C, 0x04, /*     ##       #   */
+	0x0E, 0x02, /*     ###       #  */
+	0x0F, 0x02, /*     ####      #  */
+	0x0B, 0x82, /*     # ###     #  */
+	0x09, 0xE2, /*     #  ####   #  */
+	0x08, 0xFC, /*     #   ######   */
+	0x08, 0x7C, /*     #    #####   */
+	0x00, 0x00, /*                  */
+
+	/* @342 '3' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x04, 0x04, /*      #       #   */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x22, /*     #     #   #  */
+	0x08, 0x22, /*     #     #   #  */
+	0x0C, 0x62, /*     ##   ##   #  */
+	0x07, 0xDE, /*      ##### ####  */
+	0x07, 0x9C, /*      ####  ###   */
+	0x00, 0x00, /*                  */
+
+	/* @360 '4' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x01, 0xC0, /*        ###       */
+	0x01, 0x60, /*        # ##      */
+	0x01, 0x38, /*        #  ###    */
+	0x01, 0x0C, /*        #    ##   */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x01, 0x00, /*        #         */
+	0x00, 0x00, /*                  */
+
+	/* @378 '5' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x04, 0x7E, /*      #   ######  */
+	0x08, 0x3E, /*     #     #####  */
+	0x08, 0x22, /*     #     #   #  */
+	0x08, 0x22, /*     #     #   #  */
+	0x0C, 0x62, /*     ##   ##   #  */
+	0x07, 0xC2, /*      #####    #  */
+	0x03, 0x80, /*       ###        */
+	0x00, 0x00, /*                  */
+
+	/* @396 '6' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xF8, /*       #######    */
+	0x07, 0xFC, /*      #########   */
+	0x08, 0x26, /*     #     #  ##  */
+	0x08, 0x22, /*     #     #   #  */
+	0x08, 0x22, /*     #     #   #  */
+	0x0F, 0xE4, /*     #######  #   */
+	0x07, 0xC0, /*      #####       */
+	0x00, 0x00, /*                  */
+
+	/* @414 '7' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x02, /*               #  */
+	0x08, 0x02, /*     #         #  */
+	0x0F, 0x02, /*     ####      #  */
+	0x07, 0xC2, /*      #####    #  */
+	0x01, 0xFA, /*        ###### #  */
+	0x00, 0x3E, /*           #####  */
+	0x00, 0x0E, /*             ###  */
+	0x00, 0x00, /*                  */
+
+	/* @432 '8' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0x9C, /*      ####  ###   */
+	0x0F, 0xDE, /*     ###### ####  */
+	0x0C, 0x62, /*     ##   ##   #  */
+	0x08, 0x22, /*     #     #   #  */
+	0x0C, 0x62, /*     ##   ##   #  */
+	0x0F, 0xDE, /*     ###### ####  */
+	0x07, 0x9C, /*      ####  ###   */
+	0x00, 0x00, /*                  */
+
+	/* @450 '9' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x7C, /*          #####   */
+	0x04, 0xFE, /*      #  #######  */
+	0x08, 0x82, /*     #   #     #  */
+	0x08, 0x82, /*     #   #     #  */
+	0x0C, 0x82, /*     ##  #     #  */
+	0x07, 0xFC, /*      #########   */
+	0x03, 0xF8, /*       #######    */
+	0x00, 0x00, /*                  */
+
+	/* @468 ':' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x0E, 0x70, /*     ###  ###     */
+	0x0E, 0x70, /*     ###  ###     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @486 ';' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x20, 0x00, /*   #              */
+	0x3E, 0x70, /*   #####  ###     */
+	0x1E, 0x70, /*    ####  ###     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @504 '<' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0xC0, /*         ##       */
+	0x00, 0xC0, /*         ##       */
+	0x01, 0xE0, /*        ####      */
+	0x01, 0x20, /*        #  #      */
+	0x03, 0x30, /*       ##  ##     */
+	0x03, 0x30, /*       ##  ##     */
+	0x02, 0x10, /*       #    #     */
+	0x06, 0x18, /*      ##    ##    */
+
+	/* @522 '=' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0x30, /*       ##  ##     */
+	0x03, 0x30, /*       ##  ##     */
+	0x03, 0x30, /*       ##  ##     */
+	0x03, 0x30, /*       ##  ##     */
+	0x03, 0x30, /*       ##  ##     */
+	0x03, 0x30, /*       ##  ##     */
+	0x03, 0x30, /*       ##  ##     */
+	0x03, 0x30, /*       ##  ##     */
+
+	/* @540 '>' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x06, 0x18, /*      ##    ##    */
+	0x02, 0x10, /*       #    #     */
+	0x03, 0x30, /*       ##  ##     */
+	0x03, 0x30, /*       ##  ##     */
+	0x01, 0x20, /*        #  #      */
+	0x01, 0xE0, /*        ####      */
+	0x00, 0xC0, /*         ##       */
+	0x00, 0xC0, /*         ##       */
+
+	/* @558 '?' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x04, /*              #   */
+	0x00, 0x02, /*               #  */
+	0x0D, 0xE2, /*     ## ####   #  */
+	0x0D, 0xF2, /*     ## #####  #  */
+	0x00, 0x3E, /*           #####  */
+	0x00, 0x1C, /*            ###   */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @576 '@' (9 pixels wide) */
+	0x0F, 0xE0, /*     #######      */
+	0x1F, 0xF0, /*    #########     */
+	0x30, 0x18, /*   ##       ##    */
+	0x67, 0xC4, /*  ##  #####   #   */
+	0x4F, 0xE4, /*  #  #######  #   */
+	0x48, 0x24, /*  #  #     #  #   */
+	0x6F, 0xFC, /*  ## ##########   */
+	0x4F, 0xF8, /*  #  #########    */
+	0x00, 0x00, /*                  */
+
+	/* @594 'A' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0C, 0x00, /*     ##           */
+	0x0F, 0xE0, /*     #######      */
+	0x07, 0xFE, /*      ##########  */
+	0x01, 0x1E, /*        #   ####  */
+	0x07, 0xFE, /*      ##########  */
+	0x0F, 0xE0, /*     #######      */
+	0x0C, 0x00, /*     ##           */
+	0x00, 0x00, /*                  */
+
+	/* @612 'B' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x0F, 0xBE, /*     ##### #####  */
+	0x07, 0xBC, /*      #### ####   */
+	0x00, 0x00, /*                  */
+
+	/* @630 'C' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x01, 0xF0, /*        #####     */
+	0x07, 0xFC, /*      #########   */
+	0x0C, 0x06, /*     ##       ##  */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x02, /*     #         #  */
+	0x04, 0x04, /*      #       #   */
+	0x00, 0x00, /*                  */
+
+	/* @648 'D' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x02, /*     #         #  */
+	0x0C, 0x06, /*     ##       ##  */
+	0x07, 0xFC, /*      #########   */
+	0x03, 0xF8, /*       #######    */
+	0x00, 0x00, /*                  */
+
+	/* @666 'E' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x42, /*     #    #    #  */
+	0x08, 0x02, /*     #         #  */
+	0x00, 0x00, /*                  */
+
+	/* @684 'F' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x42, /*          #    #  */
+	0x00, 0x42, /*          #    #  */
+	0x00, 0x42, /*          #    #  */
+	0x00, 0x42, /*          #    #  */
+	0x00, 0x02, /*               #  */
+	0x00, 0x00, /*                  */
+
+	/* @702 'G' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xF0, /*       ######     */
+	0x07, 0xFC, /*      #########   */
+	0x0C, 0x06, /*     ##       ##  */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x82, /*     #   #     #  */
+	0x0F, 0x82, /*     #####     #  */
+	0x0F, 0x84, /*     #####    #   */
+	0x00, 0x00, /*                  */
+
+	/* @720 'H' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x40, /*          #       */
+	0x00, 0x40, /*          #       */
+	0x00, 0x40, /*          #       */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x00, /*                  */
+
+	/* @738 'I' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x02, /*     #         #  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x02, /*     #         #  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @756 'J' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x04, 0x00, /*      #           */
+	0x08, 0x00, /*     #            */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x02, /*     #         #  */
+	0x08, 0x02, /*     #         #  */
+	0x0F, 0xFE, /*     ###########  */
+	0x07, 0xFE, /*      ##########  */
+	0x00, 0x00, /*                  */
+
+	/* @774 'K' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0xE0, /*         ###      */
+	0x00, 0xF8, /*         #####    */
+	0x03, 0xDC, /*       #### ###   */
+	0x0F, 0x8E, /*     #####   ###  */
+	0x0E, 0x06, /*     ###      ##  */
+	0x08, 0x00, /*     #            */
+
+	/* @792 'L' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x00, 0x00, /*                  */
+
+	/* @810 'M' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x7E, /*          ######  */
+	0x00, 0xC0, /*         ##       */
+	0x00, 0x7E, /*          ######  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x00, /*                  */
+
+	/* @828 'N' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x3E, /*           #####  */
+	0x01, 0xF0, /*        #####     */
+	0x0F, 0x80, /*     #####        */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x00, /*                  */
+
+	/* @846 'O' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xF8, /*       #######    */
+	0x07, 0xFC, /*      #########   */
+	0x0C, 0x06, /*     ##       ##  */
+	0x08, 0x02, /*     #         #  */
+	0x0C, 0x06, /*     ##       ##  */
+	0x07, 0xFC, /*      #########   */
+	0x03, 0xF8, /*       #######    */
+	0x00, 0x00, /*                  */
+
+	/* @864 'P' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x82, /*         #     #  */
+	0x00, 0x82, /*         #     #  */
+	0x00, 0xC6, /*         ##   ##  */
+	0x00, 0xFE, /*         #######  */
+	0x00, 0x7C, /*          #####   */
+	0x00, 0x00, /*                  */
+
+	/* @882 'Q' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xF8, /*       #######    */
+	0x07, 0xFC, /*      #########   */
+	0x0C, 0x06, /*     ##       ##  */
+	0x08, 0x02, /*     #         #  */
+	0x1C, 0x06, /*    ###       ##  */
+	0x3F, 0xFC, /*   ############   */
+	0x03, 0xF8, /*       #######    */
+	0x00, 0x00, /*                  */
+
+	/* @900 'R' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x82, /*         #     #  */
+	0x00, 0x82, /*         #     #  */
+	0x03, 0x82, /*       ###     #  */
+	0x0F, 0x7E, /*     #### ######  */
+	0x0E, 0x7C, /*     ###  #####   */
+	0x08, 0x00, /*     #            */
+
+	/* @918 'S' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x04, 0x3C, /*      #    ####   */
+	0x08, 0x7C, /*     #    #####   */
+	0x08, 0x62, /*     #    ##   #  */
+	0x08, 0xE2, /*     #   ###   #  */
+	0x08, 0xC2, /*     #   ##    #  */
+	0x0F, 0xC2, /*     ######    #  */
+	0x07, 0x84, /*      ####    #   */
+	0x00, 0x00, /*                  */
+
+	/* @936 'T' (9 pixels wide) */
+	0x00, 0x02, /*               #  */
+	0x00, 0x02, /*               #  */
+	0x00, 0x02, /*               #  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x02, /*               #  */
+	0x00, 0x02, /*               #  */
+	0x00, 0x02, /*               #  */
+	0x00, 0x00, /*                  */
+
+	/* @954 'U' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xFE, /*      ##########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x0F, 0xFE, /*     ###########  */
+	0x07, 0xFE, /*      ##########  */
+	0x00, 0x00, /*                  */
+
+	/* @972 'V' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x06, /*              ##  */
+	0x00, 0xFE, /*         #######  */
+	0x0F, 0xF8, /*     #########    */
+	0x0E, 0x00, /*     ###          */
+	0x0F, 0xF8, /*     #########    */
+	0x00, 0xFE, /*         #######  */
+	0x00, 0x06, /*              ##  */
+	0x00, 0x00, /*                  */
+
+	/* @990 'W' (9 pixels wide) */
+	0x00, 0x3E, /*           #####  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0E, 0x00, /*     ###          */
+	0x03, 0xE0, /*       #####      */
+	0x00, 0x70, /*          ###     */
+	0x03, 0xE0, /*       #####      */
+	0x0E, 0x00, /*     ###          */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x3E, /*           #####  */
+
+	/* @1008 'X' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x08, 0x02, /*     #         #  */
+	0x0E, 0x0E, /*     ###     ###  */
+	0x07, 0xBC, /*      #### ####   */
+	0x01, 0xF0, /*        #####     */
+	0x07, 0xBC, /*      #### ####   */
+	0x0E, 0x0E, /*     ###     ###  */
+	0x08, 0x02, /*     #         #  */
+	0x00, 0x00, /*                  */
+
+	/* @1026 'Y' (9 pixels wide) */
+	0x00, 0x02, /*               #  */
+	0x00, 0x0E, /*             ###  */
+	0x00, 0x7E, /*          ######  */
+	0x0F, 0xF0, /*     ########     */
+	0x0F, 0xF0, /*     ########     */
+	0x00, 0x7E, /*          ######  */
+	0x00, 0x0E, /*             ###  */
+	0x00, 0x02, /*               #  */
+	0x00, 0x00, /*                  */
+
+	/* @1044 'Z' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0E, 0x02, /*     ###       #  */
+	0x0F, 0x02, /*     ####      #  */
+	0x0B, 0xC2, /*     # ####    #  */
+	0x08, 0xF2, /*     #   ####  #  */
+	0x08, 0x7A, /*     #    #### #  */
+	0x08, 0x1E, /*     #      ####  */
+	0x08, 0x0E, /*     #       ###  */
+	0x00, 0x00, /*                  */
+
+	/* @1062 '[' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x3F, 0xFE, /*   #############  */
+	0x3F, 0xFE, /*   #############  */
+	0x20, 0x02, /*   #           #  */
+	0x20, 0x02, /*   #           #  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1080 '\' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x02, /*               #  */
+	0x00, 0x0E, /*             ###  */
+	0x00, 0x78, /*          ####    */
+	0x01, 0xE0, /*        ####      */
+	0x07, 0x80, /*      ####        */
+	0x1C, 0x00, /*    ###           */
+	0x10, 0x00, /*    #             */
+	0x00, 0x00, /*                  */
+
+	/* @1098 ']' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x20, 0x02, /*   #           #  */
+	0x20, 0x02, /*   #           #  */
+	0x3F, 0xFE, /*   #############  */
+	0x3F, 0xFE, /*   #############  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1116 '^' (9 pixels wide) */
+	0x00, 0x10, /*            #     */
+	0x00, 0x18, /*            ##    */
+	0x00, 0x0C, /*             ##   */
+	0x00, 0x06, /*              ##  */
+	0x00, 0x06, /*              ##  */
+	0x00, 0x0C, /*             ##   */
+	0x00, 0x18, /*            ##    */
+	0x00, 0x10, /*            #     */
+	0x00, 0x00, /*                  */
+
+	/* @1134 '_' (9 pixels wide) */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+
+	/* @1152 '`' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x01, /*                # */
+	0x00, 0x03, /*               ## */
+	0x00, 0x06, /*              ##  */
+	0x00, 0x04, /*              #   */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1170 'a' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0x00, /*      ###         */
+	0x0F, 0xA0, /*     ##### #      */
+	0x08, 0x90, /*     #   #  #     */
+	0x08, 0x90, /*     #   #  #     */
+	0x0C, 0x90, /*     ##  #  #     */
+	0x0F, 0xF0, /*     ########     */
+	0x0F, 0xE0, /*     #######      */
+	0x00, 0x00, /*                  */
+
+	/* @1188 'b' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0C, 0x30, /*     ##    ##     */
+	0x08, 0x10, /*     #      #     */
+	0x0C, 0x30, /*     ##    ##     */
+	0x0F, 0xF0, /*     ########     */
+	0x07, 0xE0, /*      ######      */
+	0x00, 0x00, /*                  */
+
+	/* @1206 'c' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xC0, /*       ####       */
+	0x07, 0xE0, /*      ######      */
+	0x0C, 0x30, /*     ##    ##     */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x04, 0x20, /*      #    #      */
+	0x00, 0x00, /*                  */
+
+	/* @1224 'd' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xE0, /*      ######      */
+	0x0F, 0xF0, /*     ########     */
+	0x0C, 0x30, /*     ##    ##     */
+	0x08, 0x10, /*     #      #     */
+	0x0C, 0x30, /*     ##    ##     */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x00, /*                  */
+
+	/* @1242 'e' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xC0, /*       ####       */
+	0x07, 0xE0, /*      ######      */
+	0x0C, 0x90, /*     ##  #  #     */
+	0x08, 0x90, /*     #   #  #     */
+	0x08, 0x90, /*     #   #  #     */
+	0x08, 0xF0, /*     #   ####     */
+	0x04, 0xE0, /*      #  ###      */
+	0x00, 0x00, /*                  */
+
+	/* @1260 'f' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x0F, 0xFC, /*     ##########   */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x12, /*            #  #  */
+	0x00, 0x12, /*            #  #  */
+	0x00, 0x12, /*            #  #  */
+	0x00, 0x00, /*                  */
+
+	/* @1278 'g' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xC0, /*       ####       */
+	0x2F, 0xF0, /*   # ########     */
+	0x4C, 0x30, /*  #  ##    ##     */
+	0x48, 0x10, /*  #  #      #     */
+	0x4C, 0x30, /*  #  ##    ##     */
+	0x7F, 0xF0, /*  ###########     */
+	0x3F, 0xF0, /*   ##########     */
+	0x00, 0x00, /*                  */
+
+	/* @1296 'h' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x0F, 0xF0, /*     ########     */
+	0x0F, 0xE0, /*     #######      */
+	0x00, 0x00, /*                  */
+
+	/* @1314 'i' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x08, 0x00, /*     #            */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x0F, 0xF7, /*     ######## ### */
+	0x0F, 0xF7, /*     ######## ### */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+
+	/* @1332 'j' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x40, 0x00, /*  #               */
+	0x40, 0x10, /*  #         #     */
+	0x40, 0x10, /*  #         #     */
+	0x7F, 0xF7, /*  ########### ### */
+	0x3F, 0xF7, /*   ########## ### */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1350 'k' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xFE, /*     ###########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x00, 0xC0, /*         ##       */
+	0x03, 0xE0, /*       #####      */
+	0x0F, 0x30, /*     ####  ##     */
+	0x0C, 0x10, /*     ##     #     */
+	0x08, 0x00, /*     #            */
+	0x00, 0x00, /*                  */
+
+	/* @1368 'l' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x02, /*               #  */
+	0x00, 0x02, /*               #  */
+	0x07, 0xFE, /*      ##########  */
+	0x0F, 0xFE, /*     ###########  */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x00, 0x00, /*                  */
+
+	/* @1386 'm' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xF0, /*     ########     */
+	0x0F, 0xF0, /*     ########     */
+	0x00, 0x10, /*            #     */
+	0x0F, 0xF0, /*     ########     */
+	0x0F, 0xF0, /*     ########     */
+	0x00, 0x10, /*            #     */
+	0x0F, 0xF0, /*     ########     */
+	0x0F, 0xF0, /*     ########     */
+
+	/* @1404 'n' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xF0, /*     ########     */
+	0x0F, 0xF0, /*     ########     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x0F, 0xF0, /*     ########     */
+	0x0F, 0xE0, /*     #######      */
+	0x00, 0x00, /*                  */
+
+	/* @1422 'o' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xC0, /*       ####       */
+	0x07, 0xE0, /*      ######      */
+	0x0C, 0x30, /*     ##    ##     */
+	0x08, 0x10, /*     #      #     */
+	0x0C, 0x30, /*     ##    ##     */
+	0x07, 0xE0, /*      ######      */
+	0x03, 0xC0, /*       ####       */
+	0x00, 0x00, /*                  */
+
+	/* @1440 'p' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x7F, 0xF0, /*  ###########     */
+	0x7F, 0xF0, /*  ###########     */
+	0x0C, 0x30, /*     ##    ##     */
+	0x08, 0x10, /*     #      #     */
+	0x0C, 0x30, /*     ##    ##     */
+	0x0F, 0xF0, /*     ########     */
+	0x07, 0xE0, /*      ######      */
+	0x00, 0x00, /*                  */
+
+	/* @1458 'q' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xE0, /*      ######      */
+	0x0F, 0xF0, /*     ########     */
+	0x0C, 0x30, /*     ##    ##     */
+	0x08, 0x10, /*     #      #     */
+	0x0C, 0x30, /*     ##    ##     */
+	0x7F, 0xF0, /*  ###########     */
+	0x7F, 0xF0, /*  ###########     */
+	0x00, 0x00, /*                  */
+
+	/* @1476 'r' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x0F, 0xF0, /*     ########     */
+	0x0F, 0xF0, /*     ########     */
+	0x00, 0x30, /*           ##     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x00, /*                  */
+
+	/* @1494 's' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x04, 0xE0, /*      #  ###      */
+	0x08, 0xF0, /*     #   ####     */
+	0x09, 0x90, /*     #  ##  #     */
+	0x09, 0x90, /*     #  ##  #     */
+	0x09, 0x90, /*     #  ##  #     */
+	0x0F, 0x10, /*     ####   #     */
+	0x07, 0x20, /*      ###  #      */
+	0x00, 0x00, /*                  */
+
+	/* @1512 't' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x07, 0xFC, /*      #########   */
+	0x0F, 0xFC, /*     ##########   */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x08, 0x10, /*     #      #     */
+	0x00, 0x00, /*                  */
+
+	/* @1530 'u' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xF0, /*      #######     */
+	0x0F, 0xF0, /*     ########     */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x0F, 0xF0, /*     ########     */
+	0x0F, 0xF0, /*     ########     */
+	0x00, 0x00, /*                  */
+
+	/* @1548 'v' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x30, /*           ##     */
+	0x01, 0xF0, /*        #####     */
+	0x0F, 0xE0, /*     #######      */
+	0x0C, 0x00, /*     ##           */
+	0x0F, 0xE0, /*     #######      */
+	0x01, 0xF0, /*        #####     */
+	0x00, 0x30, /*           ##     */
+	0x00, 0x00, /*                  */
+
+	/* @1566 'w' (9 pixels wide) */
+	0x00, 0x70, /*          ###     */
+	0x0F, 0xF0, /*     ########     */
+	0x0F, 0x00, /*     ####         */
+	0x03, 0x80, /*       ###        */
+	0x00, 0xC0, /*         ##       */
+	0x03, 0x80, /*       ###        */
+	0x0F, 0x00, /*     ####         */
+	0x0F, 0xF0, /*     ########     */
+	0x00, 0x70, /*          ###     */
+
+	/* @1584 'x' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x08, 0x10, /*     #      #     */
+	0x0C, 0x30, /*     ##    ##     */
+	0x0F, 0xF0, /*     ########     */
+	0x03, 0xC0, /*       ####       */
+	0x0F, 0xF0, /*     ########     */
+	0x0E, 0x30, /*     ###   ##     */
+	0x08, 0x10, /*     #      #     */
+	0x00, 0x00, /*                  */
+
+	/* @1602 'y' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x10, /*            #     */
+	0x40, 0xF0, /*  #      ####     */
+	0x63, 0xE0, /*  ##   #####      */
+	0x7F, 0x00, /*  #######         */
+	0x1F, 0xE0, /*    ########      */
+	0x01, 0xF0, /*        #####     */
+	0x00, 0x30, /*           ##     */
+	0x00, 0x00, /*                  */
+
+	/* @1620 'z' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0C, 0x10, /*     ##     #     */
+	0x0E, 0x10, /*     ###    #     */
+	0x0B, 0x10, /*     # ##   #     */
+	0x09, 0x90, /*     #  ##  #     */
+	0x08, 0xD0, /*     #   ## #     */
+	0x08, 0x70, /*     #    ###     */
+	0x08, 0x30, /*     #     ##     */
+	0x00, 0x00, /*                  */
+
+	/* @1638 '{' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x01, 0x00, /*        #         */
+	0x01, 0x00, /*        #         */
+	0x3E, 0xFC, /*   ##### ######   */
+	0x7E, 0xFE, /*  ###### #######  */
+	0x40, 0x02, /*  #            #  */
+	0x40, 0x02, /*  #            #  */
+	0x00, 0x00, /*                  */
+
+	/* @1656 '|' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xFF, 0xFE, /* ###############  */
+	0xFF, 0xFE, /* ###############  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1674 '}' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x40, 0x02, /*  #            #  */
+	0x40, 0x02, /*  #            #  */
+	0x7E, 0xFE, /*  ###### #######  */
+	0x3E, 0xFC, /*   ##### ######   */
+	0x01, 0x00, /*        #         */
+	0x01, 0x00, /*        #         */
+	0x00, 0x00, /*                  */
+
+	/* @1692 '~' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x01, 0x80, /*        ##        */
+	0x00, 0xC0, /*         ##       */
+	0x00, 0xC0, /*         ##       */
+	0x00, 0xC0, /*         ##       */
+	0x01, 0x80, /*        ##        */
+	0x01, 0x80, /*        ##        */
+	0x01, 0x80, /*        ##        */
+	0x00, 0xC0, /*         ##       */
+};
+
+/* Character descriptors for Bitstream Vera Sans Mono 11pt */
+/* { [Char width in bits], [Offset into bitstreamVeraSansMonoBold11ptCharBitmaps in bytes] } */
+const FONT_CHAR_INFO bitstreamVeraSansMonoBold11ptCharDescriptors[] =
+{
+	{9, 0}, 		/*   */
+	{9, 18}, 		/* ! */
+	{9, 36}, 		/* " */
+	{9, 54}, 		/* # */
+	{9, 72}, 		/* $ */
+	{9, 90}, 		/* % */
+	{9, 108}, 		/* & */
+	{9, 126}, 		/* ' */
+	{9, 144}, 		/* ( */
+	{9, 162}, 		/* ) */
+	{9, 180}, 		/* * */
+	{9, 198}, 		/* + */
+	{9, 216}, 		/* , */
+	{9, 234}, 		/* - */
+	{9, 252}, 		/* . */
+	{9, 270}, 		/* / */
+	{9, 288}, 		/* 0 */
+	{9, 306}, 		/* 1 */
+	{9, 324}, 		/* 2 */
+	{9, 342}, 		/* 3 */
+	{9, 360}, 		/* 4 */
+	{9, 378}, 		/* 5 */
+	{9, 396}, 		/* 6 */
+	{9, 414}, 		/* 7 */
+	{9, 432}, 		/* 8 */
+	{9, 450}, 		/* 9 */
+	{9, 468}, 		/* : */
+	{9, 486}, 		/* ; */
+	{9, 504}, 		/* < */
+	{9, 522}, 		/* = */
+	{9, 540}, 		/* > */
+	{9, 558}, 		/* ? */
+	{9, 576}, 		/* @ */
+	{9, 594}, 		/* A */
+	{9, 612}, 		/* B */
+	{9, 630}, 		/* C */
+	{9, 648}, 		/* D */
+	{9, 666}, 		/* E */
+	{9, 684}, 		/* F */
+	{9, 702}, 		/* G */
+	{9, 720}, 		/* H */
+	{9, 738}, 		/* I */
+	{9, 756}, 		/* J */
+	{9, 774}, 		/* K */
+	{9, 792}, 		/* L */
+	{9, 810}, 		/* M */
+	{9, 828}, 		/* N */
+	{9, 846}, 		/* O */
+	{9, 864}, 		/* P */
+	{9, 882}, 		/* Q */
+	{9, 900}, 		/* R */
+	{9, 918}, 		/* S */
+	{9, 936}, 		/* T */
+	{9, 954}, 		/* U */
+	{9, 972}, 		/* V */
+	{9, 990}, 		/* W */
+	{9, 1008}, 		/* X */
+	{9, 1026}, 		/* Y */
+	{9, 1044}, 		/* Z */
+	{9, 1062}, 		/* [ */
+	{9, 1080}, 		/* \ */
+	{9, 1098}, 		/* ] */
+	{9, 1116}, 		/* ^ */
+	{9, 1134}, 		/* _ */
+	{9, 1152}, 		/* ` */
+	{9, 1170}, 		/* a */
+	{9, 1188}, 		/* b */
+	{9, 1206}, 		/* c */
+	{9, 1224}, 		/* d */
+	{9, 1242}, 		/* e */
+	{9, 1260}, 		/* f */
+	{9, 1278}, 		/* g */
+	{9, 1296}, 		/* h */
+	{9, 1314}, 		/* i */
+	{9, 1332}, 		/* j */
+	{9, 1350}, 		/* k */
+	{9, 1368}, 		/* l */
+	{9, 1386}, 		/* m */
+	{9, 1404}, 		/* n */
+	{9, 1422}, 		/* o */
+	{9, 1440}, 		/* p */
+	{9, 1458}, 		/* q */
+	{9, 1476}, 		/* r */
+	{9, 1494}, 		/* s */
+	{9, 1512}, 		/* t */
+	{9, 1530}, 		/* u */
+	{9, 1548}, 		/* v */
+	{9, 1566}, 		/* w */
+	{9, 1584}, 		/* x */
+	{9, 1602}, 		/* y */
+	{9, 1620}, 		/* z */
+	{9, 1638}, 		/* { */
+	{9, 1656}, 		/* | */
+	{9, 1674}, 		/* } */
+	{9, 1692}, 		/* ~ */
+};
+
+/* Font information for Bitstream Vera Sans Mono 11pt */
+const FONT_INFO bitstreamVeraSansMonoBold11ptFontInfo =
+{
+	2, /*  Character height */
+	' ', /*  Start character */
+	'~', /*  End character */
+	bitstreamVeraSansMonoBold11ptCharDescriptors, /*  Character decriptor array */
+	bitstreamVeraSansMonoBold11ptCharBitmaps, /*  Character bitmap array */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramonobold11.h b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramonobold11.h
new file mode 100644
index 0000000000000000000000000000000000000000..79357e51e2d4e09a89c12d8ab5a3bf1025472aa8
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramonobold11.h
@@ -0,0 +1,19 @@
+#ifndef __VERA_MONO_BOLD_11__
+#define __VERA_MONO_BOLD_11__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../fonts.h"
+
+/* Font data for Bitstream Vera Sans Mono Bold 11pt */
+extern const uint8_t bitstreamVeraSansMonoBold11ptCharBitmaps[];
+extern const FONT_CHAR_INFO bitstreamVeraSansMonoBold11ptCharDescriptors[];
+extern const FONT_INFO bitstreamVeraSansMonoBold11ptFontInfo;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramonobold9.c b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramonobold9.c
new file mode 100644
index 0000000000000000000000000000000000000000..cb1c78ebcf4867b08780a7b2145bdcf1ac461568
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramonobold9.c
@@ -0,0 +1,1070 @@
+#include "veramonobold9.h"
+
+/* 
+**  Font data for Bitstream Vera Sans Mono Bold 9pt
+*/
+
+/* Character bitmaps for Bitstream Vera Sans Mono Bold 9pt */
+const uint8_t bitstreamVeraSansMonoBold9ptCharBitmaps[] = 
+{
+	/* @0 ' ' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @16 '!' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x1B, 0xF0, /*    ## ######     */
+	0x1B, 0xF0, /*    ## ######     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @32 '"' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x70, /*          ###     */
+	0x00, 0x70, /*          ###     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x70, /*          ###     */
+	0x00, 0x70, /*          ###     */
+	0x00, 0x00, /*                  */
+
+	/* @48 '#' (8 pixels wide) */
+	0x04, 0x00, /*      #           */
+	0x1C, 0x80, /*    ###  #        */
+	0x07, 0xC0, /*      #####       */
+	0x1C, 0xE0, /*    ###  ###      */
+	0x0F, 0x80, /*     #####        */
+	0x04, 0xE0, /*      #  ###      */
+	0x00, 0x80, /*         #        */
+	0x00, 0x00, /*                  */
+
+	/* @64 '$' (8 pixels wide) */
+	0x08, 0xC0, /*     #   ##       */
+	0x19, 0xE0, /*    ##  ####      */
+	0x11, 0x20, /*    #   #  #      */
+	0x7F, 0xF0, /*  ###########     */
+	0x11, 0x20, /*    #   #  #      */
+	0x1F, 0x60, /*    ##### ##      */
+	0x0E, 0x00, /*     ###          */
+	0x00, 0x00, /*                  */
+
+	/* @80 '%' (8 pixels wide) */
+	0x02, 0x60, /*       #  ##      */
+	0x02, 0x90, /*       # #  #     */
+	0x02, 0x90, /*       # #  #     */
+	0x0D, 0x60, /*     ## # ##      */
+	0x13, 0x00, /*    #  ##         */
+	0x12, 0x80, /*    #  # #        */
+	0x0C, 0x80, /*     ##  #        */
+	0x00, 0x00, /*                  */
+
+	/* @96 '&' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0E, 0x00, /*     ###          */
+	0x1F, 0x70, /*    ##### ###     */
+	0x11, 0xF0, /*    #   #####     */
+	0x1F, 0x10, /*    #####   #     */
+	0x1C, 0x00, /*    ###           */
+	0x17, 0x00, /*    # ###         */
+	0x00, 0x00, /*                  */
+
+	/* @112 ''' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x70, /*          ###     */
+	0x00, 0x70, /*          ###     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @128 '(' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x07, 0xC0, /*      #####       */
+	0x1F, 0xF0, /*    #########     */
+	0x30, 0x18, /*   ##       ##    */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @144 ')' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x30, 0x18, /*   ##       ##    */
+	0x1F, 0xF0, /*    #########     */
+	0x07, 0xC0, /*      #####       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @160 '*' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x01, 0x20, /*        #  #      */
+	0x00, 0xC0, /*         ##       */
+	0x03, 0xF0, /*       ######     */
+	0x00, 0xC0, /*         ##       */
+	0x01, 0x20, /*        #  #      */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @176 '+' (8 pixels wide) */
+	0x02, 0x00, /*       #          */
+	0x02, 0x00, /*       #          */
+	0x02, 0x00, /*       #          */
+	0x1F, 0xC0, /*    #######       */
+	0x02, 0x00, /*       #          */
+	0x02, 0x00, /*       #          */
+	0x02, 0x00, /*       #          */
+	0x00, 0x00, /*                  */
+
+	/* @192 ',' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x40, 0x00, /*  #               */
+	0x38, 0x00, /*   ###            */
+	0x18, 0x00, /*    ##            */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @208 '-' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x03, 0x00, /*       ##         */
+	0x03, 0x00, /*       ##         */
+	0x03, 0x00, /*       ##         */
+	0x03, 0x00, /*       ##         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @224 '.' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x18, 0x00, /*    ##            */
+	0x18, 0x00, /*    ##            */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @240 '/' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x20, 0x00, /*   #              */
+	0x18, 0x00, /*    ##            */
+	0x06, 0x00, /*      ##          */
+	0x01, 0x80, /*        ##        */
+	0x00, 0x60, /*          ##      */
+	0x00, 0x10, /*            #     */
+	0x00, 0x00, /*                  */
+
+	/* @256 '0' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xC0, /*      #####       */
+	0x1F, 0xF0, /*    #########     */
+	0x10, 0x10, /*    #       #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x1F, 0xF0, /*    #########     */
+	0x07, 0xC0, /*      #####       */
+	0x00, 0x00, /*                  */
+
+	/* @272 '1' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x10, 0x10, /*    #       #     */
+	0x10, 0x10, /*    #       #     */
+	0x1F, 0xF0, /*    #########     */
+	0x1F, 0xF0, /*    #########     */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x00, 0x00, /*                  */
+
+	/* @288 '2' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x18, 0x20, /*    ##     #      */
+	0x1C, 0x10, /*    ###     #     */
+	0x16, 0x10, /*    # ##    #     */
+	0x13, 0x10, /*    #  ##   #     */
+	0x11, 0xF0, /*    #   #####     */
+	0x10, 0xE0, /*    #    ###      */
+	0x00, 0x00, /*                  */
+
+	/* @304 '3' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x08, 0x20, /*     #     #      */
+	0x10, 0x10, /*    #       #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x1E, 0xF0, /*    #### ####     */
+	0x0E, 0xE0, /*     ### ###      */
+	0x00, 0x00, /*                  */
+
+	/* @320 '4' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0x00, /*      ###         */
+	0x05, 0x80, /*      # ##        */
+	0x04, 0x60, /*      #   ##      */
+	0x1F, 0xF0, /*    #########     */
+	0x1F, 0xF0, /*    #########     */
+	0x04, 0x00, /*      #           */
+	0x00, 0x00, /*                  */
+
+	/* @336 '5' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x08, 0xF0, /*     #   ####     */
+	0x10, 0xF0, /*    #    ####     */
+	0x10, 0x90, /*    #    #  #     */
+	0x11, 0x90, /*    #   ##  #     */
+	0x1F, 0x90, /*    ######  #     */
+	0x0F, 0x00, /*     ####         */
+	0x00, 0x00, /*                  */
+
+	/* @352 '6' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xC0, /*     ######       */
+	0x1F, 0xF0, /*    #########     */
+	0x10, 0xB0, /*    #    # ##     */
+	0x10, 0x90, /*    #    #  #     */
+	0x1F, 0x90, /*    ######  #     */
+	0x0F, 0x00, /*     ####         */
+	0x00, 0x00, /*                  */
+
+	/* @368 '7' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x10, /*            #     */
+	0x10, 0x10, /*    #       #     */
+	0x1E, 0x10, /*    ####    #     */
+	0x0F, 0xD0, /*     ###### #     */
+	0x01, 0xF0, /*        #####     */
+	0x00, 0x70, /*          ###     */
+	0x00, 0x00, /*                  */
+
+	/* @384 '8' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0E, 0xE0, /*     ### ###      */
+	0x1E, 0xF0, /*    #### ####     */
+	0x11, 0x10, /*    #   #   #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x1E, 0xF0, /*    #### ####     */
+	0x0E, 0xE0, /*     ### ###      */
+	0x00, 0x00, /*                  */
+
+	/* @400 '9' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x01, 0xE0, /*        ####      */
+	0x13, 0xF0, /*    #  ######     */
+	0x12, 0x10, /*    #  #    #     */
+	0x1A, 0x10, /*    ## #    #     */
+	0x1F, 0xF0, /*    #########     */
+	0x07, 0xE0, /*      ######      */
+	0x00, 0x00, /*                  */
+
+	/* @416 ':' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x19, 0x80, /*    ##  ##        */
+	0x19, 0x80, /*    ##  ##        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @432 ';' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x40, 0x00, /*  #               */
+	0x39, 0x80, /*   ###  ##        */
+	0x19, 0x80, /*    ##  ##        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @448 '<' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0x00, /*       ##         */
+	0x03, 0x00, /*       ##         */
+	0x07, 0x80, /*      ####        */
+	0x04, 0x80, /*      #  #        */
+	0x04, 0x80, /*      #  #        */
+	0x0C, 0xC0, /*     ##  ##       */
+	0x00, 0x00, /*                  */
+
+	/* @464 '=' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x05, 0x00, /*      # #         */
+	0x05, 0x00, /*      # #         */
+	0x05, 0x00, /*      # #         */
+	0x05, 0x00, /*      # #         */
+	0x05, 0x00, /*      # #         */
+	0x05, 0x00, /*      # #         */
+	0x00, 0x00, /*                  */
+
+	/* @480 '>' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0C, 0xC0, /*     ##  ##       */
+	0x04, 0x80, /*      #  #        */
+	0x04, 0x80, /*      #  #        */
+	0x07, 0x80, /*      ####        */
+	0x03, 0x00, /*       ##         */
+	0x03, 0x00, /*       ##         */
+	0x00, 0x00, /*                  */
+
+	/* @496 '?' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x20, /*           #      */
+	0x1B, 0x10, /*    ## ##   #     */
+	0x1B, 0x90, /*    ## ###  #     */
+	0x00, 0xF0, /*         ####     */
+	0x00, 0x60, /*          ##      */
+	0x00, 0x00, /*                  */
+
+	/* @512 '@' (8 pixels wide) */
+	0x0F, 0x80, /*     #####        */
+	0x30, 0xC0, /*   ##    ##       */
+	0x6F, 0x20, /*  ## ####  #      */
+	0x50, 0xA0, /*  # #    # #      */
+	0x50, 0xA0, /*  # #    # #      */
+	0x50, 0xA0, /*  # #    # #      */
+	0x7F, 0xC0, /*  #########       */
+	0x00, 0x00, /*                  */
+
+	/* @528 'A' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x18, 0x00, /*    ##            */
+	0x1F, 0x80, /*    ######        */
+	0x05, 0xF0, /*      # #####     */
+	0x05, 0xF0, /*      # #####     */
+	0x1F, 0x80, /*    ######        */
+	0x18, 0x00, /*    ##            */
+	0x00, 0x00, /*                  */
+
+	/* @544 'B' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x1F, 0xF0, /*    #########     */
+	0x11, 0x10, /*    #   #   #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x1E, 0xF0, /*    #### ####     */
+	0x0E, 0xE0, /*     ### ###      */
+	0x00, 0x00, /*                  */
+
+	/* @560 'C' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xC0, /*      #####       */
+	0x0F, 0xE0, /*     #######      */
+	0x18, 0x30, /*    ##     ##     */
+	0x10, 0x10, /*    #       #     */
+	0x10, 0x10, /*    #       #     */
+	0x08, 0x20, /*     #     #      */
+	0x00, 0x00, /*                  */
+
+	/* @576 'D' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x1F, 0xF0, /*    #########     */
+	0x10, 0x10, /*    #       #     */
+	0x18, 0x30, /*    ##     ##     */
+	0x0F, 0xE0, /*     #######      */
+	0x07, 0xC0, /*      #####       */
+	0x00, 0x00, /*                  */
+
+	/* @592 'E' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x1F, 0xF0, /*    #########     */
+	0x11, 0x10, /*    #   #   #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x11, 0x10, /*    #   #   #     */
+	0x10, 0x10, /*    #       #     */
+	0x00, 0x00, /*                  */
+
+	/* @608 'F' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x1F, 0xF0, /*    #########     */
+	0x01, 0x10, /*        #   #     */
+	0x01, 0x10, /*        #   #     */
+	0x01, 0x10, /*        #   #     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x00, /*                  */
+
+	/* @624 'G' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xC0, /*      #####       */
+	0x0F, 0xE0, /*     #######      */
+	0x18, 0x30, /*    ##     ##     */
+	0x12, 0x10, /*    #  #    #     */
+	0x1E, 0x10, /*    ####    #     */
+	0x1E, 0x20, /*    ####   #      */
+	0x00, 0x00, /*                  */
+
+	/* @640 'H' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x1F, 0xF0, /*    #########     */
+	0x01, 0x00, /*        #         */
+	0x01, 0x00, /*        #         */
+	0x1F, 0xF0, /*    #########     */
+	0x1F, 0xF0, /*    #########     */
+	0x00, 0x00, /*                  */
+
+	/* @656 'I' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x10, 0x10, /*    #       #     */
+	0x10, 0x10, /*    #       #     */
+	0x1F, 0xF0, /*    #########     */
+	0x1F, 0xF0, /*    #########     */
+	0x10, 0x10, /*    #       #     */
+	0x10, 0x10, /*    #       #     */
+	0x00, 0x00, /*                  */
+
+	/* @672 'J' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x08, 0x00, /*     #            */
+	0x10, 0x00, /*    #             */
+	0x10, 0x10, /*    #       #     */
+	0x10, 0x10, /*    #       #     */
+	0x1F, 0xF0, /*    #########     */
+	0x0F, 0xF0, /*     ########     */
+	0x00, 0x00, /*                  */
+
+	/* @688 'K' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x1F, 0xF0, /*    #########     */
+	0x01, 0x80, /*        ##        */
+	0x03, 0xC0, /*       ####       */
+	0x0E, 0x70, /*     ###  ###     */
+	0x18, 0x30, /*    ##     ##     */
+	0x10, 0x00, /*    #             */
+
+	/* @704 'L' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x1F, 0xF0, /*    #########     */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x00, 0x00, /*                  */
+
+	/* @720 'M' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x1F, 0xE0, /*    ########      */
+	0x01, 0xC0, /*        ###       */
+	0x01, 0xC0, /*        ###       */
+	0x1F, 0xE0, /*    ########      */
+	0x1F, 0xF0, /*    #########     */
+	0x00, 0x00, /*                  */
+
+	/* @736 'N' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x1F, 0xF0, /*    #########     */
+	0x01, 0xE0, /*        ####      */
+	0x0F, 0x00, /*     ####         */
+	0x1F, 0xF0, /*    #########     */
+	0x1F, 0xF0, /*    #########     */
+	0x00, 0x00, /*                  */
+
+	/* @752 'O' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xC0, /*      #####       */
+	0x1F, 0xF0, /*    #########     */
+	0x10, 0x10, /*    #       #     */
+	0x10, 0x10, /*    #       #     */
+	0x1F, 0xF0, /*    #########     */
+	0x07, 0xC0, /*      #####       */
+	0x00, 0x00, /*                  */
+
+	/* @768 'P' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x1F, 0xF0, /*    #########     */
+	0x01, 0x10, /*        #   #     */
+	0x01, 0x10, /*        #   #     */
+	0x01, 0xF0, /*        #####     */
+	0x00, 0xE0, /*         ###      */
+	0x00, 0x00, /*                  */
+
+	/* @784 'Q' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xC0, /*      #####       */
+	0x1F, 0xF0, /*    #########     */
+	0x10, 0x10, /*    #       #     */
+	0x10, 0x10, /*    #       #     */
+	0x3F, 0xF0, /*   ##########     */
+	0x07, 0xC0, /*      #####       */
+	0x00, 0x00, /*                  */
+
+	/* @800 'R' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF0, /*    #########     */
+	0x1F, 0xF0, /*    #########     */
+	0x01, 0x10, /*        #   #     */
+	0x03, 0x10, /*       ##   #     */
+	0x0E, 0xF0, /*     ### ####     */
+	0x1C, 0xE0, /*    ###  ###      */
+	0x10, 0x00, /*    #             */
+
+	/* @816 'S' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x08, 0xE0, /*     #   ###      */
+	0x11, 0xF0, /*    #   #####     */
+	0x11, 0x90, /*    #   ##  #     */
+	0x13, 0x10, /*    #  ##   #     */
+	0x1F, 0x10, /*    #####   #     */
+	0x0E, 0x20, /*     ###   #      */
+	0x00, 0x00, /*                  */
+
+	/* @832 'T' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x1F, 0xF0, /*    #########     */
+	0x1F, 0xF0, /*    #########     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x00, /*                  */
+
+	/* @848 'U' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xF0, /*     ########     */
+	0x1F, 0xF0, /*    #########     */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x1F, 0xF0, /*    #########     */
+	0x0F, 0xF0, /*     ########     */
+	0x00, 0x00, /*                  */
+
+	/* @864 'V' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x30, /*           ##     */
+	0x07, 0xF0, /*      #######     */
+	0x1F, 0x00, /*    #####         */
+	0x1F, 0x00, /*    #####         */
+	0x07, 0xF0, /*      #######     */
+	0x00, 0x30, /*           ##     */
+	0x00, 0x00, /*                  */
+
+	/* @880 'W' (8 pixels wide) */
+	0x00, 0xF0, /*         ####     */
+	0x1F, 0xF0, /*    #########     */
+	0x1F, 0x00, /*    #####         */
+	0x00, 0xC0, /*         ##       */
+	0x1F, 0x00, /*    #####         */
+	0x1F, 0xF0, /*    #########     */
+	0x01, 0xF0, /*        #####     */
+	0x00, 0x00, /*                  */
+
+	/* @896 'X' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x10, 0x10, /*    #       #     */
+	0x1C, 0x70, /*    ###   ###     */
+	0x07, 0xC0, /*      #####       */
+	0x07, 0xC0, /*      #####       */
+	0x1C, 0x70, /*    ###   ###     */
+	0x10, 0x10, /*    #       #     */
+	0x00, 0x00, /*                  */
+
+	/* @912 'Y' (8 pixels wide) */
+	0x00, 0x10, /*            #     */
+	0x00, 0x70, /*          ###     */
+	0x01, 0xE0, /*        ####      */
+	0x1F, 0x80, /*    ######        */
+	0x1F, 0x80, /*    ######        */
+	0x01, 0xE0, /*        ####      */
+	0x00, 0x70, /*          ###     */
+	0x00, 0x10, /*            #     */
+
+	/* @928 'Z' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x18, 0x10, /*    ##      #     */
+	0x1E, 0x10, /*    ####    #     */
+	0x17, 0x10, /*    # ###   #     */
+	0x11, 0xD0, /*    #   ### #     */
+	0x10, 0xF0, /*    #    ####     */
+	0x10, 0x30, /*    #      ##     */
+	0x00, 0x00, /*                  */
+
+	/* @944 '[' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x3F, 0xF8, /*   ###########    */
+	0x3F, 0xF8, /*   ###########    */
+	0x20, 0x08, /*   #         #    */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @960 '\' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x10, /*            #     */
+	0x00, 0x70, /*          ###     */
+	0x01, 0x80, /*        ##        */
+	0x06, 0x00, /*      ##          */
+	0x38, 0x00, /*   ###            */
+	0x20, 0x00, /*   #              */
+	0x00, 0x00, /*                  */
+
+	/* @976 ']' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x20, 0x08, /*   #         #    */
+	0x3F, 0xF8, /*   ###########    */
+	0x3F, 0xF8, /*   ###########    */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @992 '^' (8 pixels wide) */
+	0x00, 0x40, /*          #       */
+	0x00, 0x60, /*          ##      */
+	0x00, 0x30, /*           ##     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x30, /*           ##     */
+	0x00, 0x60, /*          ##      */
+	0x00, 0x40, /*          #       */
+	0x00, 0x00, /*                  */
+
+	/* @1008 '_' (8 pixels wide) */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x80, 0x00, /* #                */
+	0x00, 0x00, /*                  */
+
+	/* @1024 '`' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x08, /*             #    */
+	0x00, 0x18, /*            ##    */
+	0x00, 0x10, /*            #     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1040 'a' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0C, 0x00, /*     ##           */
+	0x1E, 0x80, /*    #### #        */
+	0x12, 0x40, /*    #  #  #       */
+	0x12, 0x40, /*    #  #  #       */
+	0x1F, 0xC0, /*    #######       */
+	0x1F, 0x80, /*    ######        */
+	0x00, 0x00, /*                  */
+
+	/* @1056 'b' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF8, /*    ##########    */
+	0x1F, 0xF8, /*    ##########    */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0x1F, 0xC0, /*    #######       */
+	0x0F, 0x80, /*     #####        */
+	0x00, 0x00, /*                  */
+
+	/* @1072 'c' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0x00, /*      ###         */
+	0x0F, 0x80, /*     #####        */
+	0x18, 0xC0, /*    ##   ##       */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0x08, 0x80, /*     #   #        */
+	0x00, 0x00, /*                  */
+
+	/* @1088 'd' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0x80, /*     #####        */
+	0x1F, 0xC0, /*    #######       */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0x1F, 0xF8, /*    ##########    */
+	0x1F, 0xF8, /*    ##########    */
+	0x00, 0x00, /*                  */
+
+	/* @1104 'e' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0x80, /*     #####        */
+	0x1F, 0xC0, /*    #######       */
+	0x12, 0x40, /*    #  #  #       */
+	0x12, 0x40, /*    #  #  #       */
+	0x13, 0xC0, /*    #  ####       */
+	0x0B, 0x80, /*     # ###        */
+	0x00, 0x00, /*                  */
+
+	/* @1120 'f' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x40, /*          #       */
+	0x00, 0x40, /*          #       */
+	0x1F, 0xF0, /*    #########     */
+	0x1F, 0xF8, /*    ##########    */
+	0x00, 0x48, /*          #  #    */
+	0x00, 0x48, /*          #  #    */
+	0x00, 0x00, /*                  */
+
+	/* @1136 'g' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0x80, /*     #####        */
+	0x9F, 0xC0, /* #  #######       */
+	0x90, 0x40, /* #  #     #       */
+	0x90, 0x40, /* #  #     #       */
+	0xFF, 0xC0, /* ##########       */
+	0x7F, 0xC0, /*  #########       */
+	0x00, 0x00, /*                  */
+
+	/* @1152 'h' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF8, /*    ##########    */
+	0x1F, 0xF8, /*    ##########    */
+	0x00, 0x40, /*          #       */
+	0x00, 0x40, /*          #       */
+	0x1F, 0xC0, /*    #######       */
+	0x1F, 0x80, /*    ######        */
+	0x00, 0x00, /*                  */
+
+	/* @1168 'i' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0x1F, 0xD8, /*    ####### ##    */
+	0x1F, 0xD8, /*    ####### ##    */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x00, 0x00, /*                  */
+
+	/* @1184 'j' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x80, 0x40, /* #        #       */
+	0x80, 0x40, /* #        #       */
+	0xFF, 0xD8, /* ########## ##    */
+	0x7F, 0xD8, /*  ######### ##    */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1200 'k' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xF8, /*    ##########    */
+	0x1F, 0xF8, /*    ##########    */
+	0x03, 0x00, /*       ##         */
+	0x0F, 0x80, /*     #####        */
+	0x1C, 0xC0, /*    ###  ##       */
+	0x10, 0x00, /*    #             */
+	0x00, 0x00, /*                  */
+
+	/* @1216 'l' (8 pixels wide) */
+	0x00, 0x08, /*             #    */
+	0x00, 0x08, /*             #    */
+	0x0F, 0xF8, /*     #########    */
+	0x1F, 0xF8, /*    ##########    */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1232 'm' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xC0, /*    #######       */
+	0x1F, 0xC0, /*    #######       */
+	0x00, 0x40, /*          #       */
+	0x1F, 0xC0, /*    #######       */
+	0x00, 0x40, /*          #       */
+	0x1F, 0xC0, /*    #######       */
+	0x00, 0x00, /*                  */
+
+	/* @1248 'n' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1F, 0xC0, /*    #######       */
+	0x1F, 0xC0, /*    #######       */
+	0x00, 0x40, /*          #       */
+	0x00, 0x40, /*          #       */
+	0x1F, 0xC0, /*    #######       */
+	0x1F, 0x80, /*    ######        */
+	0x00, 0x00, /*                  */
+
+	/* @1264 'o' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0x80, /*     #####        */
+	0x1F, 0xC0, /*    #######       */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0x1F, 0xC0, /*    #######       */
+	0x0F, 0x80, /*     #####        */
+	0x00, 0x00, /*                  */
+
+	/* @1280 'p' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0xC0, /* ##########       */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0x1F, 0xC0, /*    #######       */
+	0x0F, 0x80, /*     #####        */
+	0x00, 0x00, /*                  */
+
+	/* @1296 'q' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0x80, /*     #####        */
+	0x1F, 0xC0, /*    #######       */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0xC0, /* ##########       */
+	0x00, 0x00, /*                  */
+
+	/* @1312 'r' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x1F, 0xC0, /*    #######       */
+	0x1F, 0xC0, /*    #######       */
+	0x00, 0x40, /*          #       */
+	0x00, 0x40, /*          #       */
+	0x00, 0x40, /*          #       */
+	0x00, 0x00, /*                  */
+
+	/* @1328 's' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x09, 0x80, /*     #  ##        */
+	0x13, 0xC0, /*    #  ####       */
+	0x13, 0x40, /*    #  ## #       */
+	0x12, 0x40, /*    #  #  #       */
+	0x1E, 0x40, /*    ####  #       */
+	0x0C, 0x80, /*     ##  #        */
+	0x00, 0x00, /*                  */
+
+	/* @1344 't' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x40, /*          #       */
+	0x00, 0x40, /*          #       */
+	0x0F, 0xF0, /*     ########     */
+	0x1F, 0xF0, /*    #########     */
+	0x10, 0x40, /*    #     #       */
+	0x10, 0x40, /*    #     #       */
+	0x00, 0x00, /*                  */
+
+	/* @1360 'u' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xC0, /*     ######       */
+	0x1F, 0xC0, /*    #######       */
+	0x10, 0x00, /*    #             */
+	0x10, 0x00, /*    #             */
+	0x1F, 0xC0, /*    #######       */
+	0x1F, 0xC0, /*    #######       */
+	0x00, 0x00, /*                  */
+
+	/* @1376 'v' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0xC0, /*         ##       */
+	0x07, 0xC0, /*      #####       */
+	0x1E, 0x00, /*    ####          */
+	0x1E, 0x00, /*    ####          */
+	0x07, 0xC0, /*      #####       */
+	0x00, 0xC0, /*         ##       */
+	0x00, 0x00, /*                  */
+
+	/* @1392 'w' (8 pixels wide) */
+	0x01, 0xC0, /*        ###       */
+	0x1F, 0xC0, /*    #######       */
+	0x1E, 0x00, /*    ####          */
+	0x01, 0x00, /*        #         */
+	0x1E, 0x00, /*    ####          */
+	0x1F, 0xC0, /*    #######       */
+	0x01, 0xC0, /*        ###       */
+	0x00, 0x00, /*                  */
+
+	/* @1408 'x' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x10, 0x40, /*    #     #       */
+	0x1D, 0xC0, /*    ### ###       */
+	0x0F, 0x80, /*     #####        */
+	0x0F, 0x80, /*     #####        */
+	0x1D, 0xC0, /*    ### ###       */
+	0x10, 0x40, /*    #     #       */
+	0x00, 0x00, /*                  */
+
+	/* @1424 'y' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x80, 0xC0, /* #       ##       */
+	0x87, 0xC0, /* #    #####       */
+	0xFE, 0x00, /* #######          */
+	0x3E, 0x00, /*   #####          */
+	0x07, 0xC0, /*      #####       */
+	0x00, 0xC0, /*         ##       */
+	0x00, 0x00, /*                  */
+
+	/* @1440 'z' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x18, 0x40, /*    ##    #       */
+	0x1C, 0x40, /*    ###   #       */
+	0x16, 0x40, /*    # ##  #       */
+	0x13, 0x40, /*    #  ## #       */
+	0x11, 0xC0, /*    #   ###       */
+	0x10, 0xC0, /*    #    ##       */
+	0x00, 0x00, /*                  */
+
+	/* @1456 '{' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x01, 0x00, /*        #         */
+	0x01, 0x00, /*        #         */
+	0x1E, 0xF8, /*    #### #####    */
+	0x3E, 0xF8, /*   ##### #####    */
+	0x20, 0x08, /*   #         #    */
+	0x20, 0x08, /*   #         #    */
+	0x00, 0x00, /*                  */
+
+	/* @1472 '|' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x7F, 0xF8, /*  ############    */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1488 '}' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x20, 0x08, /*   #         #    */
+	0x20, 0x08, /*   #         #    */
+	0x3E, 0xF8, /*   ##### #####    */
+	0x3E, 0xF8, /*   ##### #####    */
+	0x01, 0x00, /*        #         */
+	0x01, 0x00, /*        #         */
+	0x00, 0x00, /*                  */
+
+	/* @1504 '~' (8 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x02, 0x00, /*       #          */
+	0x02, 0x00, /*       #          */
+	0x02, 0x00, /*       #          */
+	0x04, 0x00, /*      #           */
+	0x04, 0x00, /*      #           */
+	0x04, 0x00, /*      #           */
+	0x00, 0x00, /*                  */
+};
+
+/* Character descriptors for Bitstream Vera Sans Mono 9pt */
+/* { [Char width in bits], [Offset into bitstreamVeraSansMonoBold9ptCharBitmaps in bytes] } */
+const FONT_CHAR_INFO bitstreamVeraSansMonoBold9ptCharDescriptors[] =
+{
+	{8, 0}, 		/*   */
+	{8, 16}, 		/* ! */
+	{8, 32}, 		/* " */
+	{8, 48}, 		/* # */
+	{8, 64}, 		/* $ */
+	{8, 80}, 		/* % */
+	{8, 96}, 		/* & */
+	{8, 112}, 		/* ' */
+	{8, 128}, 		/* ( */
+	{8, 144}, 		/* ) */
+	{8, 160}, 		/* * */
+	{8, 176}, 		/* + */
+	{8, 192}, 		/* , */
+	{8, 208}, 		/* - */
+	{8, 224}, 		/* . */
+	{8, 240}, 		/* / */
+	{8, 256}, 		/* 0 */
+	{8, 272}, 		/* 1 */
+	{8, 288}, 		/* 2 */
+	{8, 304}, 		/* 3 */
+	{8, 320}, 		/* 4 */
+	{8, 336}, 		/* 5 */
+	{8, 352}, 		/* 6 */
+	{8, 368}, 		/* 7 */
+	{8, 384}, 		/* 8 */
+	{8, 400}, 		/* 9 */
+	{8, 416}, 		/* : */
+	{8, 432}, 		/* ; */
+	{8, 448}, 		/* < */
+	{8, 464}, 		/* = */
+	{8, 480}, 		/* > */
+	{8, 496}, 		/* ? */
+	{8, 512}, 		/* @ */
+	{8, 528}, 		/* A */
+	{8, 544}, 		/* B */
+	{8, 560}, 		/* C */
+	{8, 576}, 		/* D */
+	{8, 592}, 		/* E */
+	{8, 608}, 		/* F */
+	{8, 624}, 		/* G */
+	{8, 640}, 		/* H */
+	{8, 656}, 		/* I */
+	{8, 672}, 		/* J */
+	{8, 688}, 		/* K */
+	{8, 704}, 		/* L */
+	{8, 720}, 		/* M */
+	{8, 736}, 		/* N */
+	{8, 752}, 		/* O */
+	{8, 768}, 		/* P */
+	{8, 784}, 		/* Q */
+	{8, 800}, 		/* R */
+	{8, 816}, 		/* S */
+	{8, 832}, 		/* T */
+	{8, 848}, 		/* U */
+	{8, 864}, 		/* V */
+	{8, 880}, 		/* W */
+	{8, 896}, 		/* X */
+	{8, 912}, 		/* Y */
+	{8, 928}, 		/* Z */
+	{8, 944}, 		/* [ */
+	{8, 960}, 		/* \ */
+	{8, 976}, 		/* ] */
+	{8, 992}, 		/* ^ */
+	{8, 1008}, 		/* _ */
+	{8, 1024}, 		/* ` */
+	{8, 1040}, 		/* a */
+	{8, 1056}, 		/* b */
+	{8, 1072}, 		/* c */
+	{8, 1088}, 		/* d */
+	{8, 1104}, 		/* e */
+	{8, 1120}, 		/* f */
+	{8, 1136}, 		/* g */
+	{8, 1152}, 		/* h */
+	{8, 1168}, 		/* i */
+	{8, 1184}, 		/* j */
+	{8, 1200}, 		/* k */
+	{8, 1216}, 		/* l */
+	{8, 1232}, 		/* m */
+	{8, 1248}, 		/* n */
+	{8, 1264}, 		/* o */
+	{8, 1280}, 		/* p */
+	{8, 1296}, 		/* q */
+	{8, 1312}, 		/* r */
+	{8, 1328}, 		/* s */
+	{8, 1344}, 		/* t */
+	{8, 1360}, 		/* u */
+	{8, 1376}, 		/* v */
+	{8, 1392}, 		/* w */
+	{8, 1408}, 		/* x */
+	{8, 1424}, 		/* y */
+	{8, 1440}, 		/* z */
+	{8, 1456}, 		/* { */
+	{8, 1472}, 		/* | */
+	{8, 1488}, 		/* } */
+	{8, 1504}, 		/* ~ */
+};
+
+/* Font information for Bitstream Vera Sans Mono 9pt */
+const FONT_INFO bitstreamVeraSansMonoBold9ptFontInfo =
+{
+	2, /*  Character height */
+	' ', /*  Start character */
+	'~', /*  End character */
+	bitstreamVeraSansMonoBold9ptCharDescriptors, /*  Character decriptor array */
+	bitstreamVeraSansMonoBold9ptCharBitmaps, /*  Character bitmap array */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramonobold9.h b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramonobold9.h
new file mode 100644
index 0000000000000000000000000000000000000000..13bd6d5dec0c22387421a58163bcdcbbf2ba50fe
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/veramonobold9.h
@@ -0,0 +1,19 @@
+#ifndef __VERA_MONO_BOLD_9__
+#define __VERA_MONO_BOLD_9__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../fonts.h"
+
+/* Font data for Bitstream Vera Sans Mono Bold 9pt */
+extern const uint8_t bitstreamVeraSansMonoBold9ptCharBitmaps[];
+extern const FONT_CHAR_INFO bitstreamVeraSansMonoBold9ptCharDescriptors[];
+extern const FONT_INFO bitstreamVeraSansMonoBold9ptFontInfo;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/verdana14.c b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/verdana14.c
new file mode 100644
index 0000000000000000000000000000000000000000..1a6d8c881f2a0561cc69184d70606fdadef4da2c
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/verdana14.c
@@ -0,0 +1,2115 @@
+#include "verdana14.h"
+
+/* 
+**  Font data for Verdana 14pt
+*/
+
+/* Character bitmaps for Verdana 14pt */
+const uint8_t verdana14ptBitmaps[] = 
+{
+	/* @0 ' ' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @19 '!' (2 pixels wide) */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @38 '"' (6 pixels wide) */
+	0xCC, /* ##  ##   */
+	0xCC, /* ##  ##   */
+	0xCC, /* ##  ##   */
+	0xCC, /* ##  ##   */
+	0xCC, /* ##  ##   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @57 '#' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x04, 0x40, /*      #   #       */
+	0x04, 0x40, /*      #   #       */
+	0x08, 0x80, /*     #   #        */
+	0x08, 0x80, /*     #   #        */
+	0x7F, 0xF0, /*  ###########     */
+	0x08, 0x80, /*     #   #        */
+	0x08, 0x80, /*     #   #        */
+	0x11, 0x00, /*    #   #         */
+	0x11, 0x00, /*    #   #         */
+	0xFF, 0xE0, /* ###########      */
+	0x11, 0x00, /*    #   #         */
+	0x11, 0x00, /*    #   #         */
+	0x22, 0x00, /*   #   #          */
+	0x22, 0x00, /*   #   #          */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @95 '$' (9 pixels wide) */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x3F, 0x80, /*   #######        */
+	0x7F, 0x80, /*  ########        */
+	0xC8, 0x00, /* ##  #            */
+	0xC8, 0x00, /* ##  #            */
+	0xE8, 0x00, /* ### #            */
+	0x7C, 0x00, /*  #####           */
+	0x1F, 0x00, /*    #####         */
+	0x09, 0x80, /*     #  ##        */
+	0x09, 0x80, /*     #  ##        */
+	0x89, 0x80, /* #   #  ##        */
+	0xFF, 0x00, /* ########         */
+	0x7E, 0x00, /*  ######          */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x08, 0x00, /*     #            */
+	0x00, 0x00, /*                  */
+
+	/* @133 '%' (18 pixels wide) */
+	0x00, 0x00, 0x00, /*                          */
+	0x7C, 0x18, 0x00, /*  #####     ##            */
+	0x44, 0x10, 0x00, /*  #   #     #             */
+	0xC6, 0x30, 0x00, /* ##   ##   ##             */
+	0xC6, 0x20, 0x00, /* ##   ##   #              */
+	0xC6, 0x60, 0x00, /* ##   ##  ##              */
+	0xC6, 0x40, 0x00, /* ##   ##  #               */
+	0x44, 0x4F, 0x80, /*  #   #   #  #####        */
+	0x7C, 0x88, 0x80, /*  #####  #   #   #        */
+	0x00, 0x98, 0xC0, /*         #  ##   ##       */
+	0x01, 0x98, 0xC0, /*        ##  ##   ##       */
+	0x01, 0x18, 0xC0, /*        #   ##   ##       */
+	0x03, 0x18, 0xC0, /*       ##   ##   ##       */
+	0x02, 0x08, 0x80, /*       #     #   #        */
+	0x06, 0x0F, 0x80, /*      ##     #####        */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+
+	/* @190 '&' (13 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1E, 0x00, /*    ####          */
+	0x7F, 0x00, /*  #######         */
+	0x63, 0x00, /*  ##   ##         */
+	0x63, 0x00, /*  ##   ##         */
+	0x63, 0x00, /*  ##   ##         */
+	0x3E, 0x00, /*   #####          */
+	0x3C, 0x60, /*   ####   ##      */
+	0x66, 0x60, /*  ##  ##  ##      */
+	0xC3, 0x60, /* ##    ## ##      */
+	0xC1, 0xE0, /* ##     ####      */
+	0xC0, 0xC0, /* ##      ##       */
+	0xE1, 0xE0, /* ###    ####      */
+	0x7F, 0x30, /*  #######  ##     */
+	0x3E, 0x18, /*   #####    ##    */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @228 ''' (2 pixels wide) */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @247 '(' (6 pixels wide) */
+	0x1C, /*    ###   */
+	0x18, /*    ##    */
+	0x30, /*   ##     */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x30, /*   ##     */
+	0x18, /*    ##    */
+	0x1C, /*    ###   */
+
+	/* @266 ')' (6 pixels wide) */
+	0xE0, /* ###      */
+	0x60, /*  ##      */
+	0x30, /*   ##     */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x0C, /*     ##   */
+	0x0C, /*     ##   */
+	0x0C, /*     ##   */
+	0x0C, /*     ##   */
+	0x0C, /*     ##   */
+	0x0C, /*     ##   */
+	0x0C, /*     ##   */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x30, /*   ##     */
+	0x60, /*  ##      */
+	0xE0, /* ###      */
+
+	/* @285 '*' (9 pixels wide) */
+	0x08, 0x00, /*     #            */
+	0x88, 0x80, /* #   #   #        */
+	0xEB, 0x80, /* ### # ###        */
+	0x3E, 0x00, /*   #####          */
+	0x08, 0x00, /*     #            */
+	0x3E, 0x00, /*   #####          */
+	0xEB, 0x80, /* ### # ###        */
+	0x88, 0x80, /* #   #   #        */
+	0x08, 0x00, /*     #            */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @323 '+' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0xFF, 0xF0, /* ############     */
+	0xFF, 0xF0, /* ############     */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @361 ',' (4 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x40, /*  #       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+
+	/* @380 '-' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0xFC, /* ######   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @399 '.' (2 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @418 '/' (8 pixels wide) */
+	0x03, /*       ## */
+	0x07, /*      ### */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x0E, /*     ###  */
+	0x0C, /*     ##   */
+	0x0C, /*     ##   */
+	0x1C, /*    ###   */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x38, /*   ###    */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x70, /*  ###     */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0xE0, /* ###      */
+	0xC0, /* ##       */
+	0x00, /*          */
+
+	/* @437 '0' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1E, 0x00, /*    ####          */
+	0x7F, 0x80, /*  ########        */
+	0x61, 0x80, /*  ##    ##        */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0x61, 0x80, /*  ##    ##        */
+	0x7F, 0x80, /*  ########        */
+	0x1E, 0x00, /*    ####          */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @475 '1' (8 pixels wide) */
+	0x00, /*          */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0xF8, /* #####    */
+	0xF8, /* #####    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0xFF, /* ######## */
+	0xFF, /* ######## */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @494 '2' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x7C, 0x00, /*  #####           */
+	0xFE, 0x00, /* #######          */
+	0x87, 0x00, /* #    ###         */
+	0x03, 0x00, /*       ##         */
+	0x03, 0x00, /*       ##         */
+	0x03, 0x00, /*       ##         */
+	0x06, 0x00, /*      ##          */
+	0x0C, 0x00, /*     ##           */
+	0x18, 0x00, /*    ##            */
+	0x30, 0x00, /*   ##             */
+	0x60, 0x00, /*  ##              */
+	0xC0, 0x00, /* ##               */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x80, /* #########        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @532 '3' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x7E, 0x00, /*  ######          */
+	0xFF, 0x00, /* ########         */
+	0x83, 0x80, /* #     ###        */
+	0x01, 0x80, /*        ##        */
+	0x01, 0x80, /*        ##        */
+	0x03, 0x00, /*       ##         */
+	0x1E, 0x00, /*    ####          */
+	0x1F, 0x00, /*    #####         */
+	0x03, 0x80, /*       ###        */
+	0x01, 0x80, /*        ##        */
+	0x01, 0x80, /*        ##        */
+	0x83, 0x80, /* #     ###        */
+	0xFF, 0x00, /* ########         */
+	0x7E, 0x00, /*  ######          */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @570 '4' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0x00, /*       ##         */
+	0x07, 0x00, /*      ###         */
+	0x0F, 0x00, /*     ####         */
+	0x1F, 0x00, /*    #####         */
+	0x1B, 0x00, /*    ## ##         */
+	0x33, 0x00, /*   ##  ##         */
+	0x73, 0x00, /*  ###  ##         */
+	0xE3, 0x00, /* ###   ##         */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0xC0, /* ##########       */
+	0x03, 0x00, /*       ##         */
+	0x03, 0x00, /*       ##         */
+	0x03, 0x00, /*       ##         */
+	0x03, 0x00, /*       ##         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @608 '5' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x7F, 0x80, /*  ########        */
+	0x7F, 0x80, /*  ########        */
+	0x60, 0x00, /*  ##              */
+	0x60, 0x00, /*  ##              */
+	0x60, 0x00, /*  ##              */
+	0x7E, 0x00, /*  ######          */
+	0x7F, 0x00, /*  #######         */
+	0x03, 0x80, /*       ###        */
+	0x01, 0x80, /*        ##        */
+	0x01, 0x80, /*        ##        */
+	0x01, 0x80, /*        ##        */
+	0x83, 0x00, /* #     ##         */
+	0xFF, 0x00, /* ########         */
+	0x7C, 0x00, /*  #####           */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @646 '6' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0x80, /*     #####        */
+	0x3F, 0x80, /*   #######        */
+	0x30, 0x00, /*   ##             */
+	0x60, 0x00, /*  ##              */
+	0xC0, 0x00, /* ##               */
+	0xDF, 0x00, /* ## #####         */
+	0xFF, 0x80, /* #########        */
+	0xC1, 0xC0, /* ##     ###       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0x61, 0x80, /*  ##    ##        */
+	0x7F, 0x80, /*  ########        */
+	0x1E, 0x00, /*    ####          */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @684 '7' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x80, /* #########        */
+	0x01, 0x80, /*        ##        */
+	0x03, 0x00, /*       ##         */
+	0x03, 0x00, /*       ##         */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x0C, 0x00, /*     ##           */
+	0x0C, 0x00, /*     ##           */
+	0x18, 0x00, /*    ##            */
+	0x18, 0x00, /*    ##            */
+	0x30, 0x00, /*   ##             */
+	0x30, 0x00, /*   ##             */
+	0x70, 0x00, /*  ###             */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @722 '8' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x3F, 0x00, /*   ######         */
+	0x7F, 0x80, /*  ########        */
+	0xE1, 0xC0, /* ###    ###       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0x79, 0x80, /*  ####  ##        */
+	0x3E, 0x00, /*   #####          */
+	0x67, 0x80, /*  ##  ####        */
+	0xC1, 0xC0, /* ##     ###       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xE1, 0xC0, /* ###    ###       */
+	0x7F, 0x80, /*  ########        */
+	0x3F, 0x00, /*   ######         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @760 '9' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1E, 0x00, /*    ####          */
+	0x7F, 0x80, /*  ########        */
+	0x61, 0x80, /*  ##    ##        */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xE0, 0xC0, /* ###     ##       */
+	0x7F, 0xC0, /*  #########       */
+	0x3E, 0xC0, /*   ##### ##       */
+	0x00, 0xC0, /*         ##       */
+	0x01, 0x80, /*        ##        */
+	0x03, 0x80, /*       ###        */
+	0x7F, 0x00, /*  #######         */
+	0x7C, 0x00, /*  #####           */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @798 ':' (2 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @817 ';' (4 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x40, /*  #       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+
+	/* @836 '<' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x60, /*          ##      */
+	0x01, 0xE0, /*        ####      */
+	0x07, 0x80, /*      ####        */
+	0x1E, 0x00, /*    ####          */
+	0x78, 0x00, /*  ####            */
+	0xE0, 0x00, /* ###              */
+	0x78, 0x00, /*  ####            */
+	0x1E, 0x00, /*    ####          */
+	0x07, 0x80, /*      ####        */
+	0x01, 0xE0, /*        ####      */
+	0x00, 0x60, /*          ##      */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @874 '=' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xFF, 0xE0, /* ###########      */
+	0xFF, 0xE0, /* ###########      */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xFF, 0xE0, /* ###########      */
+	0xFF, 0xE0, /* ###########      */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @912 '>' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xC0, 0x00, /* ##               */
+	0xF0, 0x00, /* ####             */
+	0x3C, 0x00, /*   ####           */
+	0x0F, 0x00, /*     ####         */
+	0x03, 0xC0, /*       ####       */
+	0x00, 0xE0, /*         ###      */
+	0x03, 0xC0, /*       ####       */
+	0x0F, 0x00, /*     ####         */
+	0x3C, 0x00, /*   ####           */
+	0xF0, 0x00, /* ####             */
+	0xC0, 0x00, /* ##               */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @950 '?' (8 pixels wide) */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0xFE, /* #######  */
+	0x87, /* #    ### */
+	0x03, /*       ## */
+	0x03, /*       ## */
+	0x06, /*      ##  */
+	0x0E, /*     ###  */
+	0x38, /*   ###    */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x00, /*          */
+	0x00, /*          */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @969 '@' (16 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0xE0, /*      ######      */
+	0x1C, 0x18, /*    ###     ##    */
+	0x30, 0x0C, /*   ##        ##   */
+	0x60, 0x06, /*  ##          ##  */
+	0x63, 0xF6, /*  ##   ###### ##  */
+	0xC6, 0x33, /* ##   ##   ##  ## */
+	0xCC, 0x33, /* ##  ##    ##  ## */
+	0xCC, 0x33, /* ##  ##    ##  ## */
+	0xCC, 0x33, /* ##  ##    ##  ## */
+	0xCC, 0x33, /* ##  ##    ##  ## */
+	0xCC, 0x33, /* ##  ##    ##  ## */
+	0x66, 0x72, /*  ##  ##  ###  #  */
+	0x63, 0xBE, /*  ##   ### #####  */
+	0x30, 0x00, /*   ##             */
+	0x1C, 0x10, /*    ###     #     */
+	0x07, 0xF0, /*      #######     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1007 'A' (13 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x07, 0x00, /*      ###         */
+	0x07, 0x00, /*      ###         */
+	0x0D, 0x80, /*     ## ##        */
+	0x0D, 0x80, /*     ## ##        */
+	0x0D, 0x80, /*     ## ##        */
+	0x18, 0xC0, /*    ##   ##       */
+	0x18, 0xC0, /*    ##   ##       */
+	0x30, 0x60, /*   ##     ##      */
+	0x3F, 0xE0, /*   #########      */
+	0x3F, 0xE0, /*   #########      */
+	0x60, 0x30, /*  ##       ##     */
+	0x60, 0x30, /*  ##       ##     */
+	0x60, 0x30, /*  ##       ##     */
+	0xC0, 0x18, /* ##         ##    */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1045 'B' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xFE, 0x00, /* #######          */
+	0xFF, 0x80, /* #########        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC3, 0x00, /* ##    ##         */
+	0xFE, 0x00, /* #######          */
+	0xFF, 0x80, /* #########        */
+	0xC1, 0xC0, /* ##     ###       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC1, 0xC0, /* ##     ###       */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x00, /* ########         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1083 'C' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xC0, /*     ######       */
+	0x3F, 0xE0, /*   #########      */
+	0x70, 0x20, /*  ###      #      */
+	0x60, 0x00, /*  ##              */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0x60, 0x00, /*  ##              */
+	0x70, 0x20, /*  ###      #      */
+	0x3F, 0xE0, /*   #########      */
+	0x0F, 0x80, /*     #####        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1121 'D' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xFF, 0x00, /* ########         */
+	0xFF, 0x80, /* #########        */
+	0xC1, 0xE0, /* ##     ####      */
+	0xC0, 0x60, /* ##       ##      */
+	0xC0, 0x70, /* ##       ###     */
+	0xC0, 0x30, /* ##        ##     */
+	0xC0, 0x30, /* ##        ##     */
+	0xC0, 0x30, /* ##        ##     */
+	0xC0, 0x30, /* ##        ##     */
+	0xC0, 0x70, /* ##       ###     */
+	0xC0, 0x60, /* ##       ##      */
+	0xC1, 0xC0, /* ##     ###       */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x00, /* ########         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1159 'E' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x80, /* #########        */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x80, /* #########        */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x80, /* #########        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1197 'F' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x80, /* #########        */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xFF, 0x00, /* ########         */
+	0xFF, 0x00, /* ########         */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1235 'G' (13 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0xE0, /*     #######      */
+	0x3F, 0xF8, /*   ###########    */
+	0x78, 0x18, /*  ####      ##    */
+	0x60, 0x00, /*  ##              */
+	0xE0, 0x00, /* ###              */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC1, 0xF8, /* ##     ######    */
+	0xC1, 0xF8, /* ##     ######    */
+	0xE0, 0x18, /* ###        ##    */
+	0x60, 0x18, /*  ##        ##    */
+	0x78, 0x18, /*  ####      ##    */
+	0x3F, 0xF8, /*   ###########    */
+	0x0F, 0xE0, /*     #######      */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1273 'H' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0xC0, /* ##########       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1311 'I' (6 pixels wide) */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0xFC, /* ######   */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0xFC, /* ######   */
+	0xFC, /* ######   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1330 'J' (7 pixels wide) */
+	0x00, /*          */
+	0x3E, /*   #####  */
+	0x3E, /*   #####  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x0E, /*     ###  */
+	0xFC, /* ######   */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1349 'K' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xC0, 0xE0, /* ##      ###      */
+	0xC1, 0xC0, /* ##     ###       */
+	0xC3, 0x80, /* ##    ###        */
+	0xC7, 0x00, /* ##   ###         */
+	0xCE, 0x00, /* ##  ###          */
+	0xDC, 0x00, /* ## ###           */
+	0xF8, 0x00, /* #####            */
+	0xFC, 0x00, /* ######           */
+	0xEC, 0x00, /* ### ##           */
+	0xC6, 0x00, /* ##   ##          */
+	0xC3, 0x00, /* ##    ##         */
+	0xC3, 0x80, /* ##    ###        */
+	0xC1, 0xC0, /* ##     ###       */
+	0xC0, 0xE0, /* ##      ###      */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1387 'L' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x80, /* #########        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1425 'M' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xE0, 0x70, /* ###      ###     */
+	0xE0, 0x70, /* ###      ###     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xD0, 0xB0, /* ## #    # ##     */
+	0xD9, 0xB0, /* ## ##  ## ##     */
+	0xC9, 0x30, /* ##  #  #  ##     */
+	0xCD, 0x30, /* ##  ## #  ##     */
+	0xCF, 0x30, /* ##  ####  ##     */
+	0xC6, 0x30, /* ##   ##   ##     */
+	0xC6, 0x30, /* ##   ##   ##     */
+	0xC0, 0x30, /* ##        ##     */
+	0xC0, 0x30, /* ##        ##     */
+	0xC0, 0x30, /* ##        ##     */
+	0xC0, 0x30, /* ##        ##     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1463 'N' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xE0, 0xC0, /* ###     ##       */
+	0xF0, 0xC0, /* ####    ##       */
+	0xF0, 0xC0, /* ####    ##       */
+	0xD0, 0xC0, /* ## #    ##       */
+	0xD8, 0xC0, /* ## ##   ##       */
+	0xC8, 0xC0, /* ##  #   ##       */
+	0xCC, 0xC0, /* ##  ##  ##       */
+	0xC4, 0xC0, /* ##   #  ##       */
+	0xC6, 0xC0, /* ##   ## ##       */
+	0xC2, 0xC0, /* ##    # ##       */
+	0xC3, 0xC0, /* ##    ####       */
+	0xC3, 0xC0, /* ##    ####       */
+	0xC1, 0xC0, /* ##     ###       */
+	0xC1, 0xC0, /* ##     ###       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1501 'O' (13 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0x80, /*     #####        */
+	0x3F, 0xE0, /*   #########      */
+	0x70, 0x70, /*  ###     ###     */
+	0x60, 0x30, /*  ##       ##     */
+	0xC0, 0x18, /* ##         ##    */
+	0xC0, 0x18, /* ##         ##    */
+	0xC0, 0x18, /* ##         ##    */
+	0xC0, 0x18, /* ##         ##    */
+	0xC0, 0x18, /* ##         ##    */
+	0xC0, 0x18, /* ##         ##    */
+	0x60, 0x30, /*  ##       ##     */
+	0x70, 0x70, /*  ###     ###     */
+	0x3F, 0xE0, /*   #########      */
+	0x0F, 0x80, /*     #####        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1539 'P' (8 pixels wide) */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0xFE, /* #######  */
+	0xC7, /* ##   ### */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC7, /* ##   ### */
+	0xFE, /* #######  */
+	0xFC, /* ######   */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1558 'Q' (13 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0F, 0x80, /*     #####        */
+	0x3F, 0xE0, /*   #########      */
+	0x70, 0x70, /*  ###     ###     */
+	0x60, 0x30, /*  ##       ##     */
+	0xC0, 0x18, /* ##         ##    */
+	0xC0, 0x18, /* ##         ##    */
+	0xC0, 0x18, /* ##         ##    */
+	0xC0, 0x18, /* ##         ##    */
+	0xC0, 0x18, /* ##         ##    */
+	0xC0, 0x18, /* ##         ##    */
+	0x60, 0x30, /*  ##       ##     */
+	0x70, 0x70, /*  ###     ###     */
+	0x3F, 0xE0, /*   #########      */
+	0x0F, 0x80, /*     #####        */
+	0x01, 0x80, /*        ##        */
+	0x01, 0xC0, /*        ###       */
+	0x00, 0xF8, /*         #####    */
+	0x00, 0x78, /*          ####    */
+
+	/* @1596 'R' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xFE, 0x00, /* #######          */
+	0xFF, 0x00, /* ########         */
+	0xC3, 0x80, /* ##    ###        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC3, 0x80, /* ##    ###        */
+	0xFF, 0x00, /* ########         */
+	0xFC, 0x00, /* ######           */
+	0xC6, 0x00, /* ##   ##          */
+	0xC7, 0x00, /* ##   ###         */
+	0xC3, 0x00, /* ##    ##         */
+	0xC1, 0x80, /* ##     ##        */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xE0, /* ##      ###      */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1634 'S' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x3F, 0x80, /*   #######        */
+	0x7F, 0xC0, /*  #########       */
+	0xE0, 0x40, /* ###      #       */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xE0, 0x00, /* ###              */
+	0x7F, 0x00, /*  #######         */
+	0x1F, 0xC0, /*    #######       */
+	0x00, 0xE0, /*         ###      */
+	0x00, 0x60, /*          ##      */
+	0x00, 0x60, /*          ##      */
+	0xC0, 0xE0, /* ##      ###      */
+	0xFF, 0xC0, /* ##########       */
+	0x7F, 0x00, /*  #######         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1672 'T' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xFF, 0xF0, /* ############     */
+	0xFF, 0xF0, /* ############     */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1710 'U' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0x61, 0x80, /*  ##    ##        */
+	0x7F, 0x80, /*  ########        */
+	0x3F, 0x00, /*   ######         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1748 'V' (13 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xC0, 0x18, /* ##         ##    */
+	0x60, 0x30, /*  ##       ##     */
+	0x60, 0x30, /*  ##       ##     */
+	0x60, 0x30, /*  ##       ##     */
+	0x30, 0x60, /*   ##     ##      */
+	0x30, 0x60, /*   ##     ##      */
+	0x38, 0xE0, /*   ###   ###      */
+	0x18, 0xC0, /*    ##   ##       */
+	0x18, 0xC0, /*    ##   ##       */
+	0x0D, 0x80, /*     ## ##        */
+	0x0D, 0x80, /*     ## ##        */
+	0x0D, 0x80, /*     ## ##        */
+	0x07, 0x00, /*      ###         */
+	0x07, 0x00, /*      ###         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1786 'W' (17 pixels wide) */
+	0x00, 0x00, 0x00, /*                          */
+	0xC1, 0xC1, 0x80, /* ##     ###     ##        */
+	0xC1, 0xC1, 0x80, /* ##     ###     ##        */
+	0x61, 0x43, 0x00, /*  ##    # #    ##         */
+	0x61, 0x43, 0x00, /*  ##    # #    ##         */
+	0x61, 0x63, 0x00, /*  ##    # ##   ##         */
+	0x63, 0x63, 0x00, /*  ##   ## ##   ##         */
+	0x32, 0x26, 0x00, /*   ##  #   #  ##          */
+	0x32, 0x26, 0x00, /*   ##  #   #  ##          */
+	0x32, 0x36, 0x00, /*   ##  #   ## ##          */
+	0x36, 0x36, 0x00, /*   ## ##   ## ##          */
+	0x1E, 0x14, 0x00, /*    ####    # #           */
+	0x1C, 0x1C, 0x00, /*    ###     ###           */
+	0x1C, 0x1C, 0x00, /*    ###     ###           */
+	0x0C, 0x1C, 0x00, /*     ##     ###           */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+
+	/* @1843 'X' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xE0, 0xE0, /* ###     ###      */
+	0x60, 0xC0, /*  ##     ##       */
+	0x31, 0x80, /*   ##   ##        */
+	0x31, 0x80, /*   ##   ##        */
+	0x1B, 0x00, /*    ## ##         */
+	0x0A, 0x00, /*     # #          */
+	0x0E, 0x00, /*     ###          */
+	0x0E, 0x00, /*     ###          */
+	0x0B, 0x00, /*     # ##         */
+	0x1B, 0x00, /*    ## ##         */
+	0x31, 0x80, /*   ##   ##        */
+	0x31, 0x80, /*   ##   ##        */
+	0x60, 0xC0, /*  ##     ##       */
+	0xE0, 0xE0, /* ###     ###      */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1881 'Y' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xE0, 0x70, /* ###      ###     */
+	0x60, 0x60, /*  ##      ##      */
+	0x30, 0xC0, /*   ##    ##       */
+	0x30, 0xC0, /*   ##    ##       */
+	0x19, 0x80, /*    ##  ##        */
+	0x1F, 0x80, /*    ######        */
+	0x0F, 0x00, /*     ####         */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1919 'Z' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xFF, 0xE0, /* ###########      */
+	0xFF, 0xE0, /* ###########      */
+	0x00, 0xE0, /*         ###      */
+	0x01, 0xC0, /*        ###       */
+	0x03, 0x80, /*       ###        */
+	0x07, 0x00, /*      ###         */
+	0x06, 0x00, /*      ##          */
+	0x0C, 0x00, /*     ##           */
+	0x1C, 0x00, /*    ###           */
+	0x38, 0x00, /*   ###            */
+	0x70, 0x00, /*  ###             */
+	0xE0, 0x00, /* ###              */
+	0xFF, 0xE0, /* ###########      */
+	0xFF, 0xE0, /* ###########      */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1957 '[' (5 pixels wide) */
+	0xF8, /* #####    */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xF8, /* #####    */
+
+	/* @1976 '\' (8 pixels wide) */
+	0xC0, /* ##       */
+	0xE0, /* ###      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x70, /*  ###     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x38, /*   ###    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x1C, /*    ###   */
+	0x0C, /*     ##   */
+	0x0C, /*     ##   */
+	0x0E, /*     ###  */
+	0x06, /*      ##  */
+	0x06, /*      ##  */
+	0x07, /*      ### */
+	0x03, /*       ## */
+	0x00, /*          */
+
+	/* @1995 ']' (5 pixels wide) */
+	0xF8, /* #####    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0xF8, /* #####    */
+
+	/* @2014 '^' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x06, 0x00, /*      ##          */
+	0x0F, 0x00, /*     ####         */
+	0x19, 0x80, /*    ##  ##        */
+	0x11, 0x80, /*    #   ##        */
+	0x30, 0xC0, /*   ##    ##       */
+	0x60, 0x60, /*  ##      ##      */
+	0xC0, 0x30, /* ##        ##     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2052 '_' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xFF, 0xF0, /* ############     */
+	0x00, 0x00, /*                  */
+
+	/* @2090 '`' (4 pixels wide) */
+	0xE0, /* ###      */
+	0x60, /*  ##      */
+	0x30, /*   ##     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @2109 'a' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x7F, /*  ####### */
+	0x03, /*       ## */
+	0x03, /*       ## */
+	0x3F, /*   ###### */
+	0x7F, /*  ####### */
+	0xE3, /* ###   ## */
+	0xC3, /* ##    ## */
+	0xC7, /* ##   ### */
+	0xFF, /* ######## */
+	0x7B, /*  #### ## */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @2128 'b' (9 pixels wide) */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xDE, 0x00, /* ## ####          */
+	0xFF, 0x00, /* ########         */
+	0xE3, 0x80, /* ###   ###        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC3, 0x00, /* ##    ##         */
+	0xFF, 0x00, /* ########         */
+	0xDE, 0x00, /* ## ####          */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2166 'c' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x1E, /*    ####  */
+	0x7F, /*  ####### */
+	0x61, /*  ##    # */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x61, /*  ##    # */
+	0x7F, /*  ####### */
+	0x1E, /*    ####  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @2185 'd' (9 pixels wide) */
+	0x01, 0x80, /*        ##        */
+	0x01, 0x80, /*        ##        */
+	0x01, 0x80, /*        ##        */
+	0x01, 0x80, /*        ##        */
+	0x3F, 0x80, /*   #######        */
+	0x7F, 0x80, /*  ########        */
+	0x61, 0x80, /*  ##    ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xE3, 0x80, /* ###   ###        */
+	0x7F, 0x80, /*  ########        */
+	0x3D, 0x80, /*   #### ##        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2223 'e' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x1E, 0x00, /*    ####          */
+	0x7F, 0x00, /*  #######         */
+	0x63, 0x80, /*  ##   ###        */
+	0xC1, 0x80, /* ##     ##        */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x80, /* #########        */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0x60, 0x80, /*  ##     #        */
+	0x7F, 0x80, /*  ########        */
+	0x1F, 0x00, /*    #####         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2261 'f' (6 pixels wide) */
+	0x3C, /*   ####   */
+	0x7C, /*  #####   */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0xF8, /* #####    */
+	0xF8, /* #####    */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @2280 'g' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x3F, 0x80, /*   #######        */
+	0x7F, 0x80, /*  ########        */
+	0x61, 0x80, /*  ##    ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xE3, 0x80, /* ###   ###        */
+	0x7F, 0x80, /*  ########        */
+	0x3D, 0x80, /*   #### ##        */
+	0x01, 0x80, /*        ##        */
+	0x03, 0x80, /*       ###        */
+	0x7F, 0x00, /*  #######         */
+	0x7E, 0x00, /*  ######          */
+
+	/* @2318 'h' (8 pixels wide) */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xDE, /* ## ####  */
+	0xFF, /* ######## */
+	0xE3, /* ###   ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @2337 'i' (2 pixels wide) */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @2356 'j' (5 pixels wide) */
+	0x00, /*          */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x78, /*  ####    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0xF8, /* #####    */
+	0xF0, /* ####     */
+
+	/* @2375 'k' (9 pixels wide) */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC3, 0x80, /* ##    ###        */
+	0xC3, 0x00, /* ##    ##         */
+	0xC6, 0x00, /* ##   ##          */
+	0xCC, 0x00, /* ##  ##           */
+	0xD8, 0x00, /* ## ##            */
+	0xF8, 0x00, /* #####            */
+	0xF8, 0x00, /* #####            */
+	0xCC, 0x00, /* ##  ##           */
+	0xC6, 0x00, /* ##   ##          */
+	0xC7, 0x00, /* ##   ###         */
+	0xC3, 0x80, /* ##    ###        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2413 'l' (2 pixels wide) */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @2432 'm' (14 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xDE, 0x78, /* ## ####  ####    */
+	0xFF, 0xFC, /* ##############   */
+	0xE3, 0x8C, /* ###   ###   ##   */
+	0xC3, 0x0C, /* ##    ##    ##   */
+	0xC3, 0x0C, /* ##    ##    ##   */
+	0xC3, 0x0C, /* ##    ##    ##   */
+	0xC3, 0x0C, /* ##    ##    ##   */
+	0xC3, 0x0C, /* ##    ##    ##   */
+	0xC3, 0x0C, /* ##    ##    ##   */
+	0xC3, 0x0C, /* ##    ##    ##   */
+	0xC3, 0x0C, /* ##    ##    ##   */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2470 'n' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xDE, /* ## ####  */
+	0xFF, /* ######## */
+	0xE3, /* ###   ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @2489 'o' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x1E, 0x00, /*    ####          */
+	0x7F, 0x80, /*  ########        */
+	0x61, 0x80, /*  ##    ##        */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0xC0, 0xC0, /* ##      ##       */
+	0x61, 0x80, /*  ##    ##        */
+	0x7F, 0x80, /*  ########        */
+	0x1E, 0x00, /*    ####          */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2527 'p' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xDE, 0x00, /* ## ####          */
+	0xFF, 0x00, /* ########         */
+	0xE3, 0x80, /* ###   ###        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC3, 0x00, /* ##    ##         */
+	0xFF, 0x00, /* ########         */
+	0xFE, 0x00, /* #######          */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+	0xC0, 0x00, /* ##               */
+
+	/* @2565 'q' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x3F, 0x80, /*   #######        */
+	0x7F, 0x80, /*  ########        */
+	0x61, 0x80, /*  ##    ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xC1, 0x80, /* ##     ##        */
+	0xE3, 0x80, /* ###   ###        */
+	0x7F, 0x80, /*  ########        */
+	0x3D, 0x80, /*   #### ##        */
+	0x01, 0x80, /*        ##        */
+	0x01, 0x80, /*        ##        */
+	0x01, 0x80, /*        ##        */
+	0x01, 0x80, /*        ##        */
+
+	/* @2603 'r' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xDC, /* ## ###   */
+	0xFC, /* ######   */
+	0xE0, /* ###      */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @2622 's' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x3E, /*   #####  */
+	0x7F, /*  ####### */
+	0xC1, /* ##     # */
+	0xC0, /* ##       */
+	0xF0, /* ####     */
+	0x7E, /*  ######  */
+	0x0F, /*     #### */
+	0x03, /*       ## */
+	0x83, /* #     ## */
+	0xFE, /* #######  */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @2641 't' (6 pixels wide) */
+	0x00, /*          */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0xFC, /* ######   */
+	0xFC, /* ######   */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0x7C, /*  #####   */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @2660 'u' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xC7, /* ##   ### */
+	0x7F, /*  ####### */
+	0x7B, /*  #### ## */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @2679 'v' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xC1, 0x80, /* ##     ##        */
+	0x63, 0x00, /*  ##   ##         */
+	0x63, 0x00, /*  ##   ##         */
+	0x63, 0x00, /*  ##   ##         */
+	0x22, 0x00, /*   #   #          */
+	0x36, 0x00, /*   ## ##          */
+	0x36, 0x00, /*   ## ##          */
+	0x14, 0x00, /*    # #           */
+	0x14, 0x00, /*    # #           */
+	0x1C, 0x00, /*    ###           */
+	0x08, 0x00, /*     #            */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2717 'w' (14 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xC3, 0x0C, /* ##    ##    ##   */
+	0xC3, 0x0C, /* ##    ##    ##   */
+	0x63, 0x98, /*  ##   ###  ##    */
+	0x67, 0x98, /*  ##  ####  ##    */
+	0x64, 0x98, /*  ##  #  #  ##    */
+	0x64, 0x98, /*  ##  #  #  ##    */
+	0x2C, 0xD0, /*   # ##  ## #     */
+	0x38, 0x50, /*   ###    # #     */
+	0x38, 0x70, /*   ###    ###     */
+	0x38, 0x70, /*   ###    ###     */
+	0x18, 0x20, /*    ##     #      */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2755 'x' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xE3, 0x80, /* ###   ###        */
+	0x63, 0x00, /*  ##   ##         */
+	0x36, 0x00, /*   ## ##          */
+	0x36, 0x00, /*   ## ##          */
+	0x1C, 0x00, /*    ###           */
+	0x08, 0x00, /*     #            */
+	0x1C, 0x00, /*    ###           */
+	0x36, 0x00, /*   ## ##          */
+	0x36, 0x00, /*   ## ##          */
+	0x63, 0x00, /*  ##   ##         */
+	0xE3, 0x80, /* ###   ###        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2793 'y' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xC1, 0x80, /* ##     ##        */
+	0x63, 0x00, /*  ##   ##         */
+	0x63, 0x00, /*  ##   ##         */
+	0x63, 0x00, /*  ##   ##         */
+	0x36, 0x00, /*   ## ##          */
+	0x36, 0x00, /*   ## ##          */
+	0x36, 0x00, /*   ## ##          */
+	0x14, 0x00, /*    # #           */
+	0x1C, 0x00, /*    ###           */
+	0x1C, 0x00, /*    ###           */
+	0x08, 0x00, /*     #            */
+	0x18, 0x00, /*    ##            */
+	0x18, 0x00, /*    ##            */
+	0x30, 0x00, /*   ##             */
+	0x30, 0x00, /*   ##             */
+
+	/* @2831 'z' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xFF, /* ######## */
+	0xFF, /* ######## */
+	0x07, /*      ### */
+	0x06, /*      ##  */
+	0x0C, /*     ##   */
+	0x18, /*    ##    */
+	0x30, /*   ##     */
+	0x60, /*  ##      */
+	0xE0, /* ###      */
+	0xFF, /* ######## */
+	0xFF, /* ######## */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @2850 '{' (9 pixels wide) */
+	0x03, 0x80, /*       ###        */
+	0x06, 0x00, /*      ##          */
+	0x0C, 0x00, /*     ##           */
+	0x0C, 0x00, /*     ##           */
+	0x0C, 0x00, /*     ##           */
+	0x0C, 0x00, /*     ##           */
+	0x0C, 0x00, /*     ##           */
+	0x0C, 0x00, /*     ##           */
+	0x18, 0x00, /*    ##            */
+	0xE0, 0x00, /* ###              */
+	0x18, 0x00, /*    ##            */
+	0x0C, 0x00, /*     ##           */
+	0x0C, 0x00, /*     ##           */
+	0x0C, 0x00, /*     ##           */
+	0x0C, 0x00, /*     ##           */
+	0x0C, 0x00, /*     ##           */
+	0x0C, 0x00, /*     ##           */
+	0x06, 0x00, /*      ##          */
+	0x03, 0x80, /*       ###        */
+
+	/* @2888 '|' (2 pixels wide) */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+	0xC0, /* ##       */
+
+	/* @2907 '}' (9 pixels wide) */
+	0xE0, 0x00, /* ###              */
+	0x30, 0x00, /*   ##             */
+	0x18, 0x00, /*    ##            */
+	0x18, 0x00, /*    ##            */
+	0x18, 0x00, /*    ##            */
+	0x18, 0x00, /*    ##            */
+	0x18, 0x00, /*    ##            */
+	0x18, 0x00, /*    ##            */
+	0x0C, 0x00, /*     ##           */
+	0x03, 0x80, /*       ###        */
+	0x0C, 0x00, /*     ##           */
+	0x18, 0x00, /*    ##            */
+	0x18, 0x00, /*    ##            */
+	0x18, 0x00, /*    ##            */
+	0x18, 0x00, /*    ##            */
+	0x18, 0x00, /*    ##            */
+	0x18, 0x00, /*    ##            */
+	0x30, 0x00, /*   ##             */
+	0xE0, 0x00, /* ###              */
+
+	/* @2945 '~' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x38, 0x30, /*   ###     ##     */
+	0x7C, 0x30, /*  #####    ##     */
+	0xE6, 0x70, /* ###  ##  ###     */
+	0xC3, 0xE0, /* ##    #####      */
+	0xC1, 0xC0, /* ##     ###       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+};
+
+/* Character descriptors for Verdana 14pt */
+/* { [Char width in bits], [Offset into verdana14ptCharBitmaps in bytes] } */
+const FONT_CHAR_INFO verdana14ptDescriptors[] = 
+{
+	{5, 0}, 		/*   */ 
+	{2, 19}, 		/* ! */ 
+	{6, 38}, 		/* " */ 
+	{12, 57}, 		/* # */ 
+	{9, 95}, 		/* $ */ 
+	{18, 133}, 		/* % */ 
+	{13, 190}, 		/* & */ 
+	{2, 228}, 		/* ' */ 
+	{6, 247}, 		/* ( */ 
+	{6, 266}, 		/* ) */ 
+	{9, 285}, 		/* * */ 
+	{12, 323}, 		/* + */ 
+	{4, 361}, 		/* , */ 
+	{6, 380}, 		/* - */ 
+	{2, 399}, 		/* . */ 
+	{8, 418}, 		/* / */ 
+	{10, 437}, 		/* 0 */ 
+	{8, 475}, 		/* 1 */ 
+	{9, 494}, 		/* 2 */ 
+	{9, 532}, 		/* 3 */ 
+	{10, 570}, 		/* 4 */ 
+	{9, 608}, 		/* 5 */ 
+	{10, 646}, 		/* 6 */ 
+	{9, 684}, 		/* 7 */ 
+	{10, 722}, 		/* 8 */ 
+	{10, 760}, 		/* 9 */ 
+	{2, 798}, 		/* : */ 
+	{4, 817}, 		/* ; */ 
+	{11, 836}, 		/* < */ 
+	{11, 874}, 		/* = */ 
+	{11, 912}, 		/* > */ 
+	{8, 950}, 		/* ? */ 
+	{16, 969}, 		/* @ */ 
+	{13, 1007}, 		/* A */ 
+	{10, 1045}, 		/* B */ 
+	{11, 1083}, 		/* C */ 
+	{12, 1121}, 		/* D */ 
+	{9, 1159}, 		/* E */ 
+	{9, 1197}, 		/* F */ 
+	{13, 1235}, 		/* G */ 
+	{10, 1273}, 		/* H */ 
+	{6, 1311}, 		/* I */ 
+	{7, 1330}, 		/* J */ 
+	{11, 1349}, 		/* K */ 
+	{9, 1387}, 		/* L */ 
+	{12, 1425}, 		/* M */ 
+	{10, 1463}, 		/* N */ 
+	{13, 1501}, 		/* O */ 
+	{8, 1539}, 		/* P */ 
+	{13, 1558}, 		/* Q */ 
+	{11, 1596}, 		/* R */ 
+	{11, 1634}, 		/* S */ 
+	{12, 1672}, 		/* T */ 
+	{10, 1710}, 		/* U */ 
+	{13, 1748}, 		/* V */ 
+	{17, 1786}, 		/* W */ 
+	{11, 1843}, 		/* X */ 
+	{12, 1881}, 		/* Y */ 
+	{11, 1919}, 		/* Z */ 
+	{5, 1957}, 		/* [ */ 
+	{8, 1976}, 		/* \ */ 
+	{5, 1995}, 		/* ] */ 
+	{12, 2014}, 		/* ^ */ 
+	{12, 2052}, 		/* _ */ 
+	{4, 2090}, 		/* ` */ 
+	{8, 2109}, 		/* a */ 
+	{9, 2128}, 		/* b */ 
+	{8, 2166}, 		/* c */ 
+	{9, 2185}, 		/* d */ 
+	{9, 2223}, 		/* e */ 
+	{6, 2261}, 		/* f */ 
+	{9, 2280}, 		/* g */ 
+	{8, 2318}, 		/* h */ 
+	{2, 2337}, 		/* i */ 
+	{5, 2356}, 		/* j */ 
+	{9, 2375}, 		/* k */ 
+	{2, 2413}, 		/* l */ 
+	{14, 2432}, 		/* m */ 
+	{8, 2470}, 		/* n */ 
+	{10, 2489}, 		/* o */ 
+	{9, 2527}, 		/* p */ 
+	{9, 2565}, 		/* q */ 
+	{6, 2603}, 		/* r */ 
+	{8, 2622}, 		/* s */ 
+	{6, 2641}, 		/* t */ 
+	{8, 2660}, 		/* u */ 
+	{9, 2679}, 		/* v */ 
+	{14, 2717}, 		/* w */ 
+	{9, 2755}, 		/* x */ 
+	{9, 2793}, 		/* y */ 
+	{8, 2831}, 		/* z */ 
+	{9, 2850}, 		/* { */ 
+	{2, 2888}, 		/* | */ 
+	{9, 2907}, 		/* } */ 
+	{12, 2945}, 		/* ~ */ 
+};
+
+/* Font information for Verdana 14pt */
+const FONT_INFO verdana14ptFontInfo =
+{
+	19, /*  Character height */
+	' ', /*  Start character */
+	'~', /*  End character */
+	verdana14ptDescriptors, /*  Character descriptor array */
+	verdana14ptBitmaps, /*  Character bitmap array */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/verdana14.h b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/verdana14.h
new file mode 100644
index 0000000000000000000000000000000000000000..ac9ca85960fdb6a9d781ff59ea05c7346f9752a8
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/verdana14.h
@@ -0,0 +1,19 @@
+#ifndef __VERDANA_14__
+#define __VERDANA_14__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../fonts.h"
+
+/* Font data for Verdana 14pt */
+extern const uint8_t verdana14ptBitmaps[];
+extern const FONT_INFO verdana14ptFontInfo;
+extern const FONT_CHAR_INFO verdana14ptDescriptors[];
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/verdana9.c b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/verdana9.c
new file mode 100644
index 0000000000000000000000000000000000000000..42f57926a0c77839d2a3cc8d602ebefdad6d877b
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/verdana9.c
@@ -0,0 +1,1450 @@
+#include "verdana9.h"
+
+/* 
+**  Font data for Verdana 9pt
+*/
+
+/* Character bitmaps for Verdana 9pt */
+const uint8_t verdana9ptBitmaps[] = 
+{
+	/* @0 ' ' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @12 '!' (1 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @24 '"' (4 pixels wide) */
+	0x90, /* #  #     */
+	0x90, /* #  #     */
+	0x90, /* #  #     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @36 '#' (8 pixels wide) */
+	0x00, /*          */
+	0x12, /*    #  #  */
+	0x12, /*    #  #  */
+	0x24, /*   #  #   */
+	0x7F, /*  ####### */
+	0x24, /*   #  #   */
+	0x24, /*   #  #   */
+	0xFE, /* #######  */
+	0x48, /*  #  #    */
+	0x48, /*  #  #    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @48 '$' (6 pixels wide) */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x7C, /*  #####   */
+	0xA0, /* # #      */
+	0xA0, /* # #      */
+	0x60, /*  ##      */
+	0x38, /*   ###    */
+	0x24, /*   #  #   */
+	0x24, /*   #  #   */
+	0xF8, /* #####    */
+	0x20, /*   #      */
+	0x20, /*   #      */
+
+	/* @60 '%' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x61, 0x00, /*  ##    #         */
+	0x92, 0x00, /* #  #  #          */
+	0x92, 0x00, /* #  #  #          */
+	0x94, 0x00, /* #  # #           */
+	0x64, 0xC0, /*  ##  #  ##       */
+	0x05, 0x20, /*      # #  #      */
+	0x09, 0x20, /*     #  #  #      */
+	0x09, 0x20, /*     #  #  #      */
+	0x10, 0xC0, /*    #    ##       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @84 '&' (8 pixels wide) */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x72, /*  ###  #  */
+	0x8A, /* #   # #  */
+	0x84, /* #    #   */
+	0x86, /* #    ##  */
+	0x79, /*  ####  # */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @96 ''' (1 pixels wide) */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @108 '(' (3 pixels wide) */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x20, /*   #      */
+
+	/* @120 ')' (3 pixels wide) */
+	0x80, /* #        */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x80, /* #        */
+
+	/* @132 '*' (5 pixels wide) */
+	0x20, /*   #      */
+	0xA8, /* # # #    */
+	0x70, /*  ###     */
+	0xA8, /* # # #    */
+	0x20, /*   #      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @144 '+' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0xFE, /* #######  */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @156 ',' (2 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x80, /* #        */
+
+	/* @168 '-' (4 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @180 '.' (1 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @192 '/' (5 pixels wide) */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x80, /* #        */
+
+	/* @204 '0' (6 pixels wide) */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @216 '1' (5 pixels wide) */
+	0x00, /*          */
+	0x20, /*   #      */
+	0xE0, /* ###      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @228 '2' (6 pixels wide) */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x04, /*      #   */
+	0x08, /*     #    */
+	0x30, /*   ##     */
+	0x40, /*  #       */
+	0x80, /* #        */
+	0xFC, /* ######   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @240 '3' (6 pixels wide) */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x84, /* #    #   */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x38, /*   ###    */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x84, /* #    #   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @252 '4' (7 pixels wide) */
+	0x00, /*          */
+	0x08, /*     #    */
+	0x18, /*    ##    */
+	0x28, /*   # #    */
+	0x48, /*  #  #    */
+	0x88, /* #   #    */
+	0xFE, /* #######  */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @264 '5' (6 pixels wide) */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xF8, /* #####    */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x84, /* #    #   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @276 '6' (6 pixels wide) */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x40, /*  #       */
+	0x80, /* #        */
+	0xF8, /* #####    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @288 '7' (6 pixels wide) */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0x04, /*      #   */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @300 '8' (6 pixels wide) */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x78, /*  ####    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @312 '9' (6 pixels wide) */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x7C, /*  #####   */
+	0x04, /*      #   */
+	0x08, /*     #    */
+	0x70, /*  ###     */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @324 ':' (1 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @336 ';' (2 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x80, /* #        */
+
+	/* @348 '<' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x06, /*      ##  */
+	0x18, /*    ##    */
+	0x60, /*  ##      */
+	0x80, /* #        */
+	0x60, /*  ##      */
+	0x18, /*    ##    */
+	0x06, /*      ##  */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @360 '=' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xFE, /* #######  */
+	0x00, /*          */
+	0xFE, /* #######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @372 '>' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xC0, /* ##       */
+	0x30, /*   ##     */
+	0x0C, /*     ##   */
+	0x02, /*       #  */
+	0x0C, /*     ##   */
+	0x30, /*   ##     */
+	0xC0, /* ##       */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @384 '?' (5 pixels wide) */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0x88, /* #   #    */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x00, /*          */
+	0x20, /*   #      */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @396 '@' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x1E, 0x00, /*    ####          */
+	0x61, 0x80, /*  ##    ##        */
+	0x4E, 0x80, /*  #  ### #        */
+	0x92, 0x40, /* #  #  #  #       */
+	0x92, 0x40, /* #  #  #  #       */
+	0x92, 0x40, /* #  #  #  #       */
+	0x92, 0x40, /* #  #  #  #       */
+	0x4F, 0x80, /*  #  #####        */
+	0x60, 0x00, /*  ##              */
+	0x1E, 0x00, /*    ####          */
+	0x00, 0x00, /*                  */
+
+	/* @420 'A' (8 pixels wide) */
+	0x00, /*          */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x24, /*   #  #   */
+	0x24, /*   #  #   */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x7E, /*  ######  */
+	0x81, /* #      # */
+	0x81, /* #      # */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @432 'B' (6 pixels wide) */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0xF8, /* #####    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @444 'C' (7 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x42, /*  #    #  */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x42, /*  #    #  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @456 'D' (7 pixels wide) */
+	0x00, /*          */
+	0xF8, /* #####    */
+	0x84, /* #    #   */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x84, /* #    #   */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @468 'E' (6 pixels wide) */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xFC, /* ######   */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xFC, /* ######   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @480 'F' (6 pixels wide) */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xF8, /* #####    */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @492 'G' (7 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x42, /*  #    #  */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x8E, /* #   ###  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x42, /*  #    #  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @504 'H' (7 pixels wide) */
+	0x00, /*          */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0xFE, /* #######  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @516 'I' (3 pixels wide) */
+	0x00, /*          */
+	0xE0, /* ###      */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0xE0, /* ###      */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @528 'J' (4 pixels wide) */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0xE0, /* ###      */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @540 'K' (6 pixels wide) */
+	0x00, /*          */
+	0x84, /* #    #   */
+	0x88, /* #   #    */
+	0x90, /* #  #     */
+	0xA0, /* # #      */
+	0xC0, /* ##       */
+	0xA0, /* # #      */
+	0x90, /* #  #     */
+	0x88, /* #   #    */
+	0x84, /* #    #   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @552 'L' (6 pixels wide) */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xFC, /* ######   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @564 'M' (8 pixels wide) */
+	0x00, /*          */
+	0xC3, /* ##    ## */
+	0xC3, /* ##    ## */
+	0xA5, /* # #  # # */
+	0xA5, /* # #  # # */
+	0xA5, /* # #  # # */
+	0x99, /* #  ##  # */
+	0x99, /* #  ##  # */
+	0x81, /* #      # */
+	0x81, /* #      # */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @576 'N' (7 pixels wide) */
+	0x00, /*          */
+	0xC2, /* ##    #  */
+	0xC2, /* ##    #  */
+	0xA2, /* # #   #  */
+	0xA2, /* # #   #  */
+	0x92, /* #  #  #  */
+	0x8A, /* #   # #  */
+	0x8A, /* #   # #  */
+	0x86, /* #    ##  */
+	0x86, /* #    ##  */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @588 'O' (8 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x42, /*  #    #  */
+	0x81, /* #      # */
+	0x81, /* #      # */
+	0x81, /* #      # */
+	0x81, /* #      # */
+	0x81, /* #      # */
+	0x42, /*  #    #  */
+	0x3C, /*   ####   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @600 'P' (6 pixels wide) */
+	0x00, /*          */
+	0xF8, /* #####    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0xF8, /* #####    */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @612 'Q' (8 pixels wide) */
+	0x00, /*          */
+	0x3C, /*   ####   */
+	0x42, /*  #    #  */
+	0x81, /* #      # */
+	0x81, /* #      # */
+	0x81, /* #      # */
+	0x81, /* #      # */
+	0x81, /* #      # */
+	0x42, /*  #    #  */
+	0x3C, /*   ####   */
+	0x04, /*      #   */
+	0x03, /*       ## */
+
+	/* @624 'R' (7 pixels wide) */
+	0x00, /*          */
+	0xF8, /* #####    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0xF8, /* #####    */
+	0x90, /* #  #     */
+	0x88, /* #   #    */
+	0x84, /* #    #   */
+	0x82, /* #     #  */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @636 'S' (6 pixels wide) */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x84, /* #    #   */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x78, /*  ####    */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x84, /* #    #   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @648 'T' (7 pixels wide) */
+	0x00, /*          */
+	0xFE, /* #######  */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @660 'U' (7 pixels wide) */
+	0x00, /*          */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x82, /* #     #  */
+	0x44, /*  #   #   */
+	0x38, /*   ###    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @672 'V' (8 pixels wide) */
+	0x00, /*          */
+	0x81, /* #      # */
+	0x81, /* #      # */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x42, /*  #    #  */
+	0x24, /*   #  #   */
+	0x24, /*   #  #   */
+	0x18, /*    ##    */
+	0x18, /*    ##    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @684 'W' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x84, 0x20, /* #    #    #      */
+	0x84, 0x20, /* #    #    #      */
+	0x8A, 0x20, /* #   # #   #      */
+	0x8A, 0x20, /* #   # #   #      */
+	0x4A, 0x40, /*  #  # #  #       */
+	0x51, 0x40, /*  # #   # #       */
+	0x51, 0x40, /*  # #   # #       */
+	0x20, 0x80, /*   #     #        */
+	0x20, 0x80, /*   #     #        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @708 'X' (6 pixels wide) */
+	0x00, /*          */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x48, /*  #  #    */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x30, /*   ##     */
+	0x48, /*  #  #    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @720 'Y' (7 pixels wide) */
+	0x00, /*          */
+	0x82, /* #     #  */
+	0x44, /*  #   #   */
+	0x44, /*  #   #   */
+	0x28, /*   # #    */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @732 'Z' (6 pixels wide) */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0x04, /*      #   */
+	0x08, /*     #    */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0x80, /* #        */
+	0xFC, /* ######   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @744 '[' (3 pixels wide) */
+	0xE0, /* ###      */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xE0, /* ###      */
+
+	/* @756 '\' (5 pixels wide) */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x10, /*    #     */
+	0x08, /*     #    */
+	0x08, /*     #    */
+
+	/* @768 ']' (3 pixels wide) */
+	0xE0, /* ###      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0xE0, /* ###      */
+
+	/* @780 '^' (8 pixels wide) */
+	0x00, /*          */
+	0x18, /*    ##    */
+	0x24, /*   #  #   */
+	0x42, /*  #    #  */
+	0x81, /* #      # */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @792 '_' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xFF, /* ######## */
+
+	/* @804 '`' (2 pixels wide) */
+	0x80, /* #        */
+	0x40, /*  #       */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @816 'a' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x7C, /*  #####   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x7C, /*  #####   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @828 'b' (6 pixels wide) */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xB8, /* # ###    */
+	0xC4, /* ##   #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @840 'c' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x70, /*  ###     */
+	0x88, /* #   #    */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x88, /* #   #    */
+	0x70, /*  ###     */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @852 'd' (6 pixels wide) */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x04, /*      #   */
+	0x7C, /*  #####   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x8C, /* #   ##   */
+	0x74, /*  ### #   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @864 'e' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0xFC, /* ######   */
+	0x80, /* #        */
+	0x84, /* #    #   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @876 'f' (4 pixels wide) */
+	0x30, /*   ##     */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0xF0, /* ####     */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @888 'g' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x8C, /* #   ##   */
+	0x74, /*  ### #   */
+	0x04, /*      #   */
+	0x78, /*  ####    */
+
+	/* @900 'h' (6 pixels wide) */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0xB8, /* # ###    */
+	0xC4, /* ##   #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @912 'i' (1 pixels wide) */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @924 'j' (3 pixels wide) */
+	0x20, /*   #      */
+	0x00, /*          */
+	0x00, /*          */
+	0x60, /*  ##      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0xC0, /* ##       */
+
+	/* @936 'k' (5 pixels wide) */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x88, /* #   #    */
+	0x90, /* #  #     */
+	0xA0, /* # #      */
+	0xC0, /* ##       */
+	0xA0, /* # #      */
+	0x90, /* #  #     */
+	0x88, /* #   #    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @948 'l' (1 pixels wide) */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @960 'm' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xF7, 0x00, /* #### ###         */
+	0x88, 0x80, /* #   #   #        */
+	0x88, 0x80, /* #   #   #        */
+	0x88, 0x80, /* #   #   #        */
+	0x88, 0x80, /* #   #   #        */
+	0x88, 0x80, /* #   #   #        */
+	0x88, 0x80, /* #   #   #        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @984 'n' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xB8, /* # ###    */
+	0xC4, /* ##   #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @996 'o' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1008 'p' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xB8, /* # ###    */
+	0xC4, /* ##   #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0xF8, /* #####    */
+	0x80, /* #        */
+	0x80, /* #        */
+
+	/* @1020 'q' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x7C, /*  #####   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x8C, /* #   ##   */
+	0x74, /*  ### #   */
+	0x04, /*      #   */
+	0x04, /*      #   */
+
+	/* @1032 'r' (4 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xB0, /* # ##     */
+	0xC0, /* ##       */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1044 's' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x70, /*  ###     */
+	0x08, /*     #    */
+	0x08, /*     #    */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1056 't' (5 pixels wide) */
+	0x00, /*          */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0xF8, /* #####    */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x40, /*  #       */
+	0x38, /*   ###    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1068 'u' (6 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x84, /* #    #   */
+	0x8C, /* #   ##   */
+	0x74, /*  ### #   */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1080 'v' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x50, /*  # #     */
+	0x50, /*  # #     */
+	0x50, /*  # #     */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1092 'w' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x88, 0x80, /* #   #   #        */
+	0x88, 0x80, /* #   #   #        */
+	0x55, 0x00, /*  # # # #         */
+	0x55, 0x00, /*  # # # #         */
+	0x55, 0x00, /*  # # # #         */
+	0x22, 0x00, /*   #   #          */
+	0x22, 0x00, /*   #   #          */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1116 'x' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x50, /*  # #     */
+	0x20, /*   #      */
+	0x50, /*  # #     */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1128 'y' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x88, /* #   #    */
+	0x88, /* #   #    */
+	0x50, /*  # #     */
+	0x50, /*  # #     */
+	0x50, /*  # #     */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x40, /*  #       */
+
+	/* @1140 'z' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xF8, /* #####    */
+	0x08, /*     #    */
+	0x10, /*    #     */
+	0x20, /*   #      */
+	0x40, /*  #       */
+	0x80, /* #        */
+	0xF8, /* #####    */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1152 '{' (5 pixels wide) */
+	0x18, /*    ##    */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0xC0, /* ##       */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x18, /*    ##    */
+
+	/* @1164 '|' (1 pixels wide) */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+	0x80, /* #        */
+
+	/* @1176 '}' (5 pixels wide) */
+	0xC0, /* ##       */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x18, /*    ##    */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0x20, /*   #      */
+	0xC0, /* ##       */
+
+	/* @1188 '~' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x61, /*  ##    # */
+	0x99, /* #  ##  # */
+	0x86, /* #    ##  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+};
+
+/* Character descriptors for Verdana 9pt */
+/* { [Char width in bits], [Offset into verdana9ptCharBitmaps in bytes] } */
+const FONT_CHAR_INFO verdana9ptDescriptors[] = 
+{
+	{8, 0}, 		/*   */ 
+	{1, 12}, 		/* ! */ 
+	{4, 24}, 		/* " */ 
+	{8, 36}, 		/* # */ 
+	{6, 48}, 		/* $ */ 
+	{11, 60}, 		/* % */ 
+	{8, 84}, 		/* & */ 
+	{1, 96}, 		/* ' */ 
+	{3, 108}, 		/* ( */ 
+	{3, 120}, 		/* ) */ 
+	{5, 132}, 		/* * */ 
+	{7, 144}, 		/* + */ 
+	{2, 156}, 		/* , */ 
+	{4, 168}, 		/* - */ 
+	{1, 180}, 		/* . */ 
+	{5, 192}, 		/* / */ 
+	{6, 204}, 		/* 0 */ 
+	{5, 216}, 		/* 1 */ 
+	{6, 228}, 		/* 2 */ 
+	{6, 240}, 		/* 3 */ 
+	{7, 252}, 		/* 4 */ 
+	{6, 264}, 		/* 5 */ 
+	{6, 276}, 		/* 6 */ 
+	{6, 288}, 		/* 7 */ 
+	{6, 300}, 		/* 8 */ 
+	{6, 312}, 		/* 9 */ 
+	{1, 324}, 		/* : */ 
+	{2, 336}, 		/* ; */ 
+	{7, 348}, 		/* < */ 
+	{7, 360}, 		/* = */ 
+	{7, 372}, 		/* > */ 
+	{5, 384}, 		/* ? */ 
+	{10, 396}, 		/* @ */ 
+	{8, 420}, 		/* A */ 
+	{6, 432}, 		/* B */ 
+	{7, 444}, 		/* C */ 
+	{7, 456}, 		/* D */ 
+	{6, 468}, 		/* E */ 
+	{6, 480}, 		/* F */ 
+	{7, 492}, 		/* G */ 
+	{7, 504}, 		/* H */ 
+	{3, 516}, 		/* I */ 
+	{4, 528}, 		/* J */ 
+	{6, 540}, 		/* K */ 
+	{6, 552}, 		/* L */ 
+	{8, 564}, 		/* M */ 
+	{7, 576}, 		/* N */ 
+	{8, 588}, 		/* O */ 
+	{6, 600}, 		/* P */ 
+	{8, 612}, 		/* Q */ 
+	{7, 624}, 		/* R */ 
+	{6, 636}, 		/* S */ 
+	{7, 648}, 		/* T */ 
+	{7, 660}, 		/* U */ 
+	{8, 672}, 		/* V */ 
+	{11, 684}, 		/* W */ 
+	{6, 708}, 		/* X */ 
+	{7, 720}, 		/* Y */ 
+	{6, 732}, 		/* Z */ 
+	{3, 744}, 		/* [ */ 
+	{5, 756}, 		/* \ */ 
+	{3, 768}, 		/* ] */ 
+	{8, 780}, 		/* ^ */ 
+	{8, 792}, 		/* _ */ 
+	{2, 804}, 		/* ` */ 
+	{6, 816}, 		/* a */ 
+	{6, 828}, 		/* b */ 
+	{5, 840}, 		/* c */ 
+	{6, 852}, 		/* d */ 
+	{6, 864}, 		/* e */ 
+	{4, 876}, 		/* f */ 
+	{6, 888}, 		/* g */ 
+	{6, 900}, 		/* h */ 
+	{1, 912}, 		/* i */ 
+	{3, 924}, 		/* j */ 
+	{5, 936}, 		/* k */ 
+	{1, 948}, 		/* l */ 
+	{9, 960}, 		/* m */ 
+	{6, 984}, 		/* n */ 
+	{6, 996}, 		/* o */ 
+	{6, 1008}, 		/* p */ 
+	{6, 1020}, 		/* q */ 
+	{4, 1032}, 		/* r */ 
+	{5, 1044}, 		/* s */ 
+	{5, 1056}, 		/* t */ 
+	{6, 1068}, 		/* u */ 
+	{5, 1080}, 		/* v */ 
+	{9, 1092}, 		/* w */ 
+	{5, 1116}, 		/* x */ 
+	{5, 1128}, 		/* y */ 
+	{5, 1140}, 		/* z */ 
+	{5, 1152}, 		/* { */ 
+	{1, 1164}, 		/* | */ 
+	{5, 1176}, 		/* } */ 
+	{8, 1188}, 		/* ~ */ 
+};
+
+/* Font information for Verdana 9pt */
+const FONT_INFO verdana9ptFontInfo =
+{
+	12, /*  Character height */
+	' ', /*  Start character */
+	'~', /*  End character */
+	verdana9ptDescriptors, /*  Character descriptor array */
+	verdana9ptBitmaps, /*  Character bitmap array */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/verdana9.h b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/verdana9.h
new file mode 100644
index 0000000000000000000000000000000000000000..47b89fd94aa52d94564d760416180f599270040d
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/verdana9.h
@@ -0,0 +1,19 @@
+#ifndef __VERDANA_9__
+#define __VERDANA_9__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../fonts.h"
+
+/* Font data for Verdana 9pt */
+extern const uint8_t verdana9ptBitmaps[];
+extern const FONT_INFO verdana9ptFontInfo;
+extern const FONT_CHAR_INFO verdana9ptDescriptors[];
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/verdanabold14.c b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/verdanabold14.c
new file mode 100644
index 0000000000000000000000000000000000000000..5882f5ebedf92f9b9c02c70ca64d1acd924acded
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/verdanabold14.c
@@ -0,0 +1,2210 @@
+#include "verdanabold14.h"
+
+/* 
+**  Font data for Verdana Bold 14pt
+*/
+
+/* Character bitmaps for Verdana Bold 14pt */
+const uint8_t verdanabold14ptBitmaps[] = 
+{
+	/* @0 ' ' (4 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @20 '!' (4 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @40 '"' (8 pixels wide) */
+	0x00, /*          */
+	0xE7, /* ###  ### */
+	0xE7, /* ###  ### */
+	0xE7, /* ###  ### */
+	0xE7, /* ###  ### */
+	0xE7, /* ###  ### */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @60 '#' (14 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x06, 0x30, /*      ##   ##     */
+	0x06, 0x30, /*      ##   ##     */
+	0x0E, 0x60, /*     ###  ##      */
+	0x7F, 0xFC, /*  #############   */
+	0x7F, 0xFC, /*  #############   */
+	0x0C, 0x60, /*     ##   ##      */
+	0x0C, 0x60, /*     ##   ##      */
+	0x18, 0xC0, /*    ##   ##       */
+	0xFF, 0xF8, /* #############    */
+	0xFF, 0xF8, /* #############    */
+	0x18, 0xC0, /*    ##   ##       */
+	0x18, 0xC0, /*    ##   ##       */
+	0x31, 0x80, /*   ##   ##        */
+	0x31, 0x80, /*   ##   ##        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @100 '$' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x1F, 0xE0, /*    ########      */
+	0x7F, 0xE0, /*  ##########      */
+	0xFF, 0xE0, /* ###########      */
+	0xF6, 0x00, /* #### ##          */
+	0xFE, 0x00, /* #######          */
+	0x7F, 0xC0, /*  #########       */
+	0x3F, 0xF0, /*   ##########     */
+	0x07, 0xF0, /*      #######     */
+	0xC6, 0xF0, /* ##   ## ####     */
+	0xFF, 0xF0, /* ############     */
+	0xFF, 0xE0, /* ###########      */
+	0x7F, 0x80, /*  ########        */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x06, 0x00, /*      ##          */
+	0x00, 0x00, /*                  */
+
+	/* @140 '%' (22 pixels wide) */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+	0x3C, 0x03, 0x00, /*   ####        ##         */
+	0x7E, 0x06, 0x00, /*  ######      ##          */
+	0xE7, 0x0E, 0x00, /* ###  ###    ###          */
+	0xE7, 0x0C, 0x00, /* ###  ###    ##           */
+	0xE7, 0x18, 0x00, /* ###  ###   ##            */
+	0xE7, 0x18, 0xF0, /* ###  ###   ##   ####     */
+	0xE7, 0x31, 0xF8, /* ###  ###  ##   ######    */
+	0x7E, 0x33, 0x9C, /*  ######   ##  ###  ###   */
+	0x3C, 0x63, 0x9C, /*   ####   ##   ###  ###   */
+	0x00, 0x63, 0x9C, /*          ##   ###  ###   */
+	0x00, 0xC3, 0x9C, /*         ##    ###  ###   */
+	0x01, 0xC3, 0x9C, /*        ###    ###  ###   */
+	0x01, 0x81, 0xF8, /*        ##      ######    */
+	0x03, 0x00, 0xF0, /*       ##        ####     */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+
+	/* @200 '&' (15 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x1F, 0x00, /*    #####         */
+	0x3F, 0x80, /*   #######        */
+	0x7F, 0xC0, /*  #########       */
+	0x7B, 0xC0, /*  #### ####       */
+	0x7B, 0xC0, /*  #### ####       */
+	0x3B, 0x80, /*   ### ###        */
+	0x3F, 0x3C, /*   ######  ####   */
+	0x7E, 0x3C, /*  ######   ####   */
+	0xF7, 0xBC, /* #### #### ####   */
+	0xF3, 0xFC, /* ####  ########   */
+	0xF9, 0xF8, /* #####  ######    */
+	0xFF, 0xF8, /* #############    */
+	0x7F, 0xF8, /*  ############    */
+	0x1F, 0x3E, /*    #####  #####  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @240 ''' (3 pixels wide) */
+	0x00, /*          */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @260 '(' (7 pixels wide) */
+	0x00, /*          */
+	0x1E, /*    ####  */
+	0x3C, /*   ####   */
+	0x38, /*   ###    */
+	0x78, /*  ####    */
+	0x70, /*  ###     */
+	0x70, /*  ###     */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0x70, /*  ###     */
+	0x70, /*  ###     */
+	0x78, /*  ####    */
+	0x38, /*   ###    */
+	0x3C, /*   ####   */
+	0x1E, /*    ####  */
+
+	/* @280 ')' (7 pixels wide) */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0x78, /*  ####    */
+	0x38, /*   ###    */
+	0x3C, /*   ####   */
+	0x1C, /*    ###   */
+	0x1C, /*    ###   */
+	0x0E, /*     ###  */
+	0x0E, /*     ###  */
+	0x0E, /*     ###  */
+	0x0E, /*     ###  */
+	0x0E, /*     ###  */
+	0x0E, /*     ###  */
+	0x0E, /*     ###  */
+	0x1C, /*    ###   */
+	0x1C, /*    ###   */
+	0x3C, /*   ####   */
+	0x38, /*   ###    */
+	0x78, /*  ####    */
+	0xF0, /* ####     */
+
+	/* @300 '*' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x0C, 0x00, /*     ##           */
+	0x4C, 0x80, /*  #  ##  #        */
+	0xED, 0xC0, /* ### ## ###       */
+	0x3F, 0x00, /*   ######         */
+	0x1E, 0x00, /*    ####          */
+	0x3F, 0x00, /*   ######         */
+	0xED, 0xC0, /* ### ## ###       */
+	0x4C, 0x80, /*  #  ##  #        */
+	0x0C, 0x00, /*     ##           */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @340 '+' (13 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x07, 0x00, /*      ###         */
+	0x07, 0x00, /*      ###         */
+	0x07, 0x00, /*      ###         */
+	0x07, 0x00, /*      ###         */
+	0x07, 0x00, /*      ###         */
+	0xFF, 0xF8, /* #############    */
+	0xFF, 0xF8, /* #############    */
+	0xFF, 0xF8, /* #############    */
+	0x07, 0x00, /*      ###         */
+	0x07, 0x00, /*      ###         */
+	0x07, 0x00, /*      ###         */
+	0x07, 0x00, /*      ###         */
+	0x07, 0x00, /*      ###         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @380 ',' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x70, /*  ###     */
+	0x70, /*  ###     */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0xE0, /* ###      */
+	0xC0, /* ##       */
+	0x00, /*          */
+
+	/* @400 '-' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xFE, /* #######  */
+	0xFE, /* #######  */
+	0xFE, /* #######  */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @420 '.' (4 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @440 '/' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x01, 0xC0, /*        ###       */
+	0x03, 0x80, /*       ###        */
+	0x03, 0x80, /*       ###        */
+	0x03, 0x80, /*       ###        */
+	0x07, 0x00, /*      ###         */
+	0x07, 0x00, /*      ###         */
+	0x0E, 0x00, /*     ###          */
+	0x0E, 0x00, /*     ###          */
+	0x0E, 0x00, /*     ###          */
+	0x1C, 0x00, /*    ###           */
+	0x1C, 0x00, /*    ###           */
+	0x1C, 0x00, /*    ###           */
+	0x38, 0x00, /*   ###            */
+	0x38, 0x00, /*   ###            */
+	0x70, 0x00, /*  ###             */
+	0x70, 0x00, /*  ###             */
+	0x70, 0x00, /*  ###             */
+	0xE0, 0x00, /* ###              */
+	0x00, 0x00, /*                  */
+
+	/* @480 '0' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x1F, 0x80, /*    ######        */
+	0x3F, 0xC0, /*   ########       */
+	0x7F, 0xE0, /*  ##########      */
+	0xF9, 0xF0, /* #####  #####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF9, 0xF0, /* #####  #####     */
+	0x7F, 0xE0, /*  ##########      */
+	0x3F, 0xC0, /*   ########       */
+	0x1F, 0x80, /*    ######        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @520 '1' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x1E, 0x00, /*    ####          */
+	0x1E, 0x00, /*    ####          */
+	0xFE, 0x00, /* #######          */
+	0xFE, 0x00, /* #######          */
+	0xFE, 0x00, /* #######          */
+	0x1E, 0x00, /*    ####          */
+	0x1E, 0x00, /*    ####          */
+	0x1E, 0x00, /*    ####          */
+	0x1E, 0x00, /*    ####          */
+	0x1E, 0x00, /*    ####          */
+	0x1E, 0x00, /*    ####          */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0xC0, /* ##########       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @560 '2' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x7F, 0x00, /*  #######         */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0xC0, /* ##########       */
+	0x87, 0xC0, /* #    #####       */
+	0x03, 0xC0, /*       ####       */
+	0x03, 0xC0, /*       ####       */
+	0x07, 0x80, /*      ####        */
+	0x07, 0x80, /*      ####        */
+	0x0F, 0x00, /*     ####         */
+	0x3E, 0x00, /*   #####          */
+	0x78, 0x00, /*  ####            */
+	0xFF, 0xE0, /* ###########      */
+	0xFF, 0xE0, /* ###########      */
+	0xFF, 0xE0, /* ###########      */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @600 '3' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x7F, 0xC0, /*  #########       */
+	0xFF, 0xE0, /* ###########      */
+	0xFF, 0xF0, /* ############     */
+	0xC0, 0xF0, /* ##      ####     */
+	0x00, 0xF0, /*         ####     */
+	0x0F, 0xE0, /*     #######      */
+	0x0F, 0x80, /*     #####        */
+	0x0F, 0xE0, /*     #######      */
+	0x00, 0xF0, /*         ####     */
+	0x00, 0xF0, /*         ####     */
+	0xC1, 0xF0, /* ##     #####     */
+	0xFF, 0xE0, /* ###########      */
+	0xFF, 0xE0, /* ###########      */
+	0x7F, 0x80, /*  ########        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @640 '4' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x07, 0xC0, /*      #####       */
+	0x07, 0xC0, /*      #####       */
+	0x0F, 0xC0, /*     ######       */
+	0x1F, 0xC0, /*    #######       */
+	0x3B, 0xC0, /*   ### ####       */
+	0x33, 0xC0, /*   ##  ####       */
+	0x63, 0xC0, /*  ##   ####       */
+	0xE3, 0xC0, /* ###   ####       */
+	0xFF, 0xF0, /* ############     */
+	0xFF, 0xF0, /* ############     */
+	0xFF, 0xF0, /* ############     */
+	0x03, 0xC0, /*       ####       */
+	0x03, 0xC0, /*       ####       */
+	0x03, 0xC0, /*       ####       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @680 '5' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x7F, 0xE0, /*  ##########      */
+	0x7F, 0xE0, /*  ##########      */
+	0x7F, 0xE0, /*  ##########      */
+	0x78, 0x00, /*  ####            */
+	0x78, 0x00, /*  ####            */
+	0x7F, 0x80, /*  ########        */
+	0x7F, 0xC0, /*  #########       */
+	0x7F, 0xE0, /*  ##########      */
+	0x01, 0xE0, /*        ####      */
+	0x01, 0xE0, /*        ####      */
+	0xC3, 0xE0, /* ##    #####      */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0xC0, /* ##########       */
+	0x7F, 0x00, /*  #######         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @720 '6' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x07, 0xE0, /*      ######      */
+	0x1F, 0xE0, /*    ########      */
+	0x3F, 0xE0, /*   #########      */
+	0x7C, 0x00, /*  #####           */
+	0xF8, 0x00, /* #####            */
+	0xF7, 0xC0, /* #### #####       */
+	0xFF, 0xE0, /* ###########      */
+	0xFF, 0xF0, /* ############     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF8, 0xF0, /* #####   ####     */
+	0x7F, 0xE0, /*  ##########      */
+	0x3F, 0xE0, /*   #########      */
+	0x1F, 0x80, /*    ######        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @760 '7' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xFF, 0xF0, /* ############     */
+	0xFF, 0xF0, /* ############     */
+	0xFF, 0xF0, /* ############     */
+	0x01, 0xF0, /*        #####     */
+	0x01, 0xE0, /*        ####      */
+	0x03, 0xE0, /*       #####      */
+	0x07, 0xC0, /*      #####       */
+	0x07, 0x80, /*      ####        */
+	0x0F, 0x80, /*     #####        */
+	0x0F, 0x00, /*     ####         */
+	0x1F, 0x00, /*    #####         */
+	0x3E, 0x00, /*   #####          */
+	0x3E, 0x00, /*   #####          */
+	0x7C, 0x00, /*  #####           */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @800 '8' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x1F, 0x80, /*    ######        */
+	0x7F, 0xE0, /*  ##########      */
+	0xFF, 0xF0, /* ############     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0x7F, 0xE0, /*  ##########      */
+	0x3F, 0x80, /*   #######        */
+	0x7F, 0xE0, /*  ##########      */
+	0xF1, 0xF0, /* ####   #####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF8, 0xF0, /* #####   ####     */
+	0xFF, 0xF0, /* ############     */
+	0x7F, 0xE0, /*  ##########      */
+	0x1F, 0x80, /*    ######        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @840 '9' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x1F, 0x80, /*    ######        */
+	0x7F, 0xC0, /*  #########       */
+	0x7F, 0xE0, /*  ##########      */
+	0xF1, 0xF0, /* ####   #####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xFF, 0xF0, /* ############     */
+	0x7F, 0xF0, /*  ###########     */
+	0x3E, 0xF0, /*   ##### ####     */
+	0x01, 0xE0, /*        ####      */
+	0x03, 0xE0, /*       #####      */
+	0x7F, 0xC0, /*  #########       */
+	0x7F, 0x80, /*  ########        */
+	0x7E, 0x00, /*  ######          */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @880 ':' (4 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @900 ';' (5 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+	0x38, /*   ###    */
+	0x70, /*  ###     */
+	0x70, /*  ###     */
+	0x60, /*  ##      */
+	0x60, /*  ##      */
+	0xE0, /* ###      */
+	0xC0, /* ##       */
+	0x00, /*          */
+
+	/* @920 '<' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x10, /*            #     */
+	0x00, 0xF0, /*         ####     */
+	0x03, 0xF0, /*       ######     */
+	0x0F, 0xE0, /*     #######      */
+	0x7F, 0x00, /*  #######         */
+	0xFC, 0x00, /* ######           */
+	0xFC, 0x00, /* ######           */
+	0x7F, 0x00, /*  #######         */
+	0x0F, 0xE0, /*     #######      */
+	0x03, 0xF0, /*       ######     */
+	0x00, 0xF0, /*         ####     */
+	0x00, 0x10, /*            #     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @960 '=' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xFF, 0xF0, /* ############     */
+	0xFF, 0xF0, /* ############     */
+	0xFF, 0xF0, /* ############     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xFF, 0xF0, /* ############     */
+	0xFF, 0xF0, /* ############     */
+	0xFF, 0xF0, /* ############     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1000 '>' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x80, 0x00, /* #                */
+	0xF0, 0x00, /* ####             */
+	0xFC, 0x00, /* ######           */
+	0x7F, 0x00, /*  #######         */
+	0x0F, 0xE0, /*     #######      */
+	0x03, 0xF0, /*       ######     */
+	0x03, 0xF0, /*       ######     */
+	0x0F, 0xE0, /*     #######      */
+	0x7F, 0x00, /*  #######         */
+	0xFC, 0x00, /* ######           */
+	0xF0, 0x00, /* ####             */
+	0x80, 0x00, /* #                */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1040 '?' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x7F, 0x00, /*  #######         */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0xC0, /* ##########       */
+	0x83, 0xC0, /* #     ####       */
+	0x03, 0xC0, /*       ####       */
+	0x03, 0xC0, /*       ####       */
+	0x07, 0x80, /*      ####        */
+	0x1F, 0x00, /*    #####         */
+	0x3C, 0x00, /*   ####           */
+	0x38, 0x00, /*   ###            */
+	0x38, 0x00, /*   ###            */
+	0x00, 0x00, /*                  */
+	0x3C, 0x00, /*   ####           */
+	0x3C, 0x00, /*   ####           */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1080 '@' (16 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x07, 0xE0, /*      ######      */
+	0x1F, 0xF8, /*    ##########    */
+	0x3C, 0x1C, /*   ####     ###   */
+	0x73, 0xFE, /*  ###  #########  */
+	0x67, 0xF6, /*  ##  ####### ##  */
+	0xE6, 0x33, /* ###  ##   ##  ## */
+	0xCC, 0x33, /* ##  ##    ##  ## */
+	0xCC, 0x33, /* ##  ##    ##  ## */
+	0xCC, 0x33, /* ##  ##    ##  ## */
+	0xCC, 0x33, /* ##  ##    ##  ## */
+	0xCE, 0x33, /* ##  ###   ##  ## */
+	0x67, 0xFE, /*  ##  ##########  */
+	0x73, 0xFE, /*  ###  #########  */
+	0x3C, 0x10, /*   ####     #     */
+	0x1F, 0xF0, /*    #########     */
+	0x07, 0xF0, /*      #######     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1120 'A' (15 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x07, 0xC0, /*      #####       */
+	0x07, 0xC0, /*      #####       */
+	0x0F, 0xE0, /*     #######      */
+	0x0F, 0xE0, /*     #######      */
+	0x0F, 0xE0, /*     #######      */
+	0x1E, 0xF0, /*    #### ####     */
+	0x1E, 0xF0, /*    #### ####     */
+	0x3E, 0xF8, /*   ##### #####    */
+	0x3C, 0x78, /*   ####   ####    */
+	0x3F, 0xF8, /*   ###########    */
+	0x7F, 0xFC, /*  #############   */
+	0x7F, 0xFC, /*  #############   */
+	0x78, 0x3C, /*  ####     ####   */
+	0xF0, 0x1E, /* ####       ####  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1160 'B' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xFF, 0x00, /* ########         */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0xC0, /* ##########       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0xE0, /* ###########      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xFF, 0xE0, /* ###########      */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0x80, /* #########        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1200 'C' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x0F, 0xE0, /*     #######      */
+	0x3F, 0xF0, /*   ##########     */
+	0x7F, 0xF0, /*  ###########     */
+	0x7C, 0x30, /*  #####    ##     */
+	0xF8, 0x00, /* #####            */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF8, 0x00, /* #####            */
+	0x7C, 0x30, /*  #####    ##     */
+	0x7F, 0xF0, /*  ###########     */
+	0x3F, 0xF0, /*   ##########     */
+	0x0F, 0xE0, /*     #######      */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1240 'D' (13 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0xE0, /* ###########      */
+	0xFF, 0xF0, /* ############     */
+	0xF1, 0xF0, /* ####   #####     */
+	0xF0, 0xF8, /* ####    #####    */
+	0xF0, 0x78, /* ####     ####    */
+	0xF0, 0x78, /* ####     ####    */
+	0xF0, 0x78, /* ####     ####    */
+	0xF0, 0x78, /* ####     ####    */
+	0xF0, 0xF8, /* ####    #####    */
+	0xF1, 0xF0, /* ####   #####     */
+	0xFF, 0xE0, /* ###########      */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0x80, /* #########        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1280 'E' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0xC0, /* ##########       */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x80, /* #########        */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0xC0, /* ##########       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1320 'F' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x80, /* #########        */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x80, /* #########        */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1360 'G' (13 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x0F, 0xE0, /*     #######      */
+	0x1F, 0xF8, /*    ##########    */
+	0x7F, 0xF8, /*  ############    */
+	0x7C, 0x18, /*  #####     ##    */
+	0xF8, 0x00, /* #####            */
+	0xF0, 0x00, /* ####             */
+	0xF1, 0xF8, /* ####   ######    */
+	0xF1, 0xF8, /* ####   ######    */
+	0xF1, 0xF8, /* ####   ######    */
+	0xF8, 0x78, /* #####    ####    */
+	0x7C, 0x78, /*  #####   ####    */
+	0x7F, 0xF8, /*  ############    */
+	0x3F, 0xF8, /*   ###########    */
+	0x0F, 0xE0, /*     #######      */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1400 'H' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xFF, 0xF0, /* ############     */
+	0xFF, 0xF0, /* ############     */
+	0xFF, 0xF0, /* ############     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1440 'I' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0xFF, /* ######## */
+	0xFF, /* ######## */
+	0xFF, /* ######## */
+	0x3C, /*   ####   */
+	0x3C, /*   ####   */
+	0x3C, /*   ####   */
+	0x3C, /*   ####   */
+	0x3C, /*   ####   */
+	0x3C, /*   ####   */
+	0x3C, /*   ####   */
+	0x3C, /*   ####   */
+	0xFF, /* ######## */
+	0xFF, /* ######## */
+	0xFF, /* ######## */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @1460 'J' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x3F, 0x80, /*   #######        */
+	0x3F, 0x80, /*   #######        */
+	0x3F, 0x80, /*   #######        */
+	0x07, 0x80, /*      ####        */
+	0x07, 0x80, /*      ####        */
+	0x07, 0x80, /*      ####        */
+	0x07, 0x80, /*      ####        */
+	0x07, 0x80, /*      ####        */
+	0x07, 0x80, /*      ####        */
+	0x07, 0x80, /*      ####        */
+	0x0F, 0x80, /*     #####        */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x00, /* ########         */
+	0xFC, 0x00, /* ######           */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1500 'K' (13 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xF0, 0xF8, /* ####    #####    */
+	0xF1, 0xF0, /* ####   #####     */
+	0xF3, 0xE0, /* ####  #####      */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF7, 0x80, /* #### ####        */
+	0xFF, 0x00, /* ########         */
+	0xFF, 0x00, /* ########         */
+	0xFF, 0x00, /* ########         */
+	0xFF, 0x80, /* #########        */
+	0xF7, 0xC0, /* #### #####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF0, 0xF0, /* ####    ####     */
+	0xF0, 0xF8, /* ####    #####    */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1540 'L' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0xC0, /* ##########       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1580 'M' (14 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xF8, 0x7C, /* #####    #####   */
+	0xF8, 0x7C, /* #####    #####   */
+	0xF8, 0x7C, /* #####    #####   */
+	0xFC, 0xFC, /* ######  ######   */
+	0xFC, 0xFC, /* ######  ######   */
+	0xFC, 0xFC, /* ######  ######   */
+	0xF7, 0xBC, /* #### #### ####   */
+	0xF7, 0xBC, /* #### #### ####   */
+	0xF7, 0xBC, /* #### #### ####   */
+	0xF3, 0x3C, /* ####  ##  ####   */
+	0xF3, 0x3C, /* ####  ##  ####   */
+	0xF0, 0x3C, /* ####      ####   */
+	0xF0, 0x3C, /* ####      ####   */
+	0xF0, 0x3C, /* ####      ####   */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1620 'N' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xF8, 0xF0, /* #####   ####     */
+	0xF8, 0xF0, /* #####   ####     */
+	0xFC, 0xF0, /* ######  ####     */
+	0xFC, 0xF0, /* ######  ####     */
+	0xFE, 0xF0, /* ####### ####     */
+	0xFE, 0xF0, /* ####### ####     */
+	0xF6, 0xF0, /* #### ## ####     */
+	0xF7, 0xF0, /* #### #######     */
+	0xF3, 0xF0, /* ####  ######     */
+	0xF3, 0xF0, /* ####  ######     */
+	0xF3, 0xF0, /* ####  ######     */
+	0xF1, 0xF0, /* ####   #####     */
+	0xF1, 0xF0, /* ####   #####     */
+	0xF0, 0xF0, /* ####    ####     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1660 'O' (14 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x0F, 0xC0, /*     ######       */
+	0x3F, 0xF0, /*   ##########     */
+	0x7F, 0xF8, /*  ############    */
+	0x78, 0x78, /*  ####    ####    */
+	0xF8, 0x7C, /* #####    #####   */
+	0xF0, 0x3C, /* ####      ####   */
+	0xF0, 0x3C, /* ####      ####   */
+	0xF0, 0x3C, /* ####      ####   */
+	0xF0, 0x3C, /* ####      ####   */
+	0xF8, 0x7C, /* #####    #####   */
+	0x78, 0x78, /*  ####    ####    */
+	0x7F, 0xF8, /*  ############    */
+	0x3F, 0xF0, /*   ##########     */
+	0x0F, 0xC0, /*     ######       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1700 'P' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0xE0, /* ###########      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0x00, /* ########         */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1740 'Q' (14 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x0F, 0xC0, /*     ######       */
+	0x3F, 0xF0, /*   ##########     */
+	0x7F, 0xF8, /*  ############    */
+	0x78, 0x78, /*  ####    ####    */
+	0xF8, 0x7C, /* #####    #####   */
+	0xF0, 0x3C, /* ####      ####   */
+	0xF0, 0x3C, /* ####      ####   */
+	0xF0, 0x3C, /* ####      ####   */
+	0xF0, 0x3C, /* ####      ####   */
+	0xF8, 0x7C, /* #####    #####   */
+	0x78, 0x78, /*  ####    ####    */
+	0x7F, 0xF8, /*  ############    */
+	0x3F, 0xF0, /*   ##########     */
+	0x0F, 0xC0, /*     ######       */
+	0x03, 0xC0, /*       ####       */
+	0x03, 0xFC, /*       ########   */
+	0x01, 0xFC, /*        #######   */
+	0x00, 0xFC, /*         ######   */
+
+	/* @1780 'R' (13 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0xE0, /* ###########      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xFF, 0xC0, /* ##########       */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x80, /* #########        */
+	0xF7, 0xC0, /* #### #####       */
+	0xF7, 0xC0, /* #### #####       */
+	0xF3, 0xE0, /* ####  #####      */
+	0xF1, 0xF0, /* ####   #####     */
+	0xF0, 0xF8, /* ####    #####    */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1820 'S' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x1F, 0xC0, /*    #######       */
+	0x7F, 0xE0, /*  ##########      */
+	0xFF, 0xE0, /* ###########      */
+	0xF0, 0x60, /* ####     ##      */
+	0xF0, 0x00, /* ####             */
+	0xFF, 0x00, /* ########         */
+	0x7F, 0xC0, /*  #########       */
+	0x3F, 0xE0, /*   #########      */
+	0x07, 0xF0, /*      #######     */
+	0x00, 0xF0, /*         ####     */
+	0xC0, 0xF0, /* ##      ####     */
+	0xFF, 0xE0, /* ###########      */
+	0xFF, 0xE0, /* ###########      */
+	0x7F, 0x80, /*  ########        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1860 'T' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xFF, 0xF0, /* ############     */
+	0xFF, 0xF0, /* ############     */
+	0xFF, 0xF0, /* ############     */
+	0x0F, 0x00, /*     ####         */
+	0x0F, 0x00, /*     ####         */
+	0x0F, 0x00, /*     ####         */
+	0x0F, 0x00, /*     ####         */
+	0x0F, 0x00, /*     ####         */
+	0x0F, 0x00, /*     ####         */
+	0x0F, 0x00, /*     ####         */
+	0x0F, 0x00, /*     ####         */
+	0x0F, 0x00, /*     ####         */
+	0x0F, 0x00, /*     ####         */
+	0x0F, 0x00, /*     ####         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1900 'U' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0x7F, 0xC0, /*  #########       */
+	0x7F, 0xC0, /*  #########       */
+	0x1F, 0x00, /*    #####         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1940 'V' (15 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xF0, 0x1E, /* ####       ####  */
+	0x78, 0x3C, /*  ####     ####   */
+	0x78, 0x3C, /*  ####     ####   */
+	0x7C, 0x7C, /*  #####   #####   */
+	0x3C, 0x78, /*   ####   ####    */
+	0x3C, 0x78, /*   ####   ####    */
+	0x3E, 0xF8, /*   ##### #####    */
+	0x1E, 0xF0, /*    #### ####     */
+	0x1E, 0xF0, /*    #### ####     */
+	0x0F, 0xE0, /*     #######      */
+	0x0F, 0xE0, /*     #######      */
+	0x0F, 0xE0, /*     #######      */
+	0x07, 0xC0, /*      #####       */
+	0x07, 0xC0, /*      #####       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @1980 'W' (19 pixels wide) */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+	0xF0, 0xE1, 0xE0, /* ####    ###    ####      */
+	0xF0, 0xE1, 0xE0, /* ####    ###    ####      */
+	0x79, 0xF3, 0xC0, /*  ####  #####  ####       */
+	0x79, 0xF3, 0xC0, /*  ####  #####  ####       */
+	0x79, 0xF3, 0xC0, /*  ####  #####  ####       */
+	0x79, 0xB3, 0xC0, /*  ####  ## ##  ####       */
+	0x39, 0xB7, 0x80, /*   ###  ## ## ####        */
+	0x3D, 0xB7, 0x80, /*   #### ## ## ####        */
+	0x3F, 0xBF, 0x80, /*   ####### #######        */
+	0x3F, 0xBF, 0x80, /*   ####### #######        */
+	0x1F, 0x3F, 0x00, /*    #####  ######         */
+	0x1F, 0x1F, 0x00, /*    #####   #####         */
+	0x1F, 0x1F, 0x00, /*    #####   #####         */
+	0x1F, 0x1F, 0x00, /*    #####   #####         */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+
+	/* @2040 'X' (15 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xF8, 0x3E, /* #####     #####  */
+	0x7C, 0x7C, /*  #####   #####   */
+	0x3E, 0xF8, /*   ##### #####    */
+	0x3E, 0xF8, /*   ##### #####    */
+	0x1F, 0xF0, /*    #########     */
+	0x0F, 0xE0, /*     #######      */
+	0x07, 0xC0, /*      #####       */
+	0x0F, 0xE0, /*     #######      */
+	0x0F, 0xE0, /*     #######      */
+	0x1F, 0xF0, /*    #########     */
+	0x3E, 0xF8, /*   ##### #####    */
+	0x3E, 0xF8, /*   ##### #####    */
+	0x7C, 0x7C, /*  #####   #####   */
+	0xF8, 0x3E, /* #####     #####  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2080 'Y' (14 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xF8, 0x7C, /* #####    #####   */
+	0x78, 0x78, /*  ####    ####    */
+	0x7C, 0xF8, /*  #####  #####    */
+	0x3C, 0xF0, /*   ####  ####     */
+	0x1F, 0xE0, /*    ########      */
+	0x1F, 0xE0, /*    ########      */
+	0x0F, 0xC0, /*     ######       */
+	0x0F, 0xC0, /*     ######       */
+	0x07, 0x80, /*      ####        */
+	0x07, 0x80, /*      ####        */
+	0x07, 0x80, /*      ####        */
+	0x07, 0x80, /*      ####        */
+	0x07, 0x80, /*      ####        */
+	0x07, 0x80, /*      ####        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2120 'Z' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xFF, 0xE0, /* ###########      */
+	0xFF, 0xE0, /* ###########      */
+	0xFF, 0xE0, /* ###########      */
+	0x03, 0xE0, /*       #####      */
+	0x07, 0xC0, /*      #####       */
+	0x0F, 0x80, /*     #####        */
+	0x1F, 0x00, /*    #####         */
+	0x1F, 0x00, /*    #####         */
+	0x3E, 0x00, /*   #####          */
+	0x7C, 0x00, /*  #####           */
+	0xF8, 0x00, /* #####            */
+	0xFF, 0xE0, /* ###########      */
+	0xFF, 0xE0, /* ###########      */
+	0xFF, 0xE0, /* ###########      */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2160 '[' (6 pixels wide) */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0xFC, /* ######   */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xFC, /* ######   */
+	0xFC, /* ######   */
+
+	/* @2180 '\' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xE0, 0x00, /* ###              */
+	0x70, 0x00, /*  ###             */
+	0x70, 0x00, /*  ###             */
+	0x70, 0x00, /*  ###             */
+	0x38, 0x00, /*   ###            */
+	0x38, 0x00, /*   ###            */
+	0x1C, 0x00, /*    ###           */
+	0x1C, 0x00, /*    ###           */
+	0x1C, 0x00, /*    ###           */
+	0x0E, 0x00, /*     ###          */
+	0x0E, 0x00, /*     ###          */
+	0x0E, 0x00, /*     ###          */
+	0x07, 0x00, /*      ###         */
+	0x07, 0x00, /*      ###         */
+	0x03, 0x80, /*       ###        */
+	0x03, 0x80, /*       ###        */
+	0x03, 0x80, /*       ###        */
+	0x01, 0xC0, /*        ###       */
+	0x00, 0x00, /*                  */
+
+	/* @2220 ']' (6 pixels wide) */
+	0x00, /*          */
+	0xFC, /* ######   */
+	0xFC, /* ######   */
+	0x1C, /*    ###   */
+	0x1C, /*    ###   */
+	0x1C, /*    ###   */
+	0x1C, /*    ###   */
+	0x1C, /*    ###   */
+	0x1C, /*    ###   */
+	0x1C, /*    ###   */
+	0x1C, /*    ###   */
+	0x1C, /*    ###   */
+	0x1C, /*    ###   */
+	0x1C, /*    ###   */
+	0x1C, /*    ###   */
+	0x1C, /*    ###   */
+	0x1C, /*    ###   */
+	0x1C, /*    ###   */
+	0xFC, /* ######   */
+	0xFC, /* ######   */
+
+	/* @2240 '^' (13 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x07, 0x00, /*      ###         */
+	0x0F, 0x80, /*     #####        */
+	0x0F, 0x80, /*     #####        */
+	0x1D, 0xC0, /*    ### ###       */
+	0x38, 0xE0, /*   ###   ###      */
+	0x38, 0xE0, /*   ###   ###      */
+	0x70, 0x70, /*  ###     ###     */
+	0xE0, 0x38, /* ###       ###    */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2280 '_' (14 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xFF, 0xFC, /* ##############   */
+	0xFF, 0xFC, /* ##############   */
+	0x00, 0x00, /*                  */
+
+	/* @2320 '`' (6 pixels wide) */
+	0xF0, /* ####     */
+	0x70, /*  ###     */
+	0x38, /*   ###    */
+	0x1C, /*    ###   */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @2340 'a' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x7F, 0x00, /*  #######         */
+	0x7F, 0x80, /*  ########        */
+	0x43, 0xC0, /*  #    ####       */
+	0x03, 0xC0, /*       ####       */
+	0x3F, 0xC0, /*   ########       */
+	0x7F, 0xC0, /*  #########       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xFF, 0xC0, /* ##########       */
+	0x7B, 0xC0, /*  #### ####       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2380 'b' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF7, 0x00, /* #### ###         */
+	0xFF, 0x80, /* #########        */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF7, 0x80, /* #### ####        */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x00, /* ########         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2420 'c' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x1F, 0x00, /*    #####         */
+	0x7F, 0x80, /*  ########        */
+	0x79, 0x80, /*  ####  ##        */
+	0xF0, 0x80, /* ####    #        */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x80, /* ####    #        */
+	0x78, 0x80, /*  ####   #        */
+	0x7F, 0x80, /*  ########        */
+	0x1F, 0x00, /*    #####         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2460 'd' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xC0, /*       ####       */
+	0x03, 0xC0, /*       ####       */
+	0x03, 0xC0, /*       ####       */
+	0x03, 0xC0, /*       ####       */
+	0x3F, 0xC0, /*   ########       */
+	0x7F, 0xC0, /*  #########       */
+	0x7B, 0xC0, /*  #### ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0x7F, 0xC0, /*  #########       */
+	0x3B, 0xC0, /*   ### ####       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2500 'e' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x1F, 0x80, /*    ######        */
+	0x3F, 0xC0, /*   ########       */
+	0x71, 0xE0, /*  ###   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xFF, 0xE0, /* ###########      */
+	0xFF, 0xE0, /* ###########      */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x20, /* ####      #      */
+	0x78, 0x60, /*  ####    ##      */
+	0x3F, 0xE0, /*   #########      */
+	0x1F, 0xC0, /*    #######       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2540 'f' (7 pixels wide) */
+	0x00, /*          */
+	0x3E, /*   #####  */
+	0x7E, /*  ######  */
+	0x78, /*  ####    */
+	0x78, /*  ####    */
+	0xFE, /* #######  */
+	0xFE, /* #######  */
+	0x78, /*  ####    */
+	0x78, /*  ####    */
+	0x78, /*  ####    */
+	0x78, /*  ####    */
+	0x78, /*  ####    */
+	0x78, /*  ####    */
+	0x78, /*  ####    */
+	0x78, /*  ####    */
+	0x78, /*  ####    */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @2560 'g' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x3F, 0xC0, /*   ########       */
+	0x7F, 0xC0, /*  #########       */
+	0x7B, 0xC0, /*  #### ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0x7F, 0xC0, /*  #########       */
+	0x3B, 0xC0, /*   ### ####       */
+	0x03, 0xC0, /*       ####       */
+	0x47, 0xC0, /*  #   #####       */
+	0x7F, 0x80, /*  ########        */
+	0x7F, 0x00, /*  #######         */
+
+	/* @2600 'h' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF7, 0x80, /* #### ####        */
+	0xFF, 0xC0, /* ##########       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2640 'i' (4 pixels wide) */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @2660 'j' (7 pixels wide) */
+	0x00, /*          */
+	0x1E, /*    ####  */
+	0x1E, /*    ####  */
+	0x1E, /*    ####  */
+	0x00, /*          */
+	0x7E, /*  ######  */
+	0x7E, /*  ######  */
+	0x1E, /*    ####  */
+	0x1E, /*    ####  */
+	0x1E, /*    ####  */
+	0x1E, /*    ####  */
+	0x1E, /*    ####  */
+	0x1E, /*    ####  */
+	0x1E, /*    ####  */
+	0x1E, /*    ####  */
+	0x1E, /*    ####  */
+	0x1E, /*    ####  */
+	0x1E, /*    ####  */
+	0xFC, /* ######   */
+	0xF8, /* #####    */
+
+	/* @2680 'k' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF3, 0xE0, /* ####  #####      */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF7, 0x80, /* #### ####        */
+	0xFF, 0x00, /* ########         */
+	0xFE, 0x00, /* #######          */
+	0xFE, 0x00, /* #######          */
+	0xFF, 0x00, /* ########         */
+	0xF7, 0x00, /* #### ###         */
+	0xF7, 0x80, /* #### ####        */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xE0, /* ####  #####      */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2720 'l' (4 pixels wide) */
+	0x00, /*          */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @2740 'm' (16 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xF7, 0x1C, /* #### ###   ###   */
+	0xFF, 0xBE, /* ######### #####  */
+	0xF3, 0xCF, /* ####  ####  #### */
+	0xF3, 0xCF, /* ####  ####  #### */
+	0xF3, 0xCF, /* ####  ####  #### */
+	0xF3, 0xCF, /* ####  ####  #### */
+	0xF3, 0xCF, /* ####  ####  #### */
+	0xF3, 0xCF, /* ####  ####  #### */
+	0xF3, 0xCF, /* ####  ####  #### */
+	0xF3, 0xCF, /* ####  ####  #### */
+	0xF3, 0xCF, /* ####  ####  #### */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2780 'n' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xF7, 0x80, /* #### ####        */
+	0xFF, 0xC0, /* ##########       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2820 'o' (11 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x1F, 0x00, /*    #####         */
+	0x7F, 0xC0, /*  #########       */
+	0x7B, 0xC0, /*  #### ####       */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0xF1, 0xE0, /* ####   ####      */
+	0x7B, 0xC0, /*  #### ####       */
+	0x7F, 0xC0, /*  #########       */
+	0x1F, 0x00, /*    #####         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @2860 'p' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xF7, 0x00, /* #### ###         */
+	0xFF, 0x80, /* #########        */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF7, 0x80, /* #### ####        */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x00, /* ########         */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+	0xF0, 0x00, /* ####             */
+
+	/* @2900 'q' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x3F, 0xC0, /*   ########       */
+	0x7F, 0xC0, /*  #########       */
+	0x7B, 0xC0, /*  #### ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0x7F, 0xC0, /*  #########       */
+	0x3B, 0xC0, /*   ### ####       */
+	0x03, 0xC0, /*       ####       */
+	0x03, 0xC0, /*       ####       */
+	0x03, 0xC0, /*       ####       */
+	0x03, 0xC0, /*       ####       */
+
+	/* @2940 'r' (7 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0xF6, /* #### ##  */
+	0xFE, /* #######  */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0xF0, /* ####     */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @2960 's' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x3F, 0x80, /*   #######        */
+	0x7F, 0x80, /*  ########        */
+	0xF0, 0x80, /* ####    #        */
+	0xF0, 0x00, /* ####             */
+	0xFE, 0x00, /* #######          */
+	0x7F, 0x00, /*  #######         */
+	0x3F, 0x80, /*   #######        */
+	0x87, 0x80, /* #    ####        */
+	0xC7, 0x80, /* ##   ####        */
+	0xFF, 0x00, /* ########         */
+	0x7E, 0x00, /*  ######          */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @3000 't' (8 pixels wide) */
+	0x00, /*          */
+	0x00, /*          */
+	0x78, /*  ####    */
+	0x78, /*  ####    */
+	0x78, /*  ####    */
+	0xFF, /* ######## */
+	0xFF, /* ######## */
+	0x78, /*  ####    */
+	0x78, /*  ####    */
+	0x78, /*  ####    */
+	0x78, /*  ####    */
+	0x78, /*  ####    */
+	0x78, /*  ####    */
+	0x78, /*  ####    */
+	0x7F, /*  ####### */
+	0x1F, /*    ##### */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+	0x00, /*          */
+
+	/* @3020 'u' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xF3, 0xC0, /* ####  ####       */
+	0xFF, 0xC0, /* ##########       */
+	0x7B, 0xC0, /*  #### ####       */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @3060 'v' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xF0, 0xF0, /* ####    ####     */
+	0x79, 0xE0, /*  ####  ####      */
+	0x79, 0xE0, /*  ####  ####      */
+	0x79, 0xE0, /*  ####  ####      */
+	0x3F, 0xC0, /*   ########       */
+	0x3F, 0xC0, /*   ########       */
+	0x3F, 0xC0, /*   ########       */
+	0x1F, 0x80, /*    ######        */
+	0x1F, 0x80, /*    ######        */
+	0x0F, 0x00, /*     ####         */
+	0x0F, 0x00, /*     ####         */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @3100 'w' (19 pixels wide) */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+	0xF0, 0xE1, 0xE0, /* ####    ###    ####      */
+	0xF8, 0xF3, 0xE0, /* #####   ####  #####      */
+	0x79, 0xF3, 0xC0, /*  ####  #####  ####       */
+	0x79, 0xF3, 0xC0, /*  ####  #####  ####       */
+	0x79, 0xB3, 0xC0, /*  ####  ## ##  ####       */
+	0x3D, 0xB7, 0x80, /*   #### ## ## ####        */
+	0x3F, 0xBF, 0x80, /*   ####### #######        */
+	0x3F, 0xBF, 0x80, /*   ####### #######        */
+	0x1F, 0x1F, 0x00, /*    #####   #####         */
+	0x1F, 0x1F, 0x00, /*    #####   #####         */
+	0x1F, 0x1F, 0x00, /*    #####   #####         */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+	0x00, 0x00, 0x00, /*                          */
+
+	/* @3160 'x' (13 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xF8, 0xF8, /* #####   #####    */
+	0x78, 0xF0, /*  ####   ####     */
+	0x3D, 0xE0, /*   #### ####      */
+	0x1F, 0xC0, /*    #######       */
+	0x1F, 0xC0, /*    #######       */
+	0x0F, 0x80, /*     #####        */
+	0x1F, 0xC0, /*    #######       */
+	0x1F, 0xC0, /*    #######       */
+	0x3D, 0xE0, /*   #### ####      */
+	0x78, 0xF0, /*  ####   ####     */
+	0xF8, 0xF8, /* #####   #####    */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @3200 'y' (12 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xF0, 0xF0, /* ####    ####     */
+	0x70, 0xE0, /*  ###    ###      */
+	0x79, 0xE0, /*  ####  ####      */
+	0x79, 0xE0, /*  ####  ####      */
+	0x39, 0xC0, /*   ###  ###       */
+	0x3F, 0xC0, /*   ########       */
+	0x3F, 0x80, /*   #######        */
+	0x1F, 0x80, /*    ######        */
+	0x1F, 0x80, /*    ######        */
+	0x0F, 0x00, /*     ####         */
+	0x0F, 0x00, /*     ####         */
+	0x0E, 0x00, /*     ###          */
+	0x1E, 0x00, /*    ####          */
+	0x1E, 0x00, /*    ####          */
+	0x3C, 0x00, /*   ####           */
+
+	/* @3240 'z' (9 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x80, /* #########        */
+	0x07, 0x00, /*      ###         */
+	0x0F, 0x00, /*     ####         */
+	0x1E, 0x00, /*    ####          */
+	0x1C, 0x00, /*    ###           */
+	0x3C, 0x00, /*   ####           */
+	0x78, 0x00, /*  ####            */
+	0x70, 0x00, /*  ###             */
+	0xFF, 0x80, /* #########        */
+	0xFF, 0x80, /* #########        */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+
+	/* @3280 '{' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x03, 0xC0, /*       ####       */
+	0x07, 0xC0, /*      #####       */
+	0x0E, 0x00, /*     ###          */
+	0x0E, 0x00, /*     ###          */
+	0x0E, 0x00, /*     ###          */
+	0x0E, 0x00, /*     ###          */
+	0x0E, 0x00, /*     ###          */
+	0x1C, 0x00, /*    ###           */
+	0xF8, 0x00, /* #####            */
+	0xF8, 0x00, /* #####            */
+	0x1C, 0x00, /*    ###           */
+	0x0E, 0x00, /*     ###          */
+	0x0E, 0x00, /*     ###          */
+	0x0E, 0x00, /*     ###          */
+	0x0E, 0x00, /*     ###          */
+	0x0E, 0x00, /*     ###          */
+	0x0F, 0x00, /*     ####         */
+	0x07, 0xC0, /*      #####       */
+	0x03, 0xC0, /*       ####       */
+
+	/* @3320 '|' (3 pixels wide) */
+	0x00, /*          */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+	0xE0, /* ###      */
+
+	/* @3340 '}' (10 pixels wide) */
+	0x00, 0x00, /*                  */
+	0xF0, 0x00, /* ####             */
+	0xF8, 0x00, /* #####            */
+	0x1C, 0x00, /*    ###           */
+	0x1C, 0x00, /*    ###           */
+	0x1C, 0x00, /*    ###           */
+	0x1C, 0x00, /*    ###           */
+	0x1C, 0x00, /*    ###           */
+	0x0E, 0x00, /*     ###          */
+	0x07, 0xC0, /*      #####       */
+	0x07, 0xC0, /*      #####       */
+	0x0E, 0x00, /*     ###          */
+	0x1C, 0x00, /*    ###           */
+	0x1C, 0x00, /*    ###           */
+	0x1C, 0x00, /*    ###           */
+	0x1C, 0x00, /*    ###           */
+	0x1C, 0x00, /*    ###           */
+	0x3C, 0x00, /*   ####           */
+	0xF8, 0x00, /* #####            */
+	0xF0, 0x00, /* ####             */
+
+	/* @3380 '~' (14 pixels wide) */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x3C, 0x1C, /*   ####     ###   */
+	0x7F, 0x1C, /*  #######   ###   */
+	0x7F, 0x9C, /*  ########  ###   */
+	0xE7, 0xF8, /* ###  ########    */
+	0xE3, 0xF8, /* ###   #######    */
+	0xE0, 0xF0, /* ###     ####     */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+	0x00, 0x00, /*                  */
+};
+
+/* Character descriptors for Verdana 14pt */
+/* { [Char width in bits], [Offset into verdanabold14ptCharBitmaps in bytes] } */
+const FONT_CHAR_INFO verdanabold14ptDescriptors[] = 
+{
+	{4, 0}, 		/*   */ 
+	{4, 20}, 		/* ! */ 
+	{8, 40}, 		/* " */ 
+	{14, 60}, 		/* # */ 
+	{12, 100}, 		/* $ */ 
+	{22, 140}, 		/* % */ 
+	{15, 200}, 		/* & */ 
+	{3, 240}, 		/* ' */ 
+	{7, 260}, 		/* ( */ 
+	{7, 280}, 		/* ) */ 
+	{10, 300}, 		/* * */ 
+	{13, 340}, 		/* + */ 
+	{5, 380}, 		/* , */ 
+	{7, 400}, 		/* - */ 
+	{4, 420}, 		/* . */ 
+	{10, 440}, 		/* / */ 
+	{12, 480}, 		/* 0 */ 
+	{10, 520}, 		/* 1 */ 
+	{11, 560}, 		/* 2 */ 
+	{12, 600}, 		/* 3 */ 
+	{12, 640}, 		/* 4 */ 
+	{11, 680}, 		/* 5 */ 
+	{12, 720}, 		/* 6 */ 
+	{12, 760}, 		/* 7 */ 
+	{12, 800}, 		/* 8 */ 
+	{12, 840}, 		/* 9 */ 
+	{4, 880}, 		/* : */ 
+	{5, 900}, 		/* ; */ 
+	{12, 920}, 		/* < */ 
+	{12, 960}, 		/* = */ 
+	{12, 1000}, 		/* > */ 
+	{10, 1040}, 		/* ? */ 
+	{16, 1080}, 		/* @ */ 
+	{15, 1120}, 		/* A */ 
+	{11, 1160}, 		/* B */ 
+	{12, 1200}, 		/* C */ 
+	{13, 1240}, 		/* D */ 
+	{10, 1280}, 		/* E */ 
+	{9, 1320}, 		/* F */ 
+	{13, 1360}, 		/* G */ 
+	{12, 1400}, 		/* H */ 
+	{8, 1440}, 		/* I */ 
+	{9, 1460}, 		/* J */ 
+	{13, 1500}, 		/* K */ 
+	{10, 1540}, 		/* L */ 
+	{14, 1580}, 		/* M */ 
+	{12, 1620}, 		/* N */ 
+	{14, 1660}, 		/* O */ 
+	{11, 1700}, 		/* P */ 
+	{14, 1740}, 		/* Q */ 
+	{13, 1780}, 		/* R */ 
+	{12, 1820}, 		/* S */ 
+	{12, 1860}, 		/* T */ 
+	{11, 1900}, 		/* U */ 
+	{15, 1940}, 		/* V */ 
+	{19, 1980}, 		/* W */ 
+	{15, 2040}, 		/* X */ 
+	{14, 2080}, 		/* Y */ 
+	{11, 2120}, 		/* Z */ 
+	{6, 2160}, 		/* [ */ 
+	{10, 2180}, 		/* \ */ 
+	{6, 2220}, 		/* ] */ 
+	{13, 2240}, 		/* ^ */ 
+	{14, 2280}, 		/* _ */ 
+	{6, 2320}, 		/* ` */ 
+	{10, 2340}, 		/* a */ 
+	{10, 2380}, 		/* b */ 
+	{9, 2420}, 		/* c */ 
+	{10, 2460}, 		/* d */ 
+	{11, 2500}, 		/* e */ 
+	{7, 2540}, 		/* f */ 
+	{10, 2560}, 		/* g */ 
+	{10, 2600}, 		/* h */ 
+	{4, 2640}, 		/* i */ 
+	{7, 2660}, 		/* j */ 
+	{11, 2680}, 		/* k */ 
+	{4, 2720}, 		/* l */ 
+	{16, 2740}, 		/* m */ 
+	{10, 2780}, 		/* n */ 
+	{11, 2820}, 		/* o */ 
+	{10, 2860}, 		/* p */ 
+	{10, 2900}, 		/* q */ 
+	{7, 2940}, 		/* r */ 
+	{9, 2960}, 		/* s */ 
+	{8, 3000}, 		/* t */ 
+	{10, 3020}, 		/* u */ 
+	{12, 3060}, 		/* v */ 
+	{19, 3100}, 		/* w */ 
+	{13, 3160}, 		/* x */ 
+	{12, 3200}, 		/* y */ 
+	{9, 3240}, 		/* z */ 
+	{10, 3280}, 		/* { */ 
+	{3, 3320}, 		/* | */ 
+	{10, 3340}, 		/* } */ 
+	{14, 3380}, 		/* ~ */ 
+};
+
+/* Font information for Verdana Bold 14pt */
+const FONT_INFO verdanabold14ptFontInfo =
+{
+	20, /*  Character height */
+	' ', /*  Start character */
+	'~', /*  End character */
+	verdanabold14ptDescriptors, /*  Character descriptor array */
+	verdanabold14ptBitmaps, /*  Character bitmap array */
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/fonts/verdanabold14.h b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/verdanabold14.h
new file mode 100644
index 0000000000000000000000000000000000000000..6b674f006c929938f5f60f0051f1cfe1e3432f90
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/fonts/verdanabold14.h
@@ -0,0 +1,19 @@
+#ifndef __VERDANA_BOLD_14__
+#define __VERDANA_BOLD_14__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../fonts.h"
+
+/* Font data for Verdana Bold 14pt */
+extern const uint8_t verdanabold14ptBitmaps[];
+extern const FONT_INFO verdanabold14ptFontInfo;
+extern const FONT_CHAR_INFO verdanabold14ptDescriptors[];
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/hw/hx8340b.c b/reform2-lpc-fw/src/drivers/displays/graphic/hw/hx8340b.c
new file mode 100644
index 0000000000000000000000000000000000000000..5da48013b59841be023a1780b15539deabe6837c
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/hw/hx8340b.c
@@ -0,0 +1,456 @@
+/**************************************************************************/
+/*!
+    @file     hx8340b.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section  DESCRIPTION
+
+    Driver for HX8340B 176x220 pixel TFT LCD displays.
+
+    This driver uses a bit-banged SPI interface and a 16-bit RGB565
+    colour palette.
+
+    @section  LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012 Kevin Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "hx8340b.h"
+#include "core/delay/delay.h"
+#include "core/gpio/gpio.h"
+
+static lcdOrientation_t lcdOrientation = LCD_ORIENTATION_PORTRAIT;
+static lcdProperties_t hx8340bProperties = { 176, 220, false, false, false, true, true };
+
+/*************************************************/
+/* Private Methods                               */
+/*************************************************/
+
+/*************************************************/
+void hx8340bWriteCmd(uint8_t command)
+{
+  CLR_CS;
+
+  CLR_SDI;
+  CLR_SCL;
+  SET_SCL;
+
+  uint8_t i = 0;
+  for (i=0; i<8; i++)
+  {
+    if (command & 0x80)
+    {
+      SET_SDI;
+    }
+    else
+    {
+      CLR_SDI;
+    }
+    CLR_SCL;
+    __NOP();
+    __NOP();
+    __NOP();
+    command <<= 1;
+    SET_SCL;
+  }
+  SET_CS;
+}
+
+/*************************************************/
+void hx8340bWriteData(uint8_t data)
+{
+  CLR_CS;
+
+  SET_SDI;
+  CLR_SCL;
+  SET_SCL;
+
+  uint8_t i = 0;
+  for (i=0; i<8; i++)
+  {
+    if (data & 0x80)
+    {
+      SET_SDI;
+    }
+    else
+    {
+      CLR_SDI;
+    }
+    CLR_SCL;
+    __NOP();
+    __NOP();
+    __NOP();
+    data <<= 1;
+    SET_SCL;
+  }
+  SET_CS;
+}
+
+/*************************************************/
+void hx8340bWriteData16(uint16_t data)
+{
+  hx8340bWriteData((data>>8) & 0xFF);
+  hx8340bWriteData(data & 0xFF);
+}
+
+/*************************************************/
+void hx8340bWriteRegister(uint8_t reg, uint8_t value)
+{
+  hx8340bWriteCmd(reg);
+  hx8340bWriteCmd(value);
+}
+
+/*************************************************/
+void hx8340bInitDisplay(void)
+{
+  hx8340bWriteCmd(HX8340B_N_SETEXTCMD);
+  hx8340bWriteData(0xFF);
+  hx8340bWriteData(0x83);
+  hx8340bWriteData(0x40);
+
+  hx8340bWriteCmd(HX8340B_N_SPLOUT);
+  delay(100);
+
+  hx8340bWriteCmd(0xCA);                  // Undocumented register?
+  hx8340bWriteData(0x70);
+  hx8340bWriteData(0x00);
+  hx8340bWriteData(0xD9);
+  hx8340bWriteData(0x01);
+  hx8340bWriteData(0x11);
+
+  hx8340bWriteCmd(0xC9);                  // Undocumented register?
+  hx8340bWriteData(0x90);
+  hx8340bWriteData(0x49);
+  hx8340bWriteData(0x10);
+  hx8340bWriteData(0x28);
+  hx8340bWriteData(0x28);
+  hx8340bWriteData(0x10);
+  hx8340bWriteData(0x00);
+  hx8340bWriteData(0x06);
+  delay(20);
+
+  hx8340bWriteCmd(HX8340B_N_SETGAMMAP);
+  hx8340bWriteData(0x60);
+  hx8340bWriteData(0x71);
+  hx8340bWriteData(0x01);
+  hx8340bWriteData(0x0E);
+  hx8340bWriteData(0x05);
+  hx8340bWriteData(0x02);
+  hx8340bWriteData(0x09);
+  hx8340bWriteData(0x31);
+  hx8340bWriteData(0x0A);
+
+  hx8340bWriteCmd(HX8340B_N_SETGAMMAN);
+  hx8340bWriteData(0x67);
+  hx8340bWriteData(0x30);
+  hx8340bWriteData(0x61);
+  hx8340bWriteData(0x17);
+  hx8340bWriteData(0x48);
+  hx8340bWriteData(0x07);
+  hx8340bWriteData(0x05);
+  hx8340bWriteData(0x33);
+  delay(10);
+
+  hx8340bWriteCmd(HX8340B_N_SETPWCTR5);
+  hx8340bWriteData(0x35);
+  hx8340bWriteData(0x20);
+  hx8340bWriteData(0x45);
+
+  hx8340bWriteCmd(HX8340B_N_SETPWCTR4);
+  hx8340bWriteData(0x33);
+  hx8340bWriteData(0x25);
+  hx8340bWriteData(0x4c);
+  delay(10);
+
+  hx8340bWriteCmd(HX8340B_N_COLMOD);      // Color Mode
+  hx8340bWriteData(0x05);                 // 0x05 = 16bpp, 0x06 = 18bpp
+
+  hx8340bWriteCmd(HX8340B_N_DISPON);
+  delay(10);
+
+  hx8340bWriteCmd(HX8340B_N_CASET);
+  hx8340bWriteData(0x00);
+  hx8340bWriteData(0x00);
+  hx8340bWriteData(0x00);
+  hx8340bWriteData(0xaf);                 // 175
+
+  hx8340bWriteCmd(HX8340B_N_PASET);
+  hx8340bWriteData(0x00);
+  hx8340bWriteData(0x00);
+  hx8340bWriteData(0x00);
+  hx8340bWriteData(0xdb);                // 219
+
+  hx8340bWriteCmd(HX8340B_N_RAMWR);
+}
+
+/*************************************************/
+void hx8340bHome(void)
+{
+   hx8340bWriteCmd(HX8340B_N_CASET);
+   hx8340bWriteData(0x00);
+   hx8340bWriteData(0x00);
+   hx8340bWriteData(0x00);
+   hx8340bWriteData(0xaf);
+   hx8340bWriteCmd(HX8340B_N_PASET);
+   hx8340bWriteData(0x00);
+   hx8340bWriteData(0x00);
+   hx8340bWriteData(0x00);
+   hx8340bWriteData(0xdb);
+}
+
+/*************************************************/
+static inline void hx8340bSetPosition(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1)
+{
+  hx8340bWriteCmd(HX8340B_N_CASET);
+  hx8340bWriteData(x0>>8);
+  hx8340bWriteData(x0);
+  hx8340bWriteData(x1>>8);
+  hx8340bWriteData(x1);
+
+  hx8340bWriteCmd(HX8340B_N_PASET);
+  hx8340bWriteData(y0>>8);
+  hx8340bWriteData(y0);
+  hx8340bWriteData(y1>>8);
+  hx8340bWriteData(y1);
+
+  hx8340bWriteCmd(HX8340B_N_RAMWR);
+}
+
+/*************************************************/
+/* Public Methods                                */
+/*************************************************/
+
+/*************************************************/
+void lcdInit(void)
+{
+  // Set control pins to output
+  LPC_GPIO->DIR[HX8340B_PORT] |=  (1 << HX8340B_SDI_PIN);
+  LPC_GPIO->DIR[HX8340B_PORT] |=  (1 << HX8340B_SCL_PIN);
+  LPC_GPIO->DIR[HX8340B_PORT] |=  (1 << HX8340B_CS_PIN);
+  LPC_GPIO->DIR[HX8340B_PORT] |=  (1 << HX8340B_BL_PIN);
+  #ifdef HX8340B_USERESET
+  LPC_GPIO->DIR[HX8340B_PORT] |=  (1 << HX8340B_RES_PIN);
+  #endif
+
+  // Set pins low by default (except reset)
+  CLR_SDI;
+  CLR_SCL;
+  CLR_CS;
+  CLR_BL;
+  #ifdef HX8340B_USERESET
+    SET_RES;
+  #endif
+
+  // Turn backlight on
+  lcdBacklight(TRUE);
+
+  // Reset display
+  #ifdef HX8340B_USERESET
+    SET_RES;
+    delay(100);
+    CLR_RES;
+    delay(50);
+    SET_RES;
+    delay(50);
+  #endif
+
+  // Run LCD init sequence
+  hx8340bInitDisplay();
+
+  // Fill black
+  lcdFillRGB(COLOR_BLACK);
+}
+
+/*************************************************/
+void lcdBacklight(bool state)
+{
+  // Set the backlight
+  // Note: Depending on the type of transistor used
+  // to control the backlight, you made need to invert
+  // the values below
+  if (state)
+    // CLR_BL;
+    SET_BL;
+  else
+    // SET_BL;
+    CLR_BL;
+}
+
+/*************************************************/
+void lcdTest(void)
+{
+  lcdFillRGB(COLOR_GREEN);
+}
+
+/*************************************************/
+void lcdFillRGB(uint16_t color)
+{
+  uint8_t i,j;
+  for (i=0;i<220;i++)
+  {
+    for (j=0;j<176;j++)
+    {
+      hx8340bWriteData16(color);
+    }
+  }
+}
+
+/*************************************************/
+void lcdDrawPixel(uint16_t x, uint16_t y, uint16_t color)
+{
+  hx8340bSetPosition(x, y, x+1, y+1);
+  hx8340bWriteData16(color);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws an array of consecutive RGB565 pixels (much
+            faster than addressing each pixel individually)
+*/
+/**************************************************************************/
+void lcdDrawPixels(uint16_t x, uint16_t y, uint16_t *data, uint32_t len)
+{
+  // ToDo: Optimise this function ... currently only a placeholder
+  uint32_t i = 0;
+  do
+  {
+    lcdDrawPixel(x+i, y, data[i]);
+    i++;
+  } while (i<len);
+}
+
+/*************************************************/
+void lcdDrawHLine(uint16_t x0, uint16_t x1, uint16_t y, uint16_t color)
+{
+  // Allows for slightly better performance than setting individual pixels
+  uint16_t x, pixels;
+
+  if (x1 < x0)
+  {
+    // Switch x1 and x0
+    x = x1;
+    x1 = x0;
+    x0 = x;
+  }
+
+  // Check limits
+  if (x1 >= lcdGetWidth())
+  {
+    x1 = lcdGetWidth() - 1;
+  }
+  if (x0 >= lcdGetWidth())
+  {
+    x0 = lcdGetWidth() - 1;
+  }
+
+  hx8340bSetPosition(x0, y, x1, y+1);
+  for (pixels = 0; pixels < x1 - x0 + 1; pixels++)
+  {
+    hx8340bWriteData16(color);
+  }
+}
+
+/*************************************************/
+void lcdDrawVLine(uint16_t x, uint16_t y0, uint16_t y1, uint16_t color)
+{
+  // Allows for slightly better performance than setting individual pixels
+  uint16_t y, pixels;
+
+  if (y1 < y0)
+  {
+    // Switch y1 and y0
+    y = y1;
+    y1 = y0;
+    y0 = y;
+  }
+
+  // Check limits
+  if (y1 >= lcdGetHeight())
+  {
+    y1 = lcdGetHeight() - 1;
+  }
+  if (y0 >= lcdGetHeight())
+  {
+    y0 = lcdGetHeight() - 1;
+  }
+
+  for (pixels = 0; pixels < y1 - y0 + 1; pixels++)
+  {
+    hx8340bSetPosition(x, y0+pixels, x+1, y0+pixels+1);
+    hx8340bWriteData16(color);
+  }
+}
+
+/*************************************************/
+uint16_t lcdGetPixel(uint16_t x, uint16_t y)
+{
+  // ToDo
+  return 0;
+}
+
+/*************************************************/
+void lcdSetOrientation(lcdOrientation_t orientation)
+{
+  // ToDo
+}
+
+/*************************************************/
+lcdOrientation_t lcdGetOrientation(void)
+{
+  return lcdOrientation;
+}
+
+/*************************************************/
+uint16_t lcdGetWidth(void)
+{
+  return hx8340bProperties.width;
+}
+
+/*************************************************/
+uint16_t lcdGetHeight(void)
+{
+  return hx8340bProperties.height;
+}
+
+/*************************************************/
+void lcdScroll(int16_t pixels, uint16_t fillColor)
+{
+  // ToDo
+}
+
+/*************************************************/
+uint16_t lcdGetControllerID(void)
+{
+  return 0x8340;
+}
+
+/*************************************************/
+lcdProperties_t lcdGetProperties(void)
+{
+  return hx8340bProperties;
+}
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/hw/hx8340b.h b/reform2-lpc-fw/src/drivers/displays/graphic/hw/hx8340b.h
new file mode 100644
index 0000000000000000000000000000000000000000..298368274f1c35bb05778c7b5ced65679e80790f
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/hw/hx8340b.h
@@ -0,0 +1,157 @@
+/**************************************************************************/
+/*!
+    @file     hx8340b.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __HX8340B_H__
+#define __HX8340B_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "drivers/displays/graphic/lcd.h"
+
+/**************************************************************************
+    BTL221722-276L CONNECTOR (HX8340B_ICVERSION_N)
+    -----------------------------------------------------------------------
+    Pin   Function        Notes
+    ===   ==============  ===============================
+      1   VSS
+      2   NC
+      3   LED A/+         Vf 3.3V
+      4   VDD             2.8-3.3V
+      5   CS
+      6   SDI             Serial Data
+      7   SCL             Serial Clock
+      8   RS              Not used
+      9   RESET
+     10   VDD             2.8-3.3V
+     11   LED K1
+     12   LED K2
+     13   LED K3
+     14   VSS
+
+ **************************************************************************/
+
+// Comment this line out if RST on the LCD is tied to RST on the MCU
+// #define HX8340B_USERESET
+
+// Control pins
+#define HX8340B_PORT            (1)
+#define HX8340B_SDI_PIN         (25)
+#define HX8340B_SCL_PIN         (26)
+#define HX8340B_CS_PIN          (27)
+#define HX8340B_BL_PIN          (28)
+#ifdef HX8340B_USERESET
+  #define HX8340B_RES_PIN       (29)
+#endif
+
+// Macros for control line state
+#define CLR_SDI     do { LPC_GPIO->CLR[HX8340B_PORT] = (1 << HX8340B_SDI_PIN); } while(0)
+#define SET_SDI     do { LPC_GPIO->SET[HX8340B_PORT] = (1 << HX8340B_SDI_PIN); } while(0)
+#define CLR_SCL     do { LPC_GPIO->CLR[HX8340B_PORT] = (1 << HX8340B_SCL_PIN); } while(0)
+#define SET_SCL     do { LPC_GPIO->SET[HX8340B_PORT] = (1 << HX8340B_SCL_PIN); } while(0)
+#define CLR_CS      do { LPC_GPIO->CLR[HX8340B_PORT] = (1 << HX8340B_CS_PIN); } while(0)
+#define SET_CS      do { LPC_GPIO->SET[HX8340B_PORT] = (1 << HX8340B_CS_PIN); } while(0)
+#define CLR_BL      do { LPC_GPIO->CLR[HX8340B_PORT] = (1 << HX8340B_BL_PIN); } while(0)
+#define SET_BL      do { LPC_GPIO->SET[HX8340B_PORT] = (1 << HX8340B_BL_PIN); } while(0)
+#ifdef HX8340B_USERESET
+  #define CLR_RES   do { LPC_GPIO->CLR[HX8340B_PORT] = (1 << HX8340B_RES_PIN); } while(0)
+  #define SET_RES   do { LPC_GPIO->SET[HX8340B_PORT] = (1 << HX8340B_RES_PIN); } while(0)
+#endif
+
+// HX8340-B(N) Commands (used by BTL221722-276L)
+#define HX8340B_N_NOP                     (0x00)
+#define HX8340B_N_SWRESET                 (0x01)
+#define HX8340B_N_RDDIDIF                 (0x04)
+#define HX8340B_N_RDDST                   (0x09)
+#define HX8340B_N_RDDPM                   (0x0A)
+#define HX8340B_N_RDDMADCTL               (0x0B)
+#define HX8340B_N_RDDCOLMOD               (0x0C)
+#define HX8340B_N_RDDIM                   (0x0D)
+#define HX8340B_N_RDDSM                   (0x0E)
+#define HX8340B_N_RDDSDR                  (0x0F)
+#define HX8340B_N_SLPIN                   (0x10)
+#define HX8340B_N_SPLOUT                  (0x11)
+#define HX8340B_N_PTLON                   (0x12)
+#define HX8340B_N_NORON                   (0x13)
+#define HX8340B_N_INVOFF                  (0x20)
+#define HX8340B_N_INVON                   (0x21)
+#define HX8340B_N_GAMSET                  (0x26)
+#define HX8340B_N_DISPOFF                 (0x28)
+#define HX8340B_N_DISPON                  (0x29)
+#define HX8340B_N_CASET                   (0x2A)
+#define HX8340B_N_PASET                   (0x2B)
+#define HX8340B_N_RAMWR                   (0x2C)
+#define HX8340B_N_RAMRD                   (0x2E)
+#define HX8340B_N_RGBSET                  (0x2D)
+#define HX8340B_N_PLTAR                   (0x30)
+#define HX8340B_N_VSCRDEF                 (0x33)
+#define HX8340B_N_TEOFF                   (0x34)
+#define HX8340B_N_TEON                    (0x35)
+#define HX8340B_N_MADCTL                  (0x36)
+#define HX8340B_N_VSCRSADD                (0x37)
+#define HX8340B_N_IDMOFF                  (0x38)
+#define HX8340B_N_IDMON                   (0x39)
+#define HX8340B_N_COLMOD                  (0x3A)
+#define HX8340B_N_RDID1                   (0xDA)
+#define HX8340B_N_RDID2                   (0xDB)
+#define HX8340B_N_RDID3                   (0xDC)
+#define HX8340B_N_SETOSC                  (0xB0)
+#define HX8340B_N_SETPWCTR1               (0xB1)
+#define HX8340B_N_SETPWCTR2               (0xB2)
+#define HX8340B_N_SETPWCTR3               (0xB3)
+#define HX8340B_N_SETPWCTR4               (0xB4)
+#define HX8340B_N_SETPWCTR5               (0xB5)
+#define HX8340B_N_SETDISCTRL              (0xB6)
+#define HX8340B_N_SETFRMCTRL              (0xB7)
+#define HX8340B_N_SETDISCYCCTRL           (0xB8)
+#define HX8340B_N_SETINVCTRL              (0xB9)
+#define HX8340B_N_RGBBPCTR                (0xBA)
+#define HX8340B_N_SETRGBIF                (0xBB)
+#define HX8340B_N_SETDODC                 (0xBC)
+#define HX8340B_N_SETINTMODE              (0xBD)
+#define HX8340B_N_SETPANEL                (0xBE)
+#define HX8340B_N_SETOTP                  (0xC7)
+#define HX8340B_N_SETONOFF                (0xC0)
+#define HX8340B_N_SETEXTCMD               (0xC1)
+#define HX8340B_N_SETGAMMAP               (0xC2)
+#define HX8340B_N_SETGAMMAN               (0xC3)
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/hw/hx8347g.c b/reform2-lpc-fw/src/drivers/displays/graphic/hw/hx8347g.c
new file mode 100644
index 0000000000000000000000000000000000000000..1597c5a1feac6c14b72f39f901665fbebfa4afa2
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/hw/hx8347g.c
@@ -0,0 +1,564 @@
+/**************************************************************************/
+/*! 
+    @file     hx8347g.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section  DESCRIPTION
+
+    Driver for HX8347G 240x320 pixel TFT LCD displays.
+    
+    This driver uses an 8-bit interface and a 16-bit RGB565 colour palette.
+
+    @section  LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012 K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "hx8347g.h"
+#include "core/delay/delay.h"
+#include "core/gpio/gpio.h"
+// #include "drivers/displays/graphic/touchscreen.h"
+
+static volatile lcdOrientation_t lcdOrientation = LCD_ORIENTATION_PORTRAIT;
+
+// Screen/Driver Properties
+static lcdProperties_t hx8347gProperties = {  240,      // Screen width
+                                              320,      // Screen height
+                                              true,     // Has touchscreen?
+                                              false,    // Allows orientation changes?
+                                              false,    // Supports HW scrolling?
+                                              true,     // Driver includes fast horizontal line function?
+                                              false };  // Driver includes fast vertical line function?
+
+// Initialisation sequence (Ugly here but saves a bit of code space handled like this)
+static const uint8_t HX8347G_InitSequence[] = {
+  HX8347G_CMD_CYCLECONTROL2,            0x89,
+  HX8347G_CMD_FRAMERATECONTROL1,        0x8F,
+  HX8347G_CMD_FRAMERATECONTROL3,        0x02,
+  0xE2,                                 0x00,
+  HX8347G_CMD_POWERSAVING1,             0x01,
+  HX8347G_CMD_POWERSAVING2,             0x10,
+  HX8347G_CMD_POWERSAVING3,             0x01,
+  HX8347G_CMD_POWERSAVING4,             0x10,
+  HX8347G_CMD_SOURCEOP_CONTROLNORMAL,   0x70,
+  0xF2,                                 0x00,
+  0xEA,                                 0x00,
+  0xEB,                                 0x20,
+  0xEC,                                 0x3C,
+  0xED,                                 0xC8,
+  HX8347G_CMD_SOURCEOP_CONTROLIDLE,     0x38,
+  0xF1,                                 0x01,
+  // skip gamma, do later
+  HX8347G_CMD_POWERCONTROL2,            0x1B, // was 0x1A
+  HX8347G_CMD_POWERCONTROL1,            0x02,
+  HX8347G_CMD_VCOMCONTROL2,             0x65, // was 0x61
+  HX8347G_CMD_VCOMCONTROL3,             0x5C,
+  HX8347G_CMD_VCOMCONTROL1,             0x62,
+  HX8347G_CMD_OSCCONTROL2,              0x36,
+  HX8347G_CMD_OSCCONTROL1,              0x01,  // OSC_EN = 1
+  HX8347G_CMD_POWERCONTROL6,            0x88, 
+  HX8347G_INIT_DELAY,                   5,
+  HX8347G_CMD_POWERCONTROL6,            0x80,
+  HX8347G_INIT_DELAY,                   5,
+  HX8347G_CMD_POWERCONTROL6,            0x90,
+  HX8347G_INIT_DELAY,                   5,
+  HX8347G_CMD_POWERCONTROL6,            0xD4,
+  HX8347G_INIT_DELAY,                   5,
+  HX8347G_CMD_COLMOD,                   0x05,   // 0x05 = 16-bit RGB565
+  HX8347G_CMD_PANELCHARACTERISTICS,     0x09,
+  HX8347G_CMD_DISPLAYCONTROL3,          0x38,
+  HX8347G_INIT_DELAY,                   40,
+  HX8347G_CMD_DISPLAYCONTROL3,          0x3C,   // Turn the display on (GON = 1, DTE = 1, D = 1100)
+  HX8347G_CMD_COLADDRSTART2,            0x00,
+  HX8347G_CMD_COLADDRSTART1,            0x00,
+  HX8347G_CMD_COLADDREND2,              0x00,
+  HX8347G_CMD_COLADDREND1,              0xEF,
+  HX8347G_CMD_ROWADDRSTART2,            0x00,
+  HX8347G_CMD_ROWADDRSTART1,            0x00,
+  HX8347G_CMD_ROWADDREND2,              0x01,
+  HX8347G_CMD_ROWADDREND1,              0x3F,
+};
+
+/*************************************************/
+/* Private Methods                               */
+/*************************************************/
+void hx8347gDelay(unsigned int t)
+{
+  unsigned char t1;
+  while(t--)
+  for ( t1=10; t1 > 0; t1-- )
+  {
+    ASM("nop");
+  }
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Sends an 8-bit command + 8-bits data
+*/
+/**************************************************************************/
+void hx8347gWriteRegister(uint8_t command, uint8_t data)
+{
+  // Write command
+  CLR_CS_CD_SET_RD_WR;
+  // This won't work since it will only set the 1 bits and leave 0's as is
+  LPC_GPIO->SET[HX8347G_DATA_PORT] = (command & 0xFF) << HX8347G_DATA_OFFSET;
+  CLR_WR;
+  SET_WR;
+
+  // Write data
+  SET_CD;
+  // CLR_CS_SET_CD_RD_WR;
+  // This won't work since it will only set the 1 bits and leave 0's as is
+  LPC_GPIO->SET[HX8347G_DATA_PORT] = (data & 0xFF) << HX8347G_DATA_OFFSET;
+  CLR_WR;
+  SET_WR;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Sends an 8-bit command
+*/
+/**************************************************************************/
+void hx8347gWriteCommand(const uint8_t command)
+{
+  // Send command
+  CLR_CS_CD_SET_RD_WR;
+  // This won't work since it will only set the 1 bits and leave 0's as is
+  LPC_GPIO->SET[HX8347G_DATA_PORT] = (command & 0xFF) << HX8347G_DATA_OFFSET;
+  CLR_WR;
+  SET_WR;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Sends 16-bits of data
+*/
+/**************************************************************************/
+void hx8347gWriteData(const uint16_t data)
+{
+  // Send data
+  CLR_CS_SET_CD_RD_WR;
+  // This won't work since it will only set the 1 bits and leave 0's as is
+  LPC_GPIO->SET[HX8347G_DATA_PORT] = (data >> 8) << HX8347G_DATA_OFFSET;
+  CLR_WR;
+  SET_WR;
+  // This won't work since it will only set the 1 bits and leave 0's as is
+  LPC_GPIO->SET[HX8347G_DATA_PORT] = (data & 0xFF) << HX8347G_DATA_OFFSET;
+  CLR_WR;
+  SET_WR;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Reads the results from an 8-bit command
+*/
+/**************************************************************************/
+uint16_t hx8347gReadRegister(uint8_t command)
+{
+  uint16_t d = 0;
+
+  // Send command
+  CLR_CS_CD_SET_RD_WR;
+  // This won't work since it will only set the 1 bits and leave 0's as is
+  LPC_GPIO->SET[HX8347G_DATA_PORT] = (command & 0xFF) << HX8347G_DATA_OFFSET;
+  CLR_WR;
+  SET_WR;
+
+  // Set pins to input
+  HX8347G_GPIO2DATA_SETINPUT;
+
+  // Read results
+  SET_CD_RD_WR;  
+  CLR_RD;
+  hx8347gDelay(10);
+  // This won't work since it will only set the 1 bits and leave 0's as is
+  d = (((LPC_GPIO->SET[HX8347G_DATA_PORT]) & HX8347G_DATA_MASK) >> HX8347G_DATA_OFFSET);
+  SET_RD;
+  SET_CS;
+
+  // Set pins to output
+  HX8347G_GPIO2DATA_SETOUTPUT;
+
+  return d;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Reads 16-bits of data from the current pixel location
+*/
+/**************************************************************************/
+uint16_t hx8347gReadData(void)
+{
+  uint8_t high, low;
+  high = low = 0;
+
+  CLR_CS_SET_CD_RD_WR;
+
+  // Set pins to input
+  HX8347G_GPIO2DATA_SETINPUT;
+  CLR_RD;
+  hx8347gDelay(10);
+  // This won't work since it will only set the 1 bits and leave 0's as is
+  high = ((LPC_GPIO->SET[HX8347G_DATA_PORT]) & HX8347G_DATA_MASK);
+  high >>= HX8347G_DATA_OFFSET;
+  printf("high: 0x%02X\r\n", high);
+  SET_RD;
+  CLR_RD;
+  hx8347gDelay(10);
+  // This won't work since it will only set the 1 bits and leave 0's as is
+  low = ((LPC_GPIO->SET[HX8347G_DATA_PORT]) & HX8347G_DATA_MASK);
+  low >>= HX8347G_DATA_OFFSET;
+  printf("low: 0x%02X\r\n", low);
+  SET_RD;
+  SET_CS;
+  HX8347G_GPIO2DATA_SETOUTPUT;
+
+  return (uint16_t)((high << 8) | (low));
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Sets the cursor to the specified X/Y position
+*/
+/**************************************************************************/
+void hx8347gSetCursor(const uint16_t x, const uint16_t y)
+{
+  hx8347gWriteRegister(HX8347G_CMD_COLADDRSTART2, x>>8);
+  hx8347gWriteRegister(HX8347G_CMD_COLADDRSTART1, x);
+  hx8347gWriteRegister(HX8347G_CMD_ROWADDRSTART2, y>>8);
+  hx8347gWriteRegister(HX8347G_CMD_ROWADDRSTART1, y);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Sends the initialisation sequence to the display controller
+*/
+/**************************************************************************/
+void hx8347gInitDisplay(void)
+{
+  uint8_t i, a, d;
+
+  // Clear data line
+  LPC_GPIO->SET[HX8347G_DATA_PORT] &= ~HX8347G_DATA_MASK;
+    
+  SET_RD;
+  SET_WR;
+  SET_CS;
+  SET_CD;
+
+  // Reset display
+  CLR_RESET;
+  delay(10);
+  SET_RESET;
+  delay(500);
+
+  // Send the init sequence
+  for (i = 0; i < sizeof(HX8347G_InitSequence) / 2; i++) 
+  {
+    a = HX8347G_InitSequence[i*2];
+    d = HX8347G_InitSequence[i*2 + 1];
+
+    if (a == HX8347G_INIT_DELAY)
+    {
+      hx8347gDelay(1000);
+    } 
+    else 
+    {
+      hx8347gWriteRegister(a, d);
+    }
+  }
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Sets the window confines
+*/
+/**************************************************************************/
+void hx8347gSetWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
+{
+  // ToDo
+}
+
+/*************************************************/
+/* Public Methods                                */
+/*************************************************/
+
+/**************************************************************************/
+/*! 
+    @brief  Configures any pins or HW and initialises the LCD controller
+*/
+/**************************************************************************/
+void lcdInit(void)
+{
+  // Set control line pins to output
+  LPC_GPIO->DIR[HX8347G_CONTROL_PORT] |=  (1 << HX8347G_CS_PIN);
+  LPC_GPIO->DIR[HX8347G_CONTROL_PORT] |=  (1 << HX8347G_CD_PIN);
+  LPC_GPIO->DIR[HX8347G_CONTROL_PORT] |=  (1 << HX8347G_WR_PIN);
+  LPC_GPIO->DIR[HX8347G_CONTROL_PORT] |=  (1 << HX8347G_RD_PIN);
+  
+  // Set data port pins to output
+  LPC_GPIO->DIR[HX8347G_DATA_PORT] |=  (1 << HX8347G_DATA_MASK);
+
+  // Set backlight pin to output and turn it on
+  LPC_GPIO->DIR[HX8347G_BL_PORT] |=  (1 << HX8347G_BL_PIN);
+  lcdBacklight(TRUE);
+
+  // Set reset pin to output
+  LPC_GPIO->DIR[HX8347G_RES_PORT] |=  (1 << HX8347G_RES_PIN);
+  // Low then high to reset
+  CLR_RESET;
+  delay(50);
+  SET_RESET;
+
+  // Initialize the display
+  hx8347gInitDisplay();
+
+  delay(50);
+
+  // Set lcd to default orientation
+  // lcdSetOrientation(lcdOrientation);
+
+  // Fill screen
+  lcdFillRGB(COLOR_BLUE);
+  
+  // Initialise the touch screen (and calibrate if necessary)
+  // tsInit();
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Enables or disables the LCD backlight
+*/
+/**************************************************************************/
+void lcdBacklight(bool state)
+{
+  // Set the backlight
+  if (state)
+  {
+    SET_BL;
+  }
+  else
+  {
+    CLR_BL;
+  }
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Renders a simple test pattern on the LCD
+*/
+/**************************************************************************/
+void lcdTest(void)
+{
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Fills the LCD with the specified 16-bit color
+*/
+/**************************************************************************/
+void lcdFillRGB(uint16_t color)
+{
+  uint32_t i;
+  i = lcdGetWidth() * lcdGetHeight();
+
+  hx8347gSetCursor(0,0);
+  hx8347gWriteCommand(HX8347G_CMD_SRAMWRITECONTROL);
+
+  // Fill screen
+  while (i--) 
+  {
+    hx8347gWriteData(color);
+  }
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Draws a single pixel at the specified X/Y location
+*/
+/**************************************************************************/
+void lcdDrawPixel(uint16_t x, uint16_t y, uint16_t color)
+{
+  if ((x >= lcdGetWidth()) || (y >= lcdGetHeight())) return;
+
+  hx8347gSetCursor(x,y);
+  hx8347gWriteCommand(HX8347G_CMD_SRAMWRITECONTROL);
+  hx8347gWriteData(color);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Draws an array of consecutive RGB565 pixels (much
+            faster than addressing each pixel individually)
+*/
+/**************************************************************************/
+void lcdDrawPixels(uint16_t x, uint16_t y, uint16_t *data, uint32_t len)
+{
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Optimised routine to draw a horizontal line faster than
+            setting individual pixels
+*/
+/**************************************************************************/
+void lcdDrawHLine(uint16_t x0, uint16_t x1, uint16_t y, uint16_t color)
+{
+  // Allows for slightly better performance than setting individual pixels
+  uint16_t x, pixels;
+
+  if (x1 < x0)
+  {
+    // Switch x1 and x0
+    x = x1;
+    x1 = x0;
+    x0 = x;
+  }
+
+  // Check limits
+  if (x1 >= lcdGetWidth())
+  {
+    x1 = lcdGetWidth() - 1;
+  }
+  if (x0 >= lcdGetWidth())
+  {
+    x0 = lcdGetWidth() - 1;
+  }
+
+  hx8347gSetCursor(x0, y);
+  hx8347gWriteCommand(HX8347G_CMD_SRAMWRITECONTROL);
+  // Draw line
+  for (pixels = 0; pixels < x1 - x0 + 1; pixels++)
+  {
+    hx8347gWriteData(color);
+  }
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Optimised routine to draw a vertical line faster than
+            setting individual pixels
+*/
+/**************************************************************************/
+void lcdDrawVLine(uint16_t x, uint16_t y0, uint16_t y1, uint16_t color)
+{
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Gets the 16-bit color of the pixel at the specified location
+*/
+/**************************************************************************/
+uint16_t lcdGetPixel(uint16_t x, uint16_t y)
+{
+  /*  The first byte of data apparently has to be ignored (DS section 4.1, p.29):  
+      Furthermore, there are two 18-bit bus control registers used to temporarily store the
+      data written to or read from the GRAM. When the data is written into the GRAM from
+      the MPU, it is first written into the write-data latch and then automatically written into
+      the GRAM by internal operation. Data is read through the read-data latch when
+      reading from the GRAM. Therefore, the first read data operation is invalid and the
+      following read data operations are valid. */
+
+  if ((x >= hx8347gProperties.width) || (y >= hx8347gProperties.height)) return 0;
+
+  hx8347gSetCursor(x,y);
+  hx8347gWriteCommand(HX8347G_CMD_SRAMWRITECONTROL);
+  return hx8347gReadData();
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Sets the LCD orientation to horizontal and vertical
+*/
+/**************************************************************************/
+void lcdSetOrientation(lcdOrientation_t orientation)
+{
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Gets the current screen orientation (horizontal or vertical)
+*/
+/**************************************************************************/
+lcdOrientation_t lcdGetOrientation(void)
+{
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Gets the width in pixels of the LCD screen (varies depending
+            on the current screen orientation)
+*/
+/**************************************************************************/
+uint16_t lcdGetWidth(void)
+{
+    return hx8347gProperties.width;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Gets the height in pixels of the LCD screen (varies depending
+            on the current screen orientation)
+*/
+/**************************************************************************/
+uint16_t lcdGetHeight(void)
+{
+    return hx8347gProperties.height;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Scrolls the contents of the LCD screen vertically the
+            specified number of pixels using a HW optimised routine
+*/
+/**************************************************************************/
+void lcdScroll(int16_t pixels, uint16_t fillColor)
+{
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Gets the controller's 16-bit (4 hexdigit) ID
+*/
+/**************************************************************************/
+uint16_t lcdGetControllerID(void)
+{
+    return 0x8347;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Returns the LCDs 'lcdProperties_t' that describes the LCDs
+            generic capabilities and dimensions
+*/
+/**************************************************************************/
+lcdProperties_t lcdGetProperties(void)
+{
+    return hx8347gProperties;
+}
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/hw/hx8347g.h b/reform2-lpc-fw/src/drivers/displays/graphic/hw/hx8347g.h
new file mode 100644
index 0000000000000000000000000000000000000000..619a60575340058fa05664e3cbdbaa97100be10e
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/hw/hx8347g.h
@@ -0,0 +1,187 @@
+/**************************************************************************/
+/*! 
+    @file     hx8347g.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __HX8347G_H__
+#define __HX8347G_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "drivers/displays/graphic/lcd.h"
+
+// Backlight enable and reset pins
+#define HX8347G_BL_PORT               (1)
+#define HX8347G_BL_PIN                (27)
+#define HX8347G_RES_PORT              (1)
+#define HX8347G_RES_PIN               (28)
+
+// Control pins (these should be on the same port for best performance)
+#define HX8347G_CONTROL_PORT          (1)     
+#define HX8347G_CS_PIN                (13)
+#define HX8347G_CD_PIN                (14)
+#define HX8347G_WR_PIN                (15)
+#define HX8347G_RD_PIN                (16)
+
+// Combined pin definitions for optimisation purposes.
+#define HX8347G_CS_CD_PINS            ((1<<HX8347G_CS_PIN) + (1<<HX8347G_CD_PIN))
+#define HX8347G_RD_WR_PINS            ((1<<HX8347G_RD_PIN) + (1<<HX8347G_WR_PIN))
+#define HX8347G_WR_CS_PINS            ((1<<HX8347G_WR_PIN) + (1<<HX8347G_CS_PIN))
+#define HX8347G_CD_RD_WR_PINS         ((1<<HX8347G_CD_PIN) + (1<<HX8347G_RD_PIN) + (1<<HX8347G_WR_PIN))
+#define HX8347G_CS_CD_RD_WR_PINS      ((1<<HX8347G_CS_PIN) + (1<<HX8347G_CD_PIN) + (1<<HX8347G_RD_PIN) + (1<<HX8347G_WR_PIN))
+
+// Data bus (data pins must be consecutive and on the same port)
+#define HX8347G_DATA_PORT             (1)
+#define HX8347G_DATA_PIN1             (19)
+#define HX8347G_DATA_PIN2             (20)
+#define HX8347G_DATA_PIN3             (21)
+#define HX8347G_DATA_PIN4             (22)
+#define HX8347G_DATA_PIN5             (23)
+#define HX8347G_DATA_PIN6             (24)
+#define HX8347G_DATA_PIN7             (25)
+#define HX8347G_DATA_PIN8             (26)
+#define HX8347G_DATA_OFFSET           (HX8347G_DATA_PIN1)
+#define HX8347G_DATA_MASK             (0xFF << HX8347G_DATA_OFFSET)
+
+// Macros to set data bus direction to input/output
+#define HX8347G_GPIO2DATA_SETINPUT    do { LPC_GPIO->DIR[HX8347G_DATA_PORT] &= ~HX8347G_DATA_MASK; } while(0)
+#define HX8347G_GPIO2DATA_SETOUTPUT   do { LPC_GPIO->DIR[HX8347G_DATA_PORT] |= HX8347G_DATA_MASK; } while(0)
+
+// Macros for control line state
+// NOPs required since the bit-banding is too fast for some HX8347Gs to handle :(
+#define CLR_CD                        do { LPC_GPIO->CLR[HX8347G_CONTROL_PORT] = (1 << HX8347G_CD_PIN); } while(0)
+#define SET_CD                        do { LPC_GPIO->SET[HX8347G_CONTROL_PORT] = (1 << HX8347G_CD_PIN); } while(0)
+#define CLR_CS                        do { LPC_GPIO->CLR[HX8347G_CONTROL_PORT] = (1 << HX8347G_CS_PIN); } while(0)
+#define SET_CS                        do { LPC_GPIO->SET[HX8347G_CONTROL_PORT] = (1 << HX8347G_CS_PIN); } while(0)
+#define CLR_WR                        do { LPC_GPIO->CLR[HX8347G_CONTROL_PORT] = (1 << HX8347G_WR_PIN); } while(0)
+#define SET_WR                        do { LPC_GPIO->SET[HX8347G_CONTROL_PORT] = (1 << HX8347G_WR_PIN); } while(0)
+#define CLR_RD                        do { LPC_GPIO->CLR[HX8347G_CONTROL_PORT] = (1 << HX8347G_RD_PIN); } while(0)
+#define SET_RD                        do { LPC_GPIO->SET[HX8347G_CONTROL_PORT] = (1 << HX8347G_RD_PIN); } while(0)
+#define CLR_RESET                     do { LPC_GPIO->CLR[HX8347G_RES_PORT] = (1 << HX8347G_RES_PORT); } while(0)
+#define SET_RESET                     do { LPC_GPIO->SET[HX8347G_RES_PORT] = (1 << HX8347G_RES_PORT); } while(0)
+#define CLR_BL                        do { LPC_GPIO->CLR[HX8347G_BL_PORT] = (1 << HX8347G_BL_PORT); } while(0)
+#define SET_BL                        do { LPC_GPIO->SET[HX8347G_BL_PORT] = (1 << HX8347G_BL_PORT); } while(0)
+
+// These 'combined' macros are defined to improve code performance by
+// reducing the number of instructions in heavily used functions
+#define CLR_CS_CD                     do { LPC_GPIO->CLR[HX8347G_CONTROL_PORT] = (HX8347G_CS_CD_PINS); } while(0)
+#define SET_RD_WR                     do { LPC_GPIO->SET[HX8347G_CONTROL_PORT] = (HX8347G_RD_WR_PINS); } while(0)
+#define SET_WR_CS                     do { LPC_GPIO->SET[HX8347G_CONTROL_PORT] = (HX8347G_WR_CS_PINS); } while(0)
+#define SET_CD_RD_WR                  do { LPC_GPIO->SET[HX8347G_CONTROL_PORT] = (HX8347G_CD_RD_WR_PINS); } while(0)
+#define CLR_CS_CD_SET_RD_WR           do { LPC_GPIO->CLR[HX8347G_CONTROL_PORT] = (HX8347G_CS_CD_PINS); LPC_GPIO->SET[HX8347G_CONTROL_PORT] = (HX8347G_RD_WR_PINS); } while(0)
+#define CLR_CS_SET_CD_RD_WR           do { LPC_GPIO->CLR[HX8347G_CONTROL_PORT] = (HX8347G_CS_PIN); LPC_GPIO->SET[HX8347G_CONTROL_PORT] = (HX8347G_CD_RD_WR_PINS); } while(0)
+
+// Used to indicate a delay in the init sequence
+#define HX8347G_INIT_DELAY                      (0xF8)  // 0xFF is already used
+
+#define HX8347G_CMD_HIMAXID                     (0x00)
+#define HX8347G_CMD_DISPLAYMODECONTROL          (0x01)
+#define HX8347G_CMD_COLADDRSTART2               (0x02)
+#define HX8347G_CMD_COLADDRSTART1               (0x03)
+#define HX8347G_CMD_COLADDREND2                 (0x04)
+#define HX8347G_CMD_COLADDREND1                 (0x05)
+#define HX8347G_CMD_ROWADDRSTART2               (0x06)
+#define HX8347G_CMD_ROWADDRSTART1               (0x07)
+#define HX8347G_CMD_ROWADDREND2                 (0x08)
+#define HX8347G_CMD_ROWADDREND1                 (0x09)
+#define HX8347G_CMD_PARTIALAREASTARTROW2        (0x0A)
+#define HX8347G_CMD_PARTIALAREASTARTROW1        (0x0B)
+#define HX8347G_CMD_PARTIALAREAENDROW2          (0x0C)
+#define HX8347G_CMD_PARTIALAREAENDROW1          (0x0D)
+#define HX8347G_CMD_VERTICALSCROLLTOPFIXEDAREA2 (0x0E)
+#define HX8347G_CMD_VERTICALSCROLLTOPFIXEDAREA1 (0x0F)
+#define HX8347G_CMD_VERTICALSCROLLHEIGHTAREA2   (0x10)
+#define HX8347G_CMD_VERTICALSCROLLHEIGHTAREA1   (0x11)
+#define HX8347G_CMD_VERTICALSCROLLBUTTONAREA2   (0x12)
+#define HX8347G_CMD_VERTICALSCROLLBUTTONAREA1   (0x13)
+#define HX8347G_CMD_VERTICALSCROLLSTARTADDR2    (0x14)
+#define HX8347G_CMD_VERTICALSCROLLSTARTADDR1    (0x15)
+#define HX8347G_CMD_MEMORYACCESSCONTROL         (0x16)
+#define HX8347G_CMD_COLMOD                      (0x17)
+#define HX8347G_CMD_OSCCONTROL2                 (0x18)
+#define HX8347G_CMD_OSCCONTROL1                 (0x19)
+#define HX8347G_CMD_POWERCONTROL1               (0x1A)
+#define HX8347G_CMD_POWERCONTROL2               (0x1B)
+#define HX8347G_CMD_POWERCONTROL3               (0x1C)
+#define HX8347G_CMD_POWERCONTROL4               (0x1D)
+#define HX8347G_CMD_POWERCONTROL5               (0x1E)
+#define HX8347G_CMD_POWERCONTROL6               (0x1F)
+#define HX8347G_CMD_SRAMWRITECONTROL            (0x22)
+#define HX8347G_CMD_VCOMCONTROL1                (0x23)
+#define HX8347G_CMD_VCOMCONTROL2                (0x24)
+#define HX8347G_CMD_VCOMCONTROL3                (0x25)
+#define HX8347G_CMD_DISPLAYCONTROL1             (0x26)
+#define HX8347G_CMD_DISPLAYCONTROL2             (0x27)
+#define HX8347G_CMD_DISPLAYCONTROL3             (0x28)
+#define HX8347G_CMD_FRAMERATECONTROL1           (0x29)
+#define HX8347G_CMD_FRAMERATECONTROL2           (0x2A)
+#define HX8347G_CMD_FRAMERATECONTROL3           (0x2B)
+#define HX8347G_CMD_FRAMERATECONTROL4           (0x2C)
+#define HX8347G_CMD_CYCLECONTROL1               (0x2D)
+#define HX8347G_CMD_CYCLECONTROL2               (0x2E)
+#define HX8347G_CMD_DISPLAYINVERSION            (0x2F)
+#define HX8347G_CMD_RGBINTERFACECONTROL1        (0x31)
+#define HX8347G_CMD_RGBINTERFACECONTROL2        (0x32)
+#define HX8347G_CMD_RGBINTERFACECONTROL3        (0x33)
+#define HX8347G_CMD_RGBINTERFACECONTROL4        (0x34)
+#define HX8347G_CMD_PANELCHARACTERISTICS        (0x36)
+#define HX8347G_CMD_OTPCONTROL1                 (0x38)
+#define HX8347G_CMD_OTPCONTROL2                 (0x39)
+#define HX8347G_CMD_OTPCONTROL3                 (0x3A)
+#define HX8347G_CMD_OTPCONTROL4                 (0x3B)
+#define HX8347G_CMD_CABCCONTROL1                (0x3C)
+#define HX8347G_CMD_CABCCONTROL2                (0x3D)
+#define HX8347G_CMD_CABCCONTROL3                (0x3E)
+#define HX8347G_CMD_CABCCONTROL4                (0x3F)
+#define HX8347G_CMD_TECONTROL                   (0x60)
+#define HX8347G_CMD_ID1                         (0x61)
+#define HX8347G_CMD_ID2                         (0x62)
+#define HX8347G_CMD_ID3                         (0x63)
+#define HX8347G_CMD_TEOUTPUTLINE2               (0x84)
+#define HX8347G_CMD_TEOUTPUTLINE1               (0x85)
+#define HX8347G_CMD_POWERSAVING1                (0xE4)
+#define HX8347G_CMD_POWERSAVING2                (0xE5)
+#define HX8347G_CMD_POWERSAVING3                (0xE6)
+#define HX8347G_CMD_POWERSAVING4                (0xE7)
+#define HX8347G_CMD_SOURCEOP_CONTROLNORMAL      (0xE8)
+#define HX8347G_CMD_SOURCEOP_CONTROLIDLE        (0xE9)
+#define HX8347G_CMD_PAGESELECT                  (0xFF)
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/lcd.h b/reform2-lpc-fw/src/drivers/displays/graphic/lcd.h
new file mode 100644
index 0000000000000000000000000000000000000000..e3eb8800d5d2ac67678ff82df3b6ce2c8dced904
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/lcd.h
@@ -0,0 +1,91 @@
+/**************************************************************************/
+/*! 
+    @file     lcd.h
+    @author   K. Townsend (microBuilder.eu)
+    @date     22 March 2010
+    @version  0.10
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __LCD_H__
+#define __LCD_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "colors.h"
+
+// Any LCD needs to implement these common methods, which allow the low-level
+// initialisation and pixel-setting details to be abstracted away from the
+// higher level drawing and graphics code.
+
+typedef enum 
+{
+  LCD_ORIENTATION_PORTRAIT = 0,
+  LCD_ORIENTATION_LANDSCAPE = 1
+} lcdOrientation_t;
+
+// This struct is used to indicate the capabilities of different LCDs
+typedef struct
+{
+  uint16_t width;         // LCD width in pixels (default orientation)
+  uint16_t height;        // LCD height in pixels (default orientation)
+  bool     touchscreen;   // Whether the LCD has a touch screen
+  bool     orientation;   // Whether the LCD orientation can be modified
+  bool     hwscrolling;   // Whether the LCD support HW scrolling
+  bool     fastHLine;     // Whether the driver contains an accelerated horizontal line function
+  bool     fastVLine;     // Whether the driver contains an accelerated vertical line function
+} lcdProperties_t;
+
+extern void     lcdInit(void);
+extern void     lcdTest(void);
+extern uint16_t lcdGetPixel(uint16_t x, uint16_t y);
+extern void     lcdFillRGB(uint16_t data);
+extern void     lcdDrawPixel(uint16_t x, uint16_t y, uint16_t color);
+extern void     lcdDrawPixels(uint16_t x, uint16_t y, uint16_t *data, uint32_t len);
+extern void     lcdDrawHLine(uint16_t x0, uint16_t x1, uint16_t y, uint16_t color);
+extern void     lcdDrawVLine(uint16_t x, uint16_t y0, uint16_t y1, uint16_t color);
+extern void     lcdBacklight(bool state);
+extern void     lcdScroll(int16_t pixels, uint16_t fillColor);
+extern uint16_t lcdGetWidth(void);
+extern uint16_t lcdGetHeight(void);
+extern void     lcdSetOrientation(lcdOrientation_t orientation);
+extern uint16_t lcdGetControllerID(void);
+extern lcdOrientation_t lcdGetOrientation(void);
+extern lcdProperties_t lcdGetProperties(void);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/readme.txt b/reform2-lpc-fw/src/drivers/displays/graphic/readme.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0ee2bc44197ebf958f333274b7bf35d656b3359d
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/readme.txt
@@ -0,0 +1,41 @@
+TFT LCDs
+========
+
+The top level of this folder contains generic drawing routines for 16-bit TFT
+LCD displays.  The core drawing functions are defined in drawing.c, and the
+specific HW implementation of these routines (setting the individual pixels,
+initialising the display, etc.) takes place in a seperate HW drivers that
+implements the methods defined in lcd.h.  To change the LCD used, you simply
+need to change which HW-specific file is compiled and linked during the build
+process, without having to change anything else in your application code.
+
+For example:
+
+- main.c             - drawing.c          - hw\ili9325.c
+----------------     ----------------     ----------------
+  APPLICATION    --> GENERIC DRAWING  -->   SPECIFIC HW 
+     CODE        -->       CODE       -->      DRIVER
+----------------     ----------------     ----------------
+
+
+drawing.c          Generic drawing routines such as drawing pixels, lines,
+                   rectangles, as well as basic text-rendering.
+
+lcd.h              This file contains the prototypes of HW-specific functions
+                   that must be implemented in the LCD driver, since
+                   drawing.c will redirect all requests to these lower level
+                   functions.
+                   
+touchscreen.c      Contains a very simple example of how to use the ADC to read
+                   the current position on a touchscreen.  No signal debouncing
+                   takes places, and this code will need to be improved for use
+                   in a real-world situation.
+
+colors.c           Functions relating to color conversion, etc.
+
+fonts.c            1-bit font functions and definitions
+
+aafonts.c          Preliminary effort at adding 2-bit and 4-bit anti-
+                   aliased fonts, though this is still a work in progress.
+
+hw\*               HW-specific drivers based on lcd.h                   
\ No newline at end of file
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/theme.c b/reform2-lpc-fw/src/drivers/displays/graphic/theme.c
new file mode 100644
index 0000000000000000000000000000000000000000..390b1091a5defc915b1f26f29e2544dbebde104f
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/theme.c
@@ -0,0 +1,78 @@
+/**************************************************************************/
+/*! 
+    @file     theme.c
+    @author   K. Townsend (microBuilder.eu)
+    
+    Various helper functions to work with color themes.
+	
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, Kevin Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <string.h>
+
+#include "theme.h"
+
+/**************************************************************************/
+/*                                                                        */
+/* ----------------------- Private Methods ------------------------------ */
+/*                                                                        */
+/**************************************************************************/
+
+/**************************************************************************/
+/*                                                                        */
+/* ----------------------- Public Methods ------------------------------- */
+/*                                                                        */
+/**************************************************************************/
+
+/**************************************************************************/
+/*!
+    @brief  Gets the default theme
+
+    @section Example
+
+    @code 
+
+	theme_t defaultTheme = themeGetDefault();
+
+    @endcode
+*/
+/**************************************************************************/
+theme_t themeGetDefault(void)
+{
+  theme_t themeDefault = { .colorBackground   = COLOR_WHITE,       // Background Color
+                           .colorBorder       = COLOR_GRAY_128,    // Border Color
+                           .colorBorderDarker = COLOR_GRAY_80,     // Border Darker
+                           .colorText         = COLOR_BLACK,       // Text Color
+                           .colorTextAlt      = COLOR_GRAY_50,     // Alt. Text Color
+                           .colorFill         = COLOR_GRAY_200,    // Fill (Normal)
+                           .colorFillAlt      = COLOR_GRAY_225 };  // Fill (Alternate)
+
+  return themeDefault;
+}
diff --git a/reform2-lpc-fw/src/drivers/displays/graphic/theme.h b/reform2-lpc-fw/src/drivers/displays/graphic/theme.h
new file mode 100644
index 0000000000000000000000000000000000000000..c922fb71ef51e3d922688d95fefd82a52a1674a1
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/graphic/theme.h
@@ -0,0 +1,106 @@
+/**************************************************************************/
+/*! 
+    @file     theme.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Common UI definitions for the color scheme, fonts, etc.
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __THEME_H__
+#define __THEME_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+#include "colors.h"
+
+#if CFG_TFTLCD_USEAAFONTS
+  #include "drivers/displays/graphic/aafonts/aa2/DejaVuSansCondensedBold14_AA2.h"
+#else
+  #include "drivers/displays/graphic/fonts/dejavusans9.h"
+#endif
+
+// Generic Color Palettes (provided as a starting point for custom themes)
+#define THEME_COLOR_LIMEGREEN_BASE          (uint16_t)(0xD7F0)    // 211 255 130
+#define THEME_COLOR_LIMEGREEN_DARKER        (uint16_t)(0x8DE8)    // 137 188  69
+#define THEME_COLOR_LIMEGREEN_LIGHTER       (uint16_t)(0xEFF9)    // 238 255 207
+#define THEME_COLOR_LIMEGREEN_SHADOW        (uint16_t)(0x73EC)    // 119 127 103
+#define THEME_COLOR_LIMEGREEN_ACCENT        (uint16_t)(0xAE6D)    // 169 204 104
+
+#define THEME_COLOR_VIOLET_BASE             (uint16_t)(0x8AEF)    // 143  94 124
+#define THEME_COLOR_VIOLET_DARKER           (uint16_t)(0x4187)    //  66  49  59
+#define THEME_COLOR_VIOLET_LIGHTER          (uint16_t)(0xC475)    // 194 142 174
+#define THEME_COLOR_VIOLET_SHADOW           (uint16_t)(0x40E6)    //  66  29  52
+#define THEME_COLOR_VIOLET_ACCENT           (uint16_t)(0xC992)    // 204  50 144
+
+#define THEME_COLOR_EARTHY_BASE             (uint16_t)(0x6269)    //  97  79  73
+#define THEME_COLOR_EARTHY_DARKER           (uint16_t)(0x3103)    //  48  35  31
+#define THEME_COLOR_EARTHY_LIGHTER          (uint16_t)(0x8C30)    // 140 135 129
+#define THEME_COLOR_EARTHY_SHADOW           (uint16_t)(0xAB29)    // 173 102  79
+#define THEME_COLOR_EARTHY_ACCENT           (uint16_t)(0xFE77)    // 250 204 188
+
+#define THEME_COLOR_SKYBLUE_BASE            (uint16_t)(0x95BF)    // 150 180 255
+#define THEME_COLOR_SKYBLUE_DARKER          (uint16_t)(0x73B0)    // 113 118 131
+#define THEME_COLOR_SKYBLUE_LIGHTER         (uint16_t)(0xE75F)    // 227 235 255
+#define THEME_COLOR_SKYBLUE_SHADOW          (uint16_t)(0x4ACF)    //  75  90 127
+#define THEME_COLOR_SKYBLUE_ACCENT          (uint16_t)(0xB5F9)    // 182 188 204
+
+// Themes can be used to centrally change the color scheme for your app
+// All controls use the colors defined in the supplied theme_t by default
+typedef struct theme_s
+{
+  uint16_t colorBackground;                 // Fill color for the entire LCD
+  uint16_t colorBorder;                     // Border color for frames, buttons, windows, etc.
+  uint16_t colorBorderDarker;               // Slightly darker border color for frames when needed
+  uint16_t colorText;                       // Default text color (may be overridden in certain functions)
+  uint16_t colorTextAlt;                    // Alternate text color (may be overridden in certain functions)
+  uint16_t colorFill;                       // Fill color for window and control backgrounds
+  uint16_t colorFillAlt;                    // Slightly lighter or darker fill for window and control backgrounds
+} theme_t;
+
+// Default font
+#if CFG_TFTLCD_USEAAFONTS
+  #define THEME_FONT                        DejaVuSansCondensedBold14_AA2
+#else
+  #define THEME_FONT                        dejaVuSans9ptFontInfo
+#endif
+
+theme_t themeGetDefault(void);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/icons16.h b/reform2-lpc-fw/src/drivers/displays/icons16.h
new file mode 100644
index 0000000000000000000000000000000000000000..aef91aa52f36eadbda1141f4dbef23c83b64d3a5
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/icons16.h
@@ -0,0 +1,70 @@
+/**************************************************************************/
+/*! 
+    @file     icons16.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+
+/*
+    All icons have been converted from the GentleFace Toolbar Icon Set,
+    licensed under the Creative Commons Attribution-NonCommercial License.
+    for more information see: http://www.gentleface.com/free_icon_set.html
+*/
+
+// Each icon used will consume 32 bytes of flash memory
+
+#ifndef __ICONS16_H__
+#define __ICONS16_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+uint16_t icons16_alert[16]            = { 0x0000, 0x0000, 0x0180, 0x03C0, 0x03C0, 0x0660, 0x0660, 0x0E70, 0x0E70, 0x1E78, 0x3E7C, 0x3FFC, 0x7E7E, 0x7E7E, 0xFFFF, 0x0000 };
+uint16_t icons16_alert_interior[16]   = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0000, 0x0180, 0x0180, 0x0000, 0x0000 };
+uint16_t icons16_info[16]             = { 0x0000, 0x07F0, 0x0FF8, 0x1FFC, 0x3F3E, 0x7F3F, 0x7FFF, 0x7F3F, 0x7F3F, 0x7F3F, 0x7F3F, 0x7F3F, 0x3F3E, 0x1FFC, 0x0FF8, 0x07F0 };
+uint16_t icons16_info_interior[16]    = { 0x0000, 0x0000, 0x0000, 0x0000, 0x00C0, 0x00C0, 0x0000, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x0000, 0x0000, 0x0000 };
+uint16_t icons16_failed[16]           = { 0x0000, 0x07F0, 0x0FF8, 0x1FFC, 0x3FFE, 0x79CF, 0x788F, 0x7C1F, 0x7E3F, 0x7C1F, 0x788F, 0x79CF, 0x3FFE, 0x1FFC, 0x0FF8, 0x07F0 };
+uint16_t icons16_failed_interior[16]  = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0630, 0x0770, 0x03E0, 0x01C0, 0x03E0, 0x0770, 0x0630, 0x0000, 0x0000, 0x0000, 0x0000 };
+uint16_t icons16_passed[16]           = { 0x0000, 0x07F0, 0x0FF8, 0x1FFC, 0x3FFE, 0x7FEF, 0x7FC7, 0x7F8F, 0x731F, 0x783F, 0x7C7F, 0x7EFF, 0x3FFE, 0x1FFC, 0x0FF8, 0x07F0 };
+uint16_t icons16_passed_interior[16]  = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0010, 0x0038, 0x0070, 0x0CE0, 0x07C0, 0x0380, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000 };
+uint16_t icons16_pointer[16]          = { 0x07C0, 0x1FF0, 0x3FF8, 0x3FF8, 0x7FFC, 0x7FFC, 0x7FFC, 0x7FFC, 0x7FFC, 0x7FFC, 0x3FF8, 0x1FF0, 0x0FE0, 0x07C0, 0x0380, 0x0100 };
+uint16_t icons16_pointer_dot[16]      = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0380, 0x07C0, 0x07C0, 0x07C0, 0x0380, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
+uint16_t icons16_tag[16]              = { 0xFF00, 0xFF80, 0xCFC0, 0xCFE0, 0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE, 0x7FFE, 0x3FFE, 0x1FFC, 0x0FF8, 0x07F0, 0x03E0, 0x01C0, 0x0000 };
+uint16_t icons16_tag_dot[16]          = { 0x0000, 0x0000, 0x3000, 0x3000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
+uint16_t icons16_tools[16]            = { 0x118C, 0x118C, 0x11FC, 0x11FC, 0x10F8, 0x1070, 0x1070, 0x3870, 0x1070, 0x3870, 0x3870, 0x3870, 0x3870, 0x3870, 0x3870, 0x3870 };
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/segment/ht16k33/ht16k33.c b/reform2-lpc-fw/src/drivers/displays/segment/ht16k33/ht16k33.c
new file mode 100644
index 0000000000000000000000000000000000000000..6474fb3f59ea2d7abec8d8b67584b5b84207b901
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/segment/ht16k33/ht16k33.c
@@ -0,0 +1,185 @@
+/**************************************************************************/
+/*!
+    @file     ht16k33.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section DESCRIPTION
+
+    I2C Driver for the HT16K33 16*8 LED Driver
+
+    This driver is based on the HT16K33 Library from Limor Fried
+    (Adafruit Industries) at:
+    https://github.com/adafruit/Adafruit-LED-Backpack-Library
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+#include <string.h>
+#include "ht16k33.h"
+#include "core/i2c/i2c.h"
+#include "core/delay/delay.h"
+
+#define DELAY(mS)     do { delay(mS); } while(0);
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+volatile uint16_t _ht16k33_Buffer[8];
+
+/**************************************************************************/
+/* Private Methods                                                        */
+/**************************************************************************/
+
+/**************************************************************************/
+/*!
+    @brief  Writes to a register over I2C
+*/
+/**************************************************************************/
+err_t ht16k33WriteRegister (uint8_t reg)
+{
+  I2CWriteLength = 2;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = HT16K33_I2C_ADDRESS;       // I2C device address
+  I2CMasterBuffer[1] = reg;                       // Command register
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Writes an unsigned 8 bit values over I2C
+*/
+/**************************************************************************/
+err_t ht16k33Write8 (uint8_t reg, uint8_t value)
+{
+  I2CWriteLength = 3;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = HT16K33_I2C_ADDRESS;       // I2C device address
+  I2CMasterBuffer[1] = reg;                       // Command register
+  I2CMasterBuffer[2] = (value);                   // Value to write
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/* Public Methods                                                         */
+/**************************************************************************/
+
+/**************************************************************************/
+/*!
+    @brief Initialises the HT16K33 LED driver
+*/
+/**************************************************************************/
+err_t ht16k33Init(void)
+{
+  // Make sure I2C is initialised
+  i2cInit(I2CMASTER);
+
+  /* Ping the I2C device first to see if it exists! */
+  ASSERT(!(i2cCheckAddress(HT16K33_I2C_ADDRESS)), ERROR_I2C_DEVICENOTFOUND);
+
+  // Turn the oscillator on
+  ASSERT_STATUS(ht16k33WriteRegister(HT16K33_REGISTER_SYSTEM_SETUP | 0x01));
+
+  // Turn blink off
+  ASSERT_STATUS(ht16k33SetBlinkRate(HT16K33_BLINKRATE_OFF));
+
+  // Set max brightness
+  ASSERT_STATUS(ht16k33SetBrightness(15));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief Sets the display brightness/dimming (0..15)
+*/
+/**************************************************************************/
+err_t ht16k33SetBrightness(uint8_t brightness)
+{
+  if (brightness > 15) brightness = 15;
+  return ht16k33WriteRegister(HT16K33_REGISTER_DIMMING | brightness);
+}
+
+/**************************************************************************/
+/*!
+    @brief Sets the display blink rate
+*/
+/**************************************************************************/
+err_t ht16k33SetBlinkRate(ht16k33BlinkRate_t blinkRate)
+{
+  if (blinkRate > HT16K33_BLINKRATE_HALFHZ) blinkRate = HT16K33_BLINKRATE_OFF;
+  return ht16k33WriteRegister(HT16K33_REGISTER_DISPLAY_SETUP | 0x01 | (blinkRate << 1));
+}
+
+/**************************************************************************/
+/*!
+    @brief Updates the display memory
+*/
+/**************************************************************************/
+err_t ht16k33WriteDisplay(void)
+{
+  int32_t i;
+
+  // Send 8x16-bits of data
+  I2CWriteLength = 18;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = HT16K33_I2C_ADDRESS;       // I2C device address
+  I2CMasterBuffer[1] = 0x00;                      // Start at address 0
+  for (i = 0; i < 8; i++)                         // Individual characters
+  {
+    I2CMasterBuffer[(i*2)+2] = _ht16k33_Buffer[i] & 0xFF;
+    I2CMasterBuffer[(i*2)+2] = _ht16k33_Buffer[i] >> 8;
+  }
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief Clears the display memory
+*/
+/**************************************************************************/
+void ht16k33Clear(void)
+{
+  uint8_t i;
+  for (i=0; i<8; i++)
+  {
+    _ht16k33_Buffer[i] = 0xFFFF;
+  }
+}
diff --git a/reform2-lpc-fw/src/drivers/displays/segment/ht16k33/ht16k33.h b/reform2-lpc-fw/src/drivers/displays/segment/ht16k33/ht16k33.h
new file mode 100644
index 0000000000000000000000000000000000000000..efb23ca9b7078bc4b86896479cd8aa27e91b2581
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/segment/ht16k33/ht16k33.h
@@ -0,0 +1,101 @@
+/**************************************************************************/
+/*!
+    @file     ht16k33.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012 K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __JT16K33_H__
+#define __HT16K33_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+/*=========================================================================
+    I2C Address
+    ---------------------------------------------------------------------*/
+    #define HT16K33_I2C_ADDRESS             (0xE0)    // = 0111 000x
+    #define HT16K33_I2C_READWRITE           (0x01)
+/*=========================================================================*/
+
+// Registers
+enum
+{
+  HT16K33_REGISTER_DISPLAY_SETUP        = 0x80,
+  HT16K33_REGISTER_SYSTEM_SETUP         = 0x20,
+  HT16K33_REGISTER_DIMMING              = 0xE0
+};
+
+// Blink Rate
+typedef enum
+{
+  HT16K33_BLINKRATE_OFF       = 0x00,
+  HT16K33_BLINKRATE_2HZ       = 0x01,
+  HT16K33_BLINKRATE_1HZ       = 0x02,
+  HT16K33_BLINKRATE_HALFHZ    = 0x03
+} ht16k33BlinkRate_t;
+
+// Hexadecimal number table for 7-segment displays
+static const uint8_t _ht16k33_numbertable[] =
+{
+  0x3F, /* 0 */
+  0x06, /* 1 */
+  0x5B, /* 2 */
+  0x4F, /* 3 */
+  0x66, /* 4 */
+  0x6D, /* 5 */
+  0x7D, /* 6 */
+  0x07, /* 7 */
+  0x7F, /* 8 */
+  0x6F, /* 9 */
+  0x77, /* A */
+  0x7C, /* B */
+  0x39, /* C */
+  0x5E, /* D */
+  0x79, /* E */
+  0x71, /* F */
+};
+
+// Function prototypes
+err_t ht16k33Init ( void );
+err_t ht16k33SetBrightness ( uint8_t brightness );
+err_t ht16k33SetBlinkRate ( ht16k33BlinkRate_t blinkRate );
+err_t ht16k33WriteDisplay ( void );
+void    ht16k33Clear ( void );
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/displays/smallfonts.c b/reform2-lpc-fw/src/drivers/displays/smallfonts.c
new file mode 100644
index 0000000000000000000000000000000000000000..f52f9981cb7a040eaf0a401cd0f409eb5cfc225a
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/smallfonts.c
@@ -0,0 +1,556 @@
+/* Partially based on original code for the KS0108 by Stephane Rey */
+
+/**************************************************************************/
+/*! 
+    @file     smallfonts.c
+    @author   K. Townsend (microBuilder.eu)
+    @date     22 March 2010
+    @version  0.10
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "sysdefs.h"
+#include "smallfonts.h"
+
+/* Global variables */
+const struct FONT_DEF Font_System3x6    = {3, 6, 32, 96,  au8FontSystem3x6};
+const struct FONT_DEF Font_System5x8    = {5, 8, 32, 128, au8FontSystem5x8};
+const struct FONT_DEF Font_System7x8    = {7, 8, 32, 128, au8FontSystem7x8};
+const struct FONT_DEF Font_8x8          = {8, 8, 32, 128, au8Font8x8};
+const struct FONT_DEF Font_8x8Thin      = {8, 8, 32, 128, au8Font8x8Thin};
+
+/* System 3x6 - UPPER CASE ONLY */
+const uint8_t au8FontSystem3x6[]= {
+    0x00,0x00,0x00, /* Space */         
+    0x00,0x5C,0x00, /* ! */                         
+    0x0C,0x00,0x0C, /* " */                         
+    0x7C,0x28,0x7C, /* # */                         
+    0x7C,0x44,0x7C, /* 0x */                        
+    0x24,0x10,0x48, /* % */                         
+    0x28,0x54,0x08, /* & */                         
+    0x00,0x0C,0x00, /* ' */                         
+    0x38,0x44,0x00, /* ( */                         
+    0x44,0x38,0x00, /* ) */                         
+    0x20,0x10,0x08, /* // */                        
+    0x10,0x38,0x10, /* + */                         
+    0x80,0x40,0x00, /* , */                         
+    0x10,0x10,0x10, /* - */                         
+    0x00,0x40,0x00, /* . */                         
+    0x20,0x10,0x08, /* / */    
+    0x38,0x44,0x38, /* 0 */                     
+    0x00,0x7C,0x00, /* 1 */                         
+    0x64,0x54,0x48, /* 2 */                         
+    0x44,0x54,0x28, /* 3 */                         
+    0x1C,0x10,0x7C, /* 4 */                         
+    0x4C,0x54,0x24, /* 5 */                         
+    0x38,0x54,0x20, /* 6 */                         
+    0x04,0x74,0x0C, /* 7 */                         
+    0x28,0x54,0x28, /* 8 */                         
+    0x08,0x54,0x38, /* 9 */                         
+    0x00,0x50,0x00, /* : */                         
+    0x80,0x50,0x00, /* ; */                         
+    0x10,0x28,0x44, /* < */                         
+    0x28,0x28,0x28, /* = */                  
+    0x44,0x28,0x10, /* > */                        
+    0x04,0x54,0x08, /* ? */                         
+    0x38,0x4C,0x5C, /* @ */                          
+    0x78,0x14,0x78, /* A */                         
+    0x7C,0x54,0x28, /* B */                         
+    0x38,0x44,0x44, /* C */                         
+    0x7C,0x44,0x38, /* D */                         
+    0x7C,0x54,0x44, /* E */                         
+    0x7C,0x14,0x04, /* F */                         
+    0x38,0x44,0x34, /* G */                         
+    0x7C,0x10,0x7C, /* H */                         
+    0x00,0x7C,0x00, /* I */                         
+    0x20,0x40,0x3C, /* J */                         
+    0x7C,0x10,0x6C, /* K */                         
+    0x7C,0x40,0x40, /* L */                         
+    0x7C,0x08,0x7C, /* M */                         
+    0x7C,0x04,0x7C, /* N */                         
+    0x7C,0x44,0x7C, /* O */                         
+    0x7C,0x14,0x08, /* P */                 
+    0x38,0x44,0x78, /* Q */                         
+    0x7C,0x14,0x68, /* R */                         
+    0x48,0x54,0x24, /* S */                         
+    0x04,0x7C,0x04, /* T */                         
+    0x7C,0x40,0x7C, /* U */                         
+    0x3C,0x40,0x3C, /* V */                         
+    0x7C,0x20,0x7C, /* W */                         
+    0x6C,0x10,0x6C, /* X */                         
+    0x1C,0x60,0x1C, /* Y */                         
+    0x64,0x54,0x4C, /* Z */                         
+    0x7C,0x44,0x00, /* [ */                         
+    0x08,0x10,0x20, /* \ */                         
+    0x44,0x7C,0x00, /* ] */                         
+    0x08,0x04,0x08, /* ^ */                         
+    0x80,0x80,0x80, /* _ */                         
+    0x04,0x08,0x00  /* ` */                 
+};
+
+/* System 5x8 */
+const uint8_t au8FontSystem5x8[]= 
+{
+    0x00,0x00,0x00,0x00,0x00, /* Space */
+    0x00,0x00,0x4f,0x00,0x00, /* ! */
+    0x00,0x07,0x00,0x07,0x00, /* " */
+    0x14,0x7f,0x14,0x7f,0x14, /* # */
+    0x24,0x2a,0x7f,0x2a,0x12, /* 0x */
+    0x23,0x13,0x08,0x64,0x62, /* % */
+    0x36,0x49,0x55,0x22,0x20, /* & */
+    0x00,0x05,0x03,0x00,0x00, /* ' */
+    0x00,0x1c,0x22,0x41,0x00, /* ( */
+    0x00,0x41,0x22,0x1c,0x00, /* ) */
+    0x14,0x08,0x3e,0x08,0x14, /* // */
+    0x08,0x08,0x3e,0x08,0x08, /* + */
+    0x50,0x30,0x00,0x00,0x00, /* , */
+    0x08,0x08,0x08,0x08,0x08, /* - */ 
+    0x00,0x60,0x60,0x00,0x00, /* . */
+    0x20,0x10,0x08,0x04,0x02, /* / */
+    0x3e,0x51,0x49,0x45,0x3e, /* 0 */
+    0x00,0x42,0x7f,0x40,0x00, /* 1 */
+    0x42,0x61,0x51,0x49,0x46, /* 2 */
+    0x21,0x41,0x45,0x4b,0x31, /* 3 */
+    0x18,0x14,0x12,0x7f,0x10, /* 4 */
+    0x27,0x45,0x45,0x45,0x39, /* 5 */
+    0x3c,0x4a,0x49,0x49,0x30, /* 6 */
+    0x01,0x71,0x09,0x05,0x03, /* 7 */
+    0x36,0x49,0x49,0x49,0x36, /* 8 */
+    0x06,0x49,0x49,0x29,0x1e, /* 9 */
+    0x00,0x36,0x36,0x00,0x00, /* : */
+    0x00,0x56,0x36,0x00,0x00, /* ; */
+    0x08,0x14,0x22,0x41,0x00, /* < */
+    0x14,0x14,0x14,0x14,0x14, /* = */
+    0x00,0x41,0x22,0x14,0x08, /* > */
+    0x02,0x01,0x51,0x09,0x06, /* ? */
+    0x3e,0x41,0x5d,0x55,0x1e, /* @ */
+    0x7e,0x11,0x11,0x11,0x7e, /* A */
+    0x7f,0x49,0x49,0x49,0x36, /* B */
+    0x3e,0x41,0x41,0x41,0x22, /* C */
+    0x7f,0x41,0x41,0x22,0x1c, /* D */
+    0x7f,0x49,0x49,0x49,0x41, /* E */
+    0x7f,0x09,0x09,0x09,0x01, /* F */
+    0x3e,0x41,0x49,0x49,0x7a, /* G */
+    0x7f,0x08,0x08,0x08,0x7f, /* H */
+    0x00,0x41,0x7f,0x41,0x00, /* I */
+    0x20,0x40,0x41,0x3f,0x01, /* J */
+    0x7f,0x08,0x14,0x22,0x41, /* K */
+    0x7f,0x40,0x40,0x40,0x40, /* L */
+    0x7f,0x02,0x0c,0x02,0x7f, /* M */
+    0x7f,0x04,0x08,0x10,0x7f, /* N */
+    0x3e,0x41,0x41,0x41,0x3e, /* O */
+    0x7f,0x09,0x09,0x09,0x06, /* P */
+    0x3e,0x41,0x51,0x21,0x5e, /* Q */
+    0x7f,0x09,0x19,0x29,0x46, /* R */
+    0x26,0x49,0x49,0x49,0x32, /* S */
+    0x01,0x01,0x7f,0x01,0x01, /* T */
+    0x3f,0x40,0x40,0x40,0x3f, /* U */
+    0x1f,0x20,0x40,0x20,0x1f, /* V */
+    0x3f,0x40,0x38,0x40,0x3f, /* W */
+    0x63,0x14,0x08,0x14,0x63, /* X */
+    0x07,0x08,0x70,0x08,0x07, /* Y */
+    0x61,0x51,0x49,0x45,0x43, /* Z */
+    0x00,0x7f,0x41,0x41,0x00, /* [ */
+    0x02,0x04,0x08,0x10,0x20, /* \ */ 
+    0x00,0x41,0x41,0x7f,0x00, /* ] */
+    0x04,0x02,0x01,0x02,0x04, /* ^ */
+    0x40,0x40,0x40,0x40,0x40, /* _ */
+    0x00,0x00,0x03,0x05,0x00, /* ` */
+    0x20,0x54,0x54,0x54,0x78, /* a */
+    0x7F,0x44,0x44,0x44,0x38, /* b */
+    0x38,0x44,0x44,0x44,0x44, /* c */
+    0x38,0x44,0x44,0x44,0x7f, /* d */
+    0x38,0x54,0x54,0x54,0x18, /* e */
+    0x04,0x04,0x7e,0x05,0x05, /* f */
+    0x08,0x54,0x54,0x54,0x3c, /* g */
+    0x7f,0x08,0x04,0x04,0x78, /* h */
+    0x00,0x44,0x7d,0x40,0x00, /* i */
+    0x20,0x40,0x44,0x3d,0x00, /* j */
+    0x7f,0x10,0x28,0x44,0x00, /* k */
+    0x00,0x41,0x7f,0x40,0x00, /* l */
+    0x7c,0x04,0x7c,0x04,0x78, /* m */
+    0x7c,0x08,0x04,0x04,0x78, /* n */
+    0x38,0x44,0x44,0x44,0x38, /* o */
+    0x7c,0x14,0x14,0x14,0x08, /* p */
+    0x08,0x14,0x14,0x14,0x7c, /* q */
+    0x7c,0x08,0x04,0x04,0x00, /* r */
+    0x48,0x54,0x54,0x54,0x24, /* s */
+    0x04,0x04,0x3f,0x44,0x44, /* t */
+    0x3c,0x40,0x40,0x20,0x7c, /* u */
+    0x1c,0x20,0x40,0x20,0x1c, /* v */
+    0x3c,0x40,0x30,0x40,0x3c, /* w */
+    0x44,0x28,0x10,0x28,0x44, /* x */
+    0x0c,0x50,0x50,0x50,0x3c, /* y */
+    0x44,0x64,0x54,0x4c,0x44, /* z */
+    0x08,0x36,0x41,0x41,0x00, /* { */
+    0x00,0x00,0x77,0x00,0x00, /* | */
+    0x00,0x41,0x41,0x36,0x08, /* } */
+    0x08,0x08,0x2a,0x1c,0x08, /* <- */
+    0x08,0x1c,0x2a,0x08,0x08, /* -> */
+    0xff,0xff,0xff,0xff,0xff, /*  */
+};
+
+/* System 7x8 */
+const uint8_t au8FontSystem7x8[]= 
+{
+     0,   0,   0,   0,   0,   0,   0, //' '
+     0,   6,  95,  95,   6,   0,   0, //'!'
+     0,   7,   7,   0,   7,   7,   0, //'"'
+    20, 127, 127,  20, 127, 127,  20, //'#'
+    36,  46, 107, 107,  58,  18,   0, //'$'
+    70, 102,  48,  24,  12, 102,  98, //'%'
+    48, 122,  79,  93,  55, 122,  72, //'&'
+     4,   7,   3,   0,   0,   0,   0, //'''
+     0,  28,  62,  99,  65,   0,   0, //'('
+     0,  65,  99,  62,  28,   0,   0, //')'
+     8,  42,  62,  28,  28,  62,  42, //'*'
+     8,   8,  62,  62,   8,   8,   0, //'+'
+     0, 128, 224,  96,   0,   0,   0, //','
+     8,   8,   8,   8,   8,   8,   0, //'-'
+     0,   0,  96,  96,   0,   0,   0, //'.'
+    96,  48,  24,  12,   6,   3,   1, //'/'
+    62, 127, 113,  89,  77, 127,  62, //'0'
+    64,  66, 127, 127,  64,  64,   0, //'1'
+    98, 115,  89,  73, 111, 102,   0, //'2'
+    34,  99,  73,  73, 127,  54,   0, //'3'
+    24,  28,  22,  83, 127, 127,  80, //'4'
+    39, 103,  69,  69, 125,  57,   0, //'5'
+    60, 126,  75,  73, 121,  48,   0, //'6'
+     3,   3, 113, 121,  15,   7,   0, //'7'
+    54, 127,  73,  73, 127,  54,   0, //'8'
+     6,  79,  73, 105,  63,  30,   0, //'9'
+     0,   0, 102, 102,   0,   0,   0, //':'
+     0, 128, 230, 102,   0,   0,   0, //';'
+     8,  28,  54,  99,  65,   0,   0, //'<'
+    36,  36,  36,  36,  36,  36,   0, //'='
+     0,  65,  99,  54,  28,   8,   0, //'>'
+     2,   3,  81,  89,  15,   6,   0, //'?'
+    62, 127,  65,  93,  93,  31,  30, //'@'
+    124,126,  19,  19, 126, 124,   0, //'A'
+    65, 127, 127,  73,  73, 127,  54, //'B'
+    28,  62,  99,  65,  65,  99,  34, //'C'
+    65, 127, 127,  65,  99,  62,  28, //'D'
+    65, 127, 127,  73,  93,  65,  99, //'E'
+    65, 127, 127,  73,  29,   1,   3, //'F'
+    28,  62,  99,  65,  81, 115, 114, //'G'
+    127,127,   8,   8, 127, 127,   0, //'H'
+     0,  65, 127, 127,  65,   0,   0, //'I'
+    48, 112,  64,  65, 127,  63,   1, //'J'
+    65, 127, 127,   8,  28, 119,  99, //'K'
+    65, 127, 127,  65,  64,  96, 112, //'L'
+    127,127,  14,  28,  14, 127, 127, //'M'
+    127,127,   6,  12,  24, 127, 127, //'N'
+    28,  62,  99,  65,  99,  62,  28, //'O'
+    65, 127, 127,  73,   9,  15,   6, //'P'
+    30,  63,  33, 113, 127,  94,   0, //'Q'
+    65, 127, 127,   9,  25, 127, 102, //'R'
+    38, 111,  77,  89, 115,  50,   0, //'S'
+     3,  65, 127, 127,  65,   3,   0, //'T'
+    127,127,  64,  64, 127, 127,   0, //'U'
+    31,  63,  96,  96,  63,  31,   0, //'V'
+    127,127,  48,  24,  48, 127, 127, //'W'
+    67, 103,  60,  24,  60, 103,  67, //'X'
+     7,  79, 120, 120,  79,   7,   0, //'Y'
+    71,  99, 113,  89,  77, 103, 115, //'Z'
+     0, 127, 127,  65,  65,   0,   0, //'['
+     1,   3,   6,  12,  24,  48,  96, //'\'
+     0,  65,  65, 127, 127,   0,   0, //']'
+     8,  12,   6,   3,   6,  12,   8, //'^'
+    128,128, 128, 128, 128, 128, 128, //'_'
+     0,   0,   3,   7,   4,   0,   0, //'`'
+    32, 116,  84,  84,  60, 120,  64, //'a'
+    65, 127,  63,  72,  72, 120,  48, //'b'
+    56, 124,  68,  68, 108,  40,   0, //'c'
+    48, 120,  72,  73,  63, 127,  64, //'d'
+    56, 124,  84,  84,  92,  24,   0, //'e'
+    72, 126, 127,  73,   3,   2,   0, //'f'
+    56, 188, 164, 164, 252, 120,   0, //'g'
+    65, 127, 127,   8,   4, 124, 120, //'h'
+     0,  68, 125, 125,  64,   0,   0, //'i'
+    96, 224, 128, 128, 253, 125,   0, //'j'
+    65, 127, 127,  16,  56, 108,  68, //'k'
+     0,  65, 127, 127,  64,   0,   0, //'l'
+    120,124,  28,  56,  28, 124, 120, //'m'
+    124,124,   4,   4, 124, 120,   0, //'n'
+    56, 124,  68,  68, 124,  56,   0, //'o'
+    0,  252, 252, 164,  36,  60,  24, //'p'
+    24,  60,  36, 164, 248, 252, 132, //'q'
+    68, 124, 120,  76,   4,  28,  24, //'r'
+    72,  92,  84,  84, 116,  36,   0, //'s'
+     0,   4,  62, 127,  68,  36,   0, //'t'
+    60, 124,  64,  64,  60, 124,  64, //'u'
+    28,  60,  96,  96,  60,  28,   0, //'v'
+    60, 124, 112,  56, 112, 124,  60, //'w'
+    68, 108,  56,  16,  56, 108,  68, //'x'
+    60, 188, 160, 160, 252, 124,   0, //'y'
+    76, 100, 116,  92,  76, 100,   0, //'z'
+     8,   8,  62, 119,  65,  65,   0, //'{'
+     0,   0,   0, 119, 119,   0,   0, //'|'
+    65,  65, 119,  62,   8,   8,   0, //'}'
+     2,   3,   1,   3,   2,   3,   1, //'~'
+    255,129, 129, 129, 129, 129, 255, //''
+    14, 159, 145, 177, 251,  74,   0 //'�'
+};
+  
+/* 8x8 Normal */
+const uint8_t au8Font8x8[]= {
+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,       // ASCII -  32
+    0x00,0x00,0x00,0x5F,0x5F,0x00,0x00,0x00,       // ASCII -  33
+    0x00,0x00,0x03,0x07,0x00,0x07,0x03,0x00,       // ASCII -  34
+    0x00,0x10,0x74,0x1C,0x77,0x1C,0x17,0x04,       // ASCII -  35
+    0x00,0x24,0x2E,0x2A,0x7F,0x2A,0x3A,0x10,       // ASCII -  36
+    0x00,0x4C,0x6A,0x76,0x1A,0x6A,0x56,0x33,       // ASCII -  37
+    0x00,0x30,0x7A,0x4F,0x5D,0x37,0x7A,0x48,       // ASCII -  38
+    0x00,0x00,0x04,0x07,0x03,0x00,0x00,0x00,       // ASCII -  39
+    0x00,0x00,0x00,0x1C,0x3E,0x63,0x41,0x00,       // ASCII -  40
+    0x00,0x00,0x41,0x63,0x3E,0x1C,0x00,0x00,       // ASCII -  41
+    0x00,0x08,0x2A,0x3E,0x1C,0x3E,0x2A,0x08,       // ASCII -  42
+    0x00,0x08,0x08,0x3E,0x3E,0x08,0x08,0x00,       // ASCII -  43
+    0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,       // ASCII -  44
+    0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00,       // ASCII -  45
+    0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,       // ASCII -  46
+    0x00,0x60,0x30,0x18,0x0C,0x06,0x03,0x01,       // ASCII -  47
+    0x00,0x1C,0x3E,0x61,0x43,0x3E,0x1C,0x00,       // ASCII -  48
+    0x00,0x00,0x44,0x7F,0x7F,0x40,0x00,0x00,       // ASCII -  49
+    0x00,0x46,0x67,0x71,0x59,0x4F,0x66,0x00,       // ASCII -  50
+    0x00,0x22,0x63,0x49,0x4D,0x7F,0x32,0x00,       // ASCII -  51
+    0x00,0x18,0x1C,0x52,0x7F,0x7F,0x50,0x00,       // ASCII -  52
+    0x00,0x2F,0x6F,0x45,0x45,0x7D,0x39,0x00,       // ASCII -  53
+    0x00,0x3C,0x7E,0x4B,0x49,0x79,0x30,0x00,       // ASCII -  54
+    0x00,0x07,0x43,0x71,0x7D,0x0F,0x03,0x00,       // ASCII -  55
+    0x00,0x36,0x7F,0x4D,0x59,0x7F,0x36,0x00,       // ASCII -  56
+    0x00,0x06,0x4F,0x49,0x69,0x3F,0x1E,0x00,       // ASCII -  57
+    0x00,0x00,0x00,0x66,0x66,0x00,0x00,0x00,       // ASCII -  58
+    0x00,0x00,0x00,0x66,0x66,0x00,0x00,0x00,       // ASCII -  59
+    0x00,0x00,0x08,0x1C,0x36,0x63,0x41,0x00,       // ASCII -  60
+    0x00,0x14,0x14,0x14,0x14,0x14,0x14,0x00,       // ASCII -  61
+    0x00,0x00,0x41,0x63,0x36,0x1C,0x08,0x00,       // ASCII -  62
+    0x00,0x02,0x07,0x51,0x59,0x0F,0x06,0x00,       // ASCII -  63
+    0x00,0x3E,0x41,0x5D,0x55,0x5D,0x51,0x1E,       // ASCII -  64
+    0x00,0x40,0x70,0x1D,0x17,0x1F,0x78,0x60,       // ASCII -  65
+    0x00,0x41,0x7F,0x7F,0x49,0x4F,0x7E,0x30,       // ASCII -  66
+    0x00,0x1C,0x3E,0x63,0x41,0x41,0x42,0x27,       // ASCII -  67
+    0x00,0x41,0x7F,0x7F,0x41,0x63,0x3E,0x1C,       // ASCII -  68
+    0x00,0x41,0x7F,0x7F,0x49,0x5D,0x41,0x63,       // ASCII -  69
+    0x00,0x41,0x7F,0x7F,0x49,0x1D,0x01,0x03,       // ASCII -  70
+    0x00,0x1C,0x3E,0x63,0x41,0x51,0x72,0x77,       // ASCII -  71
+    0x00,0x7F,0x7F,0x08,0x08,0x7F,0x7F,0x00,       // ASCII -  72
+    0x00,0x00,0x41,0x7F,0x7F,0x41,0x00,0x00,       // ASCII -  73
+    0x00,0x30,0x70,0x41,0x41,0x7F,0x3F,0x01,       // ASCII -  74
+    0x00,0x7F,0x7F,0x08,0x1C,0x77,0x63,0x41,       // ASCII -  75
+    0x00,0x41,0x7F,0x7F,0x41,0x40,0x60,0x70,       // ASCII -  76
+    0x00,0x7F,0x7E,0x0C,0x18,0x0C,0x7E,0x7F,       // ASCII -  77
+    0x00,0x7F,0x7E,0x0C,0x18,0x30,0x7F,0x7F,       // ASCII -  78
+    0x00,0x1C,0x3E,0x63,0x41,0x63,0x3E,0x1C,       // ASCII -  79
+    0x00,0x41,0x7F,0x7F,0x49,0x09,0x0F,0x06,       // ASCII -  80
+    0x00,0x1C,0x3E,0x63,0x51,0x63,0x3E,0x1C,       // ASCII -  81
+    0x00,0x7F,0x7F,0x09,0x19,0x7F,0x66,0x40,       // ASCII -  82
+    0x00,0x66,0x6F,0x4D,0x59,0x7B,0x33,0x00,       // ASCII -  83
+    0x00,0x03,0x41,0x7F,0x7F,0x41,0x03,0x00,       // ASCII -  84
+    0x00,0x3F,0x7F,0x40,0x40,0x40,0x7F,0x3F,       // ASCII -  85
+    0x00,0x03,0x0F,0x3D,0x70,0x1D,0x07,0x01,       // ASCII -  86
+    0x00,0x0F,0x7F,0x30,0x1C,0x30,0x7F,0x0F,       // ASCII -  87
+    0x00,0x63,0x77,0x1C,0x1C,0x77,0x63,0x00,       // ASCII -  88
+    0x01,0x03,0x47,0x7C,0x78,0x47,0x03,0x01,       // ASCII -  89
+    0x00,0x67,0x73,0x59,0x4D,0x67,0x73,0x00,       // ASCII -  90
+    0x00,0x00,0x00,0x7F,0x7F,0x41,0x41,0x00,       // ASCII -  91
+    0x00,0x01,0x03,0x06,0x0C,0x18,0x30,0x60,       // ASCII -  92
+    0x00,0x00,0x41,0x41,0x7F,0x7F,0x00,0x00,       // ASCII -  93
+    0x00,0x00,0x04,0x06,0x03,0x06,0x04,0x00,       // ASCII -  94
+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,       // ASCII -  95
+    0x00,0x00,0x01,0x03,0x06,0x04,0x00,0x00,       // ASCII -  96
+    0x00,0x68,0x6C,0x54,0x54,0x3C,0x78,0x40,       // ASCII -  97
+    0x00,0x41,0x7F,0x3F,0x6C,0x44,0x7C,0x38,       // ASCII -  98
+    0x00,0x38,0x7C,0x44,0x44,0x6C,0x2C,0x00,       // ASCII -  99
+    0x00,0x38,0x7C,0x44,0x49,0x3F,0x7F,0x40,       // ASCII - 100
+    0x00,0x38,0x7C,0x54,0x54,0x5C,0x58,0x00,       // ASCII - 101
+    0x00,0x00,0x48,0x7E,0x7F,0x49,0x0B,0x02,       // ASCII - 102
+    0x00,0x48,0x7C,0x34,0x34,0x2C,0x68,0x44,       // ASCII - 103
+    0x00,0x41,0x7F,0x7F,0x08,0x04,0x7C,0x78,       // ASCII - 104
+    0x00,0x00,0x44,0x7D,0x7D,0x40,0x00,0x00,       // ASCII - 105
+    0x00,0x60,0x60,0x04,0x7D,0x7D,0x00,0x00,       // ASCII - 106
+    0x00,0x41,0x7F,0x7F,0x10,0x78,0x6C,0x44,       // ASCII - 107
+    0x00,0x00,0x41,0x7F,0x7F,0x40,0x00,0x00,       // ASCII - 108
+    0x00,0x7C,0x7C,0x0C,0x78,0x0C,0x7C,0x78,       // ASCII - 109
+    0x00,0x44,0x7C,0x7C,0x08,0x04,0x7C,0x78,       // ASCII - 110
+    0x00,0x38,0x7C,0x44,0x44,0x7C,0x38,0x00,       // ASCII - 111
+    0x00,0x04,0x7C,0x78,0x24,0x24,0x3C,0x18,       // ASCII - 112
+    0x00,0x18,0x3C,0x24,0x24,0x78,0x7C,0x00,       // ASCII - 113
+    0x00,0x44,0x7C,0x78,0x4C,0x04,0x1C,0x18,       // ASCII - 114
+    0x00,0x48,0x5C,0x5C,0x74,0x74,0x24,0x00,       // ASCII - 115
+    0x00,0x00,0x04,0x3E,0x7F,0x44,0x24,0x00,       // ASCII - 116
+    0x00,0x3C,0x7C,0x40,0x40,0x3C,0x7C,0x40,       // ASCII - 117
+    0x00,0x04,0x1C,0x3C,0x60,0x30,0x1C,0x04,       // ASCII - 118
+    0x00,0x1C,0x7C,0x30,0x1C,0x30,0x7C,0x1C,       // ASCII - 119
+    0x00,0x44,0x6C,0x3C,0x10,0x78,0x6C,0x44,       // ASCII - 120
+    0x00,0x44,0x4C,0x1C,0x70,0x64,0x1C,0x0C,       // ASCII - 121
+    0x00,0x4C,0x64,0x74,0x5C,0x4C,0x64,0x00,       // ASCII - 122
+    0x00,0x08,0x08,0x3E,0x77,0x41,0x41,0x00,       // ASCII - 123
+    0x00,0x00,0x00,0x7F,0x7F,0x00,0x00,0x00,       // ASCII - 124
+    0x00,0x41,0x41,0x77,0x3E,0x08,0x08,0x00,       // ASCII - 125
+    0x00,0x02,0x01,0x01,0x03,0x02,0x02,0x01,       // ASCII - 126
+    0x00,0x60,0x78,0x4E,0x47,0x5E,0x78,0x60,       // ASCII - 127
+    0x00,0x1C,0x3E,0x23,0x41,0x41,0x42,0x27,       // ASCII - 128
+    0x00,0x3D,0x7D,0x40,0x41,0x3D,0x7C,0x40,       // ASCII - 129
+};
+
+/* 8x8 Thin */
+const uint8_t au8Font8x8Thin[]= {
+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x00,0x00,0x00,0x5F,0x00,0x00,0x00,0x00,
+    0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+    0x00,0x14,0x7F,0x14,0x14,0x7F,0x14,0x00,
+    0x00,0x24,0x2A,0x6B,0x6B,0x2A,0x12,0x00,
+    0x00,0x46,0x26,0x10,0x08,0x64,0x62,0x00,
+    0x30,0x4A,0x45,0x4D,0x32,0x48,0x48,0x00,
+    0x00,0x00,0x04,0x03,0x00,0x00,0x00,0x00,
+    0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00,
+    0x00,0x00,0x41,0x22,0x1C,0x00,0x00,0x00,
+    0x08,0x2A,0x1C,0x1C,0x1C,0x2A,0x08,0x00,
+    0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00,
+    0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,
+    0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00,
+    0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,
+    0x00,0x40,0x20,0x10,0x08,0x04,0x02,0x00,
+    0x00,0x3E,0x61,0x51,0x49,0x45,0x3E,0x00,
+    0x00,0x44,0x42,0x7F,0x40,0x40,0x00,0x00,
+    0x00,0x62,0x51,0x51,0x49,0x49,0x66,0x00,
+    0x00,0x22,0x41,0x49,0x49,0x49,0x36,0x00,
+    0x10,0x18,0x14,0x52,0x7F,0x50,0x10,0x00,
+    0x00,0x27,0x45,0x45,0x45,0x45,0x39,0x00,
+    0x00,0x3C,0x4A,0x49,0x49,0x49,0x30,0x00,
+    0x00,0x03,0x01,0x71,0x09,0x05,0x03,0x00,
+    0x00,0x36,0x49,0x49,0x49,0x49,0x36,0x00,
+    0x00,0x06,0x49,0x49,0x49,0x29,0x1E,0x00,
+    0x00,0x00,0x00,0x66,0x00,0x00,0x00,0x00,
+    0x00,0x00,0x80,0x66,0x00,0x00,0x00,0x00,
+    0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00,
+    0x00,0x24,0x24,0x24,0x24,0x24,0x24,0x00,
+    0x00,0x00,0x00,0x41,0x22,0x14,0x08,0x00,
+    0x00,0x02,0x01,0x01,0x51,0x09,0x06,0x00,
+    0x00,0x3E,0x41,0x5D,0x55,0x55,0x1E,0x00,
+    0x00,0x7C,0x12,0x11,0x11,0x12,0x7C,0x00,
+    0x00,0x41,0x7F,0x49,0x49,0x49,0x36,0x00,
+    0x00,0x1C,0x22,0x41,0x41,0x41,0x22,0x00,
+    0x00,0x41,0x7F,0x41,0x41,0x22,0x1C,0x00,
+    0x00,0x41,0x7F,0x49,0x5D,0x41,0x63,0x00,
+    0x00,0x41,0x7F,0x49,0x1D,0x01,0x03,0x00,
+    0x00,0x1C,0x22,0x41,0x51,0x51,0x72,0x00,
+    0x00,0x7F,0x08,0x08,0x08,0x08,0x7F,0x00,
+    0x00,0x00,0x41,0x7F,0x41,0x00,0x00,0x00,
+    0x00,0x30,0x40,0x40,0x41,0x3F,0x01,0x00,
+    0x00,0x41,0x7F,0x08,0x14,0x22,0x41,0x40,
+    0x00,0x41,0x7F,0x41,0x40,0x40,0x60,0x00,
+    0x00,0x7F,0x01,0x02,0x04,0x02,0x01,0x7F,
+    0x00,0x7F,0x01,0x02,0x04,0x08,0x7F,0x00,
+    0x00,0x3E,0x41,0x41,0x41,0x41,0x3E,0x00,
+    0x00,0x41,0x7F,0x49,0x09,0x09,0x06,0x00,
+    0x00,0x1E,0x21,0x21,0x31,0x21,0x5E,0x40,
+    0x00,0x41,0x7F,0x49,0x19,0x29,0x46,0x00,
+    0x00,0x26,0x49,0x49,0x49,0x49,0x32,0x00,
+    0x00,0x03,0x01,0x41,0x7F,0x41,0x01,0x03,
+    0x00,0x3F,0x40,0x40,0x40,0x40,0x3F,0x00,
+    0x00,0x0F,0x10,0x20,0x40,0x20,0x10,0x0F,
+    0x00,0x3F,0x40,0x40,0x38,0x40,0x40,0x3F,
+    0x00,0x41,0x22,0x14,0x08,0x14,0x22,0x41,
+    0x00,0x01,0x02,0x44,0x78,0x44,0x02,0x01,
+    0x00,0x43,0x61,0x51,0x49,0x45,0x43,0x61,
+    0x00,0x7F,0x41,0x41,0x41,0x00,0x00,0x00,
+    0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x00,
+    0x00,0x41,0x41,0x41,0x7F,0x00,0x00,0x00,
+    0x08,0x04,0x02,0x01,0x02,0x04,0x08,0x00,
+    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+    0x00,0x00,0x00,0x03,0x04,0x00,0x00,0x00,
+    0x00,0x20,0x54,0x54,0x54,0x54,0x78,0x40,
+    0x00,0x01,0x7F,0x30,0x48,0x48,0x48,0x30,
+    0x00,0x38,0x44,0x44,0x44,0x44,0x28,0x00,
+    0x00,0x30,0x48,0x48,0x48,0x31,0x7F,0x40,
+    0x00,0x38,0x54,0x54,0x54,0x54,0x18,0x00,
+    0x00,0x00,0x48,0x7E,0x49,0x01,0x02,0x00,
+    0x00,0x98,0xA4,0xA4,0xA4,0xA4,0x78,0x04,
+    0x00,0x41,0x7F,0x08,0x04,0x04,0x78,0x00,
+    0x00,0x00,0x44,0x7D,0x40,0x00,0x00,0x00,
+    0x00,0x60,0x80,0x80,0x80,0x84,0x7D,0x00,
+    0x00,0x01,0x7F,0x10,0x28,0x44,0x40,0x00,
+    0x00,0x00,0x41,0x7F,0x40,0x00,0x00,0x00,
+    0x00,0x7C,0x04,0x04,0x78,0x04,0x04,0x78,
+    0x00,0x7C,0x08,0x04,0x04,0x04,0x78,0x00,
+    0x00,0x38,0x44,0x44,0x44,0x44,0x38,0x00,
+    0x00,0x84,0xFC,0x98,0x24,0x24,0x18,0x00,
+    0x00,0x18,0x24,0x24,0x98,0xFC,0x84,0x00,
+    0x00,0x44,0x7C,0x48,0x04,0x04,0x18,0x00,
+    0x00,0x48,0x54,0x54,0x54,0x54,0x24,0x00,
+    0x00,0x04,0x04,0x3F,0x44,0x44,0x20,0x00,
+    0x00,0x3C,0x40,0x40,0x40,0x20,0x7C,0x00,
+    0x00,0x0C,0x10,0x20,0x40,0x20,0x10,0x0C,
+    0x00,0x3C,0x40,0x40,0x38,0x40,0x40,0x3C,
+    0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00,
+    0x00,0x9C,0xA0,0xA0,0xA0,0xA0,0x7C,0x00,
+    0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00,
+    0x00,0x08,0x08,0x36,0x41,0x41,0x00,0x00,
+    0x00,0x00,0x00,0x77,0x00,0x00,0x00,0x00,
+    0x00,0x00,0x41,0x41,0x36,0x08,0x08,0x00,
+    0x00,0x02,0x01,0x01,0x02,0x02,0x01,0x00,
+    0x00,0x70,0x48,0x44,0x42,0x44,0x48,0x70,
+    0x00,0x0E,0x91,0x91,0xB1,0xB1,0x4A,0x00,
+    0x00,0x3A,0x40,0x40,0x40,0x7A,0x40,0x00,
+    0x00,0x38,0x54,0x54,0x55,0x55,0x18,0x00,
+    0x00,0x22,0x55,0x55,0x55,0x79,0x42,0x00,
+    0x00,0x21,0x54,0x54,0x54,0x78,0x41,0x00,
+    0x00,0x20,0x55,0x55,0x54,0x78,0x40,0x00,
+    0x00,0x20,0x54,0x55,0x54,0x78,0x40,0x00,
+    0x00,0x18,0x24,0xA4,0xA4,0xE4,0x40,0x00,
+    0x00,0x3A,0x55,0x55,0x55,0x55,0x1A,0x00,
+    0x00,0x39,0x54,0x54,0x54,0x54,0x19,0x00,
+    0x00,0x38,0x55,0x55,0x54,0x54,0x18,0x00,
+    0x00,0x00,0x01,0x44,0x7C,0x41,0x00,0x00,
+    0x02,0x01,0x45,0x7D,0x41,0x01,0x02,0x00,
+    0x00,0x00,0x01,0x45,0x7C,0x40,0x00,0x00,
+    0x00,0x79,0x14,0x12,0x12,0x14,0x79,0x00,
+    0x00,0x70,0x28,0x2B,0x2B,0x28,0x70,0x00,
+    0x00,0x44,0x7C,0x54,0x55,0x45,0x00,0x00,
+    0x00,0x20,0x54,0x54,0x58,0x38,0x54,0x54,
+    0x00,0x7C,0x0A,0x09,0x09,0x7F,0x49,0x49,
+    0x00,0x30,0x4A,0x49,0x49,0x4A,0x30,0x00,
+    0x00,0x32,0x48,0x48,0x48,0x48,0x32,0x00,
+    0x00,0x30,0x49,0x4A,0x48,0x48,0x30,0x00,
+    0x00,0x38,0x42,0x41,0x41,0x42,0x38,0x00,
+    0x00,0x38,0x41,0x42,0x40,0x40,0x38,0x00,
+    0x00,0x1A,0xA0,0xA0,0xA0,0xA0,0x7A,0x00,
+    0x00,0x19,0x24,0x42,0x42,0x24,0x19,0x00,
+    0x00,0x3D,0x40,0x40,0x40,0x40,0x3D,0x00,
+    0x00,0x18,0x24,0x24,0xE7,0x24,0x24,0x00,
+    0x00,0x68,0x5E,0x49,0x41,0x42,0x20,0x00,
+    0x00,0x15,0x16,0x7C,0x16,0x15,0x00,0x00,
+    0x81,0xFF,0x85,0x05,0x17,0xFA,0x90,0x50,
+    0x40,0x88,0x88,0x7F,0x09,0x09,0x02,0x00,
+    0x00,0x20,0x54,0x54,0x55,0x79,0x40,0x00,
+};
diff --git a/reform2-lpc-fw/src/drivers/displays/smallfonts.h b/reform2-lpc-fw/src/drivers/displays/smallfonts.h
new file mode 100644
index 0000000000000000000000000000000000000000..e63e80594eb73b55e379a79edbbaa836864ec05a
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/displays/smallfonts.h
@@ -0,0 +1,76 @@
+/**************************************************************************/
+/*! 
+    @file     smallfonts.h
+    @author   K. Townsend (microBuilder.eu)
+    @date     22 March 2010
+    @version  0.10
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __SMALLFONTS_H_
+#define __SMALLFONTS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Partially based on original code for the KS0108 by Stephane Rey */
+/* Current version by Kevin Townsend */
+/* Last Updated: 12 May 2009 */
+
+#include "projectconfig.h"
+
+struct FONT_DEF 
+{
+    uint8_t u8Width;     	        /* Character width for storage         */
+    uint8_t u8Height;  	            /* Character height for storage        */
+    uint8_t u8FirstChar;            /* The first character available       */
+    uint8_t u8LastChar;             /* The last character available        */
+    const uint8_t *au8FontTable;    /* Font table start address in memory  */
+};
+
+extern const struct FONT_DEF Font_System3x6;
+extern const struct FONT_DEF Font_System5x8;
+extern const struct FONT_DEF Font_System7x8;
+extern const struct FONT_DEF Font_8x8;
+extern const struct FONT_DEF Font_8x8Thin;
+
+extern const uint8_t au8FontSystem3x6[];
+extern const uint8_t au8FontSystem5x8[];
+extern const uint8_t au8FontSystem7x8[];
+extern const uint8_t au8Font8x8[];
+extern const uint8_t au8Font8x8Thin[];
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/README.md b/reform2-lpc-fw/src/drivers/filters/iir/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..101c7e5030612058f6c4333d0bf6cd7c495d4a29
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/iir/README.md
@@ -0,0 +1,102 @@
+# Infinite Impulse Response (IIR) Filter #
+
+This simple IIR implementation is a basic single-pole low-pass filter. It's a 'low pass' filter since it attempts to filter out short term fluctuations, giving more weight to the longer-term average. You can use it to 'smooth out' fluctuating sensor data by slowing the response to new signals. It operates on the same principle as an RC filter in HW -- numerous samples are required before the output of the filter shifts to reach the 'new' value, gradual shifting up or down towards any newly integrated values.
+
+You can configure the filter by adjusting the 'alpha' value, which controls the delay or amount of time required for new signals to be integrated into the current output value.
+
+## What is the Effect of 'Alpha' on the IIR Output? ##
+
+A small alpha will result in a slower response from the filter (more samples are required to change the current average), whereas a larger alpha will cause the average to respond more quickly to changes in the signal, at the expense of keeping more 'noise' in the signal.
+
+You can see this effect in the charts below (generated with iir_i_response_test.py).  Setting the alpha value lower pushes the response curve further out, meaning more samples are required to reach any new values that are sent into the filter.
+
+In the charts below, we start with a value of 0, and the same new value is added into the IIR filter until we reach 99.9% of the value with the IIR output.
+
+(**Note**: These charts are a bit 'wobbly' because the output is based on the integer version of the filter ... the floating point version provides more precision and linearity at the expense of more work for the MCU.)
+
+![Integer IIR Alpha 128](images/integer_responsecurve_alpha_128.png?raw=true)
+![Integer IIR Alpha 64](images/integer_responsecurve_alpha_64.png?raw=true)
+![Integer IIR Alpha 32](images/integer_responsecurve_alpha_32.png?raw=true)
+
+As you can see above, a larger alpha means that new values are integrated more quickly so the filter 'responds' more quickly, but there is also less smoothing going on due to the fast response.  All the magic in any filter is finding the right values for variables like alpha that meet your needs!
+
+## Is IIR the Right Filter For Me? ##
+
+An IIR filter is very memory efficient, and is excellent for smoothing out noisy data, but it does have some limitations and drawbacks.
+
+One big advantage of a simple IIR filter is that it requires very little memory. This filter keeps a single 'running average' value, which allows a much smaller memory footprint than some other filters. 
+
+This also presents a potential problem, though, since any errors that are introduced in that single 'running average' -- floating point precision losses, etc. -- also get multiplied over time! After running 10,000 samples through the IIR filter, we have to take into account the effect of 10,000 accumulated errors, which may or may not be an issue for you.
+
+Accumulated errors are generally only an issue over large, long-running sample sets, but it's important to keep this in mind when deciding which filter(s) to use with your data.
+
+Two other tradeoffs of IIR filters is that they aren't 'phase stable', and some signal attentuation also inevitably occurs with stronger alpha values.
+
+What this means is that using a high alpha (meaning a smaller number!) will very effectively smooth your data out, but it will also phase shift further and further to the right, and you will no longer have the same peak to peak range (or 'amplitude') of your source data.
+
+You can see this in the following charts generated with the **iir\_i\_noisysine\_test.py** Python script included in this folder.  As the alpha value lowers, the effect of the filter increases and the data is much 'smoother', but it starts to shift to be out of phase with the source signal (in blue), and you lose some amplitude.
+
+![Integer IIR Alpha 128](images/integer_sinewave_alpha_128.png?raw=true)
+![Integer IIR Alpha 64](images/integer_sinewave_alpha_64.png?raw=true)
+![Integer IIR Alpha 32](images/integer_sinewave_alpha_32.png?raw=true)
+![Integer IIR Alpha 16](images/integer_sinewave_alpha_16.png?raw=true)
+![Integer IIR Alpha 8](images/integer_sinewave_alpha_8.png?raw=true)
+
+All of the magic is, of course, in finding the right numbers for your needs, and if phase shift is an issue in your situation, the IIR filter isn't a very good choice (which is why so many different DSP filters exist)!
+
+## Which Filter Version Should I Use (int32_t or float)? ##
+
+Two versions of this filter are included, one that uses single-precision floating point values (iir_f.c), and another that uses 32-bit signed integers (iir_i.c).
+
+There are advantages and tradeoffs to both of these implementations that you should be aware of when using them!
+
+### Integer Advantages/Limitations ###
+
+The advantage of the integer version is that it will be much faster ... particularly if you use an ^2 alpha value -- 2, 4, 8, 16, 32, 64 or 128 -- since this allows the compiler to replace a division operation with a simple (single-cycle) shift.
+
+The disadvantage is that at smaller alpha values (<24 or so) the filter will never reach 99.9% of the new value, regardless of how many samples are presented, and the output isn't nearly as smooth as the floating point version.  As such, the integer version is really only appropriate for higher alpha values and quicker responses.
+
+### Floating Point Advantages/Limitations ###
+
+The major advantage of the floating point version of this filter is that you have far more range with the alpha values, and you can always reach 99.9% (or more) of any new value if you run the filter over enough samples.  
+
+The smallest equivalent alpha value in the integer version that reaches 99.9% over time is 24 (out of 255), which equals about 0.09375 in the floating point alpha notation of 0..1.0.
+
+With the floating point version, you can easily use a very small alpha value, such as 0.001, and still get a nice response curve that eventually hits 99.9% of the new value.
+
+You can confirm this by running the two python scripts, iir_i_noisysine_test.py (for integer math) and iir_f_noisysine_test.py (for floating point math).
+
+The floating point version is run with an alpha of 0.015625, which corresponds to an alpha of 4 in the integer version (4/256).  As you can see in the two images below, the limitations of the integer math with a small alpha mean that it peaks at around 93% of the new value, whereas the floating point version has a smooth curve and hits 99.9% of the new value at around 439 samples:
+
+![Integer IIR Response - Alpha 0.015625](images/integer_response_alpha_4.png?raw=true)
+![Floaing Points IIR Response - Alpha 0.015625](images/float_response_alpha_0_015625.png?raw=true)
+
+This advantage, of course, comes at a price, and the floating point math takes more clock cycles for the MCU to calculate, and floating point values are inherently 'lossy'.  
+
+The choice between integer and floating point math will ultimately be based on your requirements, and how 'heavy' a filter you require, but you can use the python scripts in this folder to test different values on both integer and floating point implementations of the filter.
+
+## How Do I Use This Code? ##
+
+After declaring a placeholder **iir\_f\_t** (for floating point math) or **iir\_i\_t** (for integer math) object, we need to call the init function and supply a reference to our IIR placeholder as well as an appropriate alpha value.
+
+For the floating point version, the alpha must be between 0 and 1.0F, and for the integer version it must be between 0 and 255.
+
+We'll use the floating point version below as an example.
+```
+  iir_f_t iir;
+  iir_f_init(&iir, 0.01);
+```
+After initialising the filter above, you continually add in your samples via the **iir\_f\_add** function, and read the current 'iir.avg' value whenever you need it:
+```
+  iir_f_add(&iir, 10.5F);
+  iir_f_add(&iir, 10.76F);
+  iir_f_add(&iir, 10.69F);
+
+  printf("SAMPLES  : %d \n", iir.k);
+  printf("AVG      : %f \n", iir.avg);
+  printf("\n");
+```
+
+## Source ##
+
+Thanks to [Robert Davidson](http://www.ambientsensors.com/about/) for suggesting this filter.
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/iir_f.c b/reform2-lpc-fw/src/drivers/filters/iir/iir_f.c
new file mode 100644
index 0000000000000000000000000000000000000000..f0c865323f2fd0c7a6ffcfd5b97595fbc5713c5e
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/iir/iir_f.c
@@ -0,0 +1,76 @@
+/**************************************************************************/
+/*!
+    @file     iir_f.c
+    @brief    A memory efficient single pole low pass filter using float
+              values
+
+    @code
+    iir_f_t iir;
+
+    iir_f_init(&iir, 0.01);
+
+    iir_f_add(&iir, 10);
+    iir_f_add(&iir, 20);
+    iir_f_add(&iir, 30);
+    iir_f_add(&iir, 35);
+
+    printf("SAMPLES  : %d       \n", iir.k);
+    printf("AVG      : %f       \n", iir.avg);
+    printf("\n");
+
+    @endcode
+ */
+/**************************************************************************/
+#include "iir_f.h"
+
+/**************************************************************************/
+/*!
+     @brief Initialises the iir_f_t instance
+
+     @param[in]  iir
+                 Pointer to the iir_f_t instances
+     @param[in]  alpha
+                 alpha value to adjust the 'effect' of the filter
+                 (smaller value = slower response).
+                 
+     @note       An alpha of 1.0 effectively disables the filter (no
+                 filtering occurs!), and an alpha of 0.0 is infinitely
+                 'heavy', in the sense that the original value will never
+                 change.
+*/
+/**************************************************************************/
+void iir_f_init(iir_f_t *iir, float alpha)
+{
+  if (alpha > 1.0F)
+    alpha = 1.0F;
+  if (alpha < 0.0F)
+    alpha = 0.0F;
+    
+  iir->k = 0;
+  iir->alpha = alpha;
+  iir->avg = 0.0F;
+}
+
+/**************************************************************************/
+/*!
+     @brief Adds a new record to the iir_f_t instances
+
+     @param[in]  iir
+                 Pointer to the iir_f_t instances
+     @param[in]  x
+                 Value to insert
+*/
+/**************************************************************************/
+void iir_f_add(iir_f_t *iir, float x)
+{
+  iir->k++;
+  if (1 == iir->k)
+  {
+    iir->avg = x;
+  }
+  else
+  {
+    /* IIR Filter */
+    iir->avg = iir->alpha * x + (1.0 - iir->alpha) * iir->avg;
+  }
+}
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/iir_f.h b/reform2-lpc-fw/src/drivers/filters/iir/iir_f.h
new file mode 100644
index 0000000000000000000000000000000000000000..c0710be9854edce9a9f7d7a1b21249f0b8dd9055
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/iir/iir_f.h
@@ -0,0 +1,29 @@
+/**************************************************************************/
+/*!
+    @file     iir_f.h
+*/
+/**************************************************************************/
+#ifndef __IIR_F_H__
+#define __IIR_F_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+typedef struct iir_f_s
+{
+  float alpha;
+  size_t k;       /**< Sample count */
+  float  avg;
+} iir_f_t;
+
+void  iir_f_init ( iir_f_t *iir, float alpha );
+void  iir_f_add  ( iir_f_t *iir, float x );
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/iir_i.c b/reform2-lpc-fw/src/drivers/filters/iir/iir_i.c
new file mode 100644
index 0000000000000000000000000000000000000000..63e3070f47a01eb0bbdaff3ca7d9669fd7782e16
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/iir/iir_i.c
@@ -0,0 +1,90 @@
+/**************************************************************************/
+/*!
+    @file     iir_i.c
+    @brief    A memory efficient single pole low pass filter using integer
+              values
+
+    @code
+    iir_i_t iir;
+
+    // Initialise the IIR filter with an alpha of 64 (=0.0625)
+    iir_i_init(&iir, 64);
+
+    // Add four samples, with the first sample used at the starting value
+    iir_i_add(&iir, 10);
+    iir_i_add(&iir, 20);
+    iir_i_add(&iir, 30);
+    iir_i_add(&iir, 35);
+
+    printf("SAMPLES  : %d       \n", iir.k);
+    printf("AVG      : %d       \n", iir.avg);
+    printf("\n");
+
+    @endcode
+ */
+/**************************************************************************/
+#include "iir_i.h"
+
+/**************************************************************************/
+/*!
+     @brief Initialises the iir_i_t instance
+
+     @param[in]  iir
+                 Pointer to the iir_i_t instance
+     @param[in]  alpha
+                 8-bit (0..255) alpha value to adjust the 'effect' of the
+                 filter(smaller value = slower response).
+
+     @note       Use a ^2 value for alpha for best results, since the
+                 division operation can be swapped out with a shift.
+
+                 For example:
+
+                 8-bit Alpha  Float equivalent
+                 -----------  ----------------
+                           1  0.00390625
+                           2  0.0078125
+                           4  0.015625
+                           8  0.03125
+                          16  0.0625
+                          32  0.125
+                          64  0.25
+                         128  0.5
+
+     @note       An alpha of 255 effectively disables the filter (no
+                 filtering occurs!), and an alpha of 0 is infinitely
+                 'heavy', in the sense that the original value will never
+                 change.
+*/
+/**************************************************************************/
+void iir_i_init(iir_i_t *iir, uint8_t alpha)
+{
+  iir->k = 0;
+  iir->alpha = alpha;
+  iir->avg = 0;
+}
+
+/**************************************************************************/
+/*!
+     @brief Adds a new record to the iir_i_t instances
+
+     @param[in]  iir
+                 Pointer to the iir_i_t instances
+     @param[in]  x
+                 Value to insert
+*/
+/**************************************************************************/
+void iir_i_add(iir_i_t *iir, int32_t x)
+{
+  int64_t xl = x;     /* Promote to 64-bit to avoid overflow issues */
+  iir->k++;
+  if (1 == iir->k)
+  {
+    iir->avg = x;
+  }
+  else
+  {
+    /* IIR Filter */
+    iir->avg = (int32_t)((xl * iir->alpha + iir->avg * (256 - iir->alpha)) / 256);
+  }
+}
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/iir_i.h b/reform2-lpc-fw/src/drivers/filters/iir/iir_i.h
new file mode 100644
index 0000000000000000000000000000000000000000..22ffe1d2dbb82d8d16d4ce7f58c8b2eee5437a4d
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/iir/iir_i.h
@@ -0,0 +1,29 @@
+/**************************************************************************/
+/*!
+    @file     iir_i.h
+*/
+/**************************************************************************/
+#ifndef __IIR_I_H__
+#define __IIR_I_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+typedef struct iir_i_s
+{
+  uint8_t  alpha;
+  size_t   k;       /**< Sample count */
+  int32_t  avg;
+} iir_i_t;
+
+void  iir_i_init ( iir_i_t *iir, uint8_t alpha );
+void  iir_i_add  ( iir_i_t *iir, int32_t x );
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/iir_u16.c b/reform2-lpc-fw/src/drivers/filters/iir/iir_u16.c
new file mode 100644
index 0000000000000000000000000000000000000000..10f968c3cf497cdb33fcdf75797ea6ce389ceb4b
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/iir/iir_u16.c
@@ -0,0 +1,90 @@
+/**************************************************************************/
+/*!
+    @file     iir_u16.c
+    @brief    A memory efficient single pole low pass filter using integer
+              values
+
+    @code
+    iir_u16_t iir;
+
+    // Initialise the IIR filter with an alpha of 64 (=0.0625)
+    iir_u16_init(&iir, 64);
+
+    // Add four samples, with the first sample used at the starting value
+    iir_u16_add(&iir, 10);
+    iir_u16_add(&iir, 20);
+    iir_u16_add(&iir, 30);
+    iir_u16_add(&iir, 35);
+
+    printf("SAMPLES  : %d       \n", iir.k);
+    printf("AVG      : %d       \n", iir.avg);
+    printf("\n");
+
+    @endcode
+ */
+/**************************************************************************/
+#include "iir_u16.h"
+
+/**************************************************************************/
+/*!
+     @brief Initialises the iir_u16_t instance
+
+     @param[in]  iir
+                 Pointer to the iir_u16_t instance
+     @param[in]  alpha
+                 8-bit (0..255) alpha value to adjust the 'effect' of the
+                 filter(smaller value = slower response).
+
+     @note       Use a ^2 value for alpha for best results, since the
+                 division operation can be swapped out with a shift.
+
+                 For example:
+
+                 8-bit Alpha  Float equivalent
+                 -----------  ----------------
+                           1  0.00390625
+                           2  0.0078125
+                           4  0.015625
+                           8  0.03125
+                          16  0.0625
+                          32  0.125
+                          64  0.25
+                         128  0.5
+
+     @note       An alpha of 255 effectively disables the filter (no
+                 filtering occurs!), and an alpha of 0 is infinitely
+                 'heavy', in the sense that the original value will never
+                 change.
+*/
+/**************************************************************************/
+void iir_u16_init(iir_u16_t *iir, uint8_t alpha)
+{
+  iir->k = 0;
+  iir->alpha = alpha;
+  iir->avg = 0;
+}
+
+/**************************************************************************/
+/*!
+     @brief Adds a new record to the iir_u16_t instances
+
+     @param[in]  iir
+                 Pointer to the iir_u16_t instances
+     @param[in]  x
+                 Value to insert
+*/
+/**************************************************************************/
+void iir_u16_add(iir_u16_t *iir, uint16_t x)
+{
+  uint32_t xl = x;     /* Promote to 32-bit to avoid overflow issues */
+  iir->k++;
+  if (1 == iir->k)
+  {
+    iir->avg = x;
+  }
+  else
+  {
+    /* IIR Filter */
+    iir->avg = (uint16_t)((xl * iir->alpha + iir->avg * (256 - iir->alpha)) / 256);
+  }
+}
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/iir_u16.h b/reform2-lpc-fw/src/drivers/filters/iir/iir_u16.h
new file mode 100644
index 0000000000000000000000000000000000000000..aeec630d77bde71b7a76e0628f6de1bb806f7c60
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/iir/iir_u16.h
@@ -0,0 +1,29 @@
+/**************************************************************************/
+/*!
+    @file     iir_u16.h
+*/
+/**************************************************************************/
+#ifndef __IIR_U16_H__
+#define __IIR_U16_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+typedef struct iir_u16_s
+{
+  uint8_t  alpha;
+  size_t   k;       /**< Sample count */
+  uint16_t avg;
+} iir_u16_t;
+
+void  iir_u16_init ( iir_u16_t *iir, uint8_t alpha );
+void  iir_u16_add  ( iir_u16_t *iir, uint16_t x );
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/images/float_response_alpha_0_015625.png b/reform2-lpc-fw/src/drivers/filters/iir/images/float_response_alpha_0_015625.png
new file mode 100644
index 0000000000000000000000000000000000000000..069757fd010516427bbdd380f30466202de32b67
Binary files /dev/null and b/reform2-lpc-fw/src/drivers/filters/iir/images/float_response_alpha_0_015625.png differ
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/images/integer_response_alpha_4.png b/reform2-lpc-fw/src/drivers/filters/iir/images/integer_response_alpha_4.png
new file mode 100644
index 0000000000000000000000000000000000000000..e5b1b4ec3e303b098bab63324d6b89a63860b697
Binary files /dev/null and b/reform2-lpc-fw/src/drivers/filters/iir/images/integer_response_alpha_4.png differ
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/images/integer_responsecurve_alpha_128.png b/reform2-lpc-fw/src/drivers/filters/iir/images/integer_responsecurve_alpha_128.png
new file mode 100644
index 0000000000000000000000000000000000000000..d87245b223913e9f7813262e5fbf9be56a7fe1f5
Binary files /dev/null and b/reform2-lpc-fw/src/drivers/filters/iir/images/integer_responsecurve_alpha_128.png differ
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/images/integer_responsecurve_alpha_32.png b/reform2-lpc-fw/src/drivers/filters/iir/images/integer_responsecurve_alpha_32.png
new file mode 100644
index 0000000000000000000000000000000000000000..47e5702ee5d2c69f84bc15c266353dce97d1bef9
Binary files /dev/null and b/reform2-lpc-fw/src/drivers/filters/iir/images/integer_responsecurve_alpha_32.png differ
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/images/integer_responsecurve_alpha_64.png b/reform2-lpc-fw/src/drivers/filters/iir/images/integer_responsecurve_alpha_64.png
new file mode 100644
index 0000000000000000000000000000000000000000..0e9d191226622041e26e1b2b9e06cae5a8cb195a
Binary files /dev/null and b/reform2-lpc-fw/src/drivers/filters/iir/images/integer_responsecurve_alpha_64.png differ
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/images/integer_sinewave_alpha_128.png b/reform2-lpc-fw/src/drivers/filters/iir/images/integer_sinewave_alpha_128.png
new file mode 100644
index 0000000000000000000000000000000000000000..4cc08bb21576ce80d5810bddc0641314bfdbd637
Binary files /dev/null and b/reform2-lpc-fw/src/drivers/filters/iir/images/integer_sinewave_alpha_128.png differ
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/images/integer_sinewave_alpha_16.png b/reform2-lpc-fw/src/drivers/filters/iir/images/integer_sinewave_alpha_16.png
new file mode 100644
index 0000000000000000000000000000000000000000..67925ad113e4715856b52877426b6e3053e95077
Binary files /dev/null and b/reform2-lpc-fw/src/drivers/filters/iir/images/integer_sinewave_alpha_16.png differ
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/images/integer_sinewave_alpha_32.png b/reform2-lpc-fw/src/drivers/filters/iir/images/integer_sinewave_alpha_32.png
new file mode 100644
index 0000000000000000000000000000000000000000..ec8d18a60439bfce814d323bb87f3c499be41eb7
Binary files /dev/null and b/reform2-lpc-fw/src/drivers/filters/iir/images/integer_sinewave_alpha_32.png differ
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/images/integer_sinewave_alpha_64.png b/reform2-lpc-fw/src/drivers/filters/iir/images/integer_sinewave_alpha_64.png
new file mode 100644
index 0000000000000000000000000000000000000000..dfe5d468ba151fab39624d02261e19e0906eed9f
Binary files /dev/null and b/reform2-lpc-fw/src/drivers/filters/iir/images/integer_sinewave_alpha_64.png differ
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/images/integer_sinewave_alpha_8.png b/reform2-lpc-fw/src/drivers/filters/iir/images/integer_sinewave_alpha_8.png
new file mode 100644
index 0000000000000000000000000000000000000000..2fc9d468e446db6fd5e9aaf56855fea971b8ab80
Binary files /dev/null and b/reform2-lpc-fw/src/drivers/filters/iir/images/integer_sinewave_alpha_8.png differ
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/python/iir_f_noisysine_test.py b/reform2-lpc-fw/src/drivers/filters/iir/python/iir_f_noisysine_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..28c02d9a83ce8fd57b83330cec4c13e3e0baa861
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/iir/python/iir_f_noisysine_test.py
@@ -0,0 +1,92 @@
+#-------------------------------------------------------------------------------
+# Name:        iir_f_tester
+#
+# Purpose:     Displays IIR output of a sine wave with optional random noise
+#
+# Author:      K. Townsend (microBuilder.eu)
+#
+# Created:     05/05/2013
+# Copyright:   (c) K. Townsend 2013
+# Licence:     BSD
+#
+# This module requires the following libs
+# matplotlib - http://matplotlib.org/
+# numpy      - http://www.numpy.org/
+#-------------------------------------------------------------------------------
+import numpy as np
+import matplotlib.pyplot as plt
+
+def main():
+    avg = 0.0
+    current = 0
+    iirvals = []
+
+    # Get alpha (determines how 'quickly' the filter responds to changes)
+    alpha = float(input("IIR alpha [0..1.0]: "))
+
+    # Set the noise level for the input sine wave
+    noiselevel = float(input("Input noise level [0..1.0]: "))
+
+    # Set the number of samples to use
+    samples = float(input("Number of samples: "))
+
+    # Check bounds
+    if (alpha > 1.0):
+        print ('Setting alpha to 1.0')
+        alpha = 1.0
+    if (alpha < 0):
+        print ('Setting alpha to 0.0')
+        alpha = 0.0
+    if (noiselevel > 1.0):
+        print ('Setting noise level to 1.0')
+        noiselevel = 1.0
+    if (noiselevel < 0):
+        print ('Setting noise level to 0.0')
+        noiselevel = 0.0
+    if (samples < 0):
+        print ('Setting samples to 100')
+        samples = 100
+
+    # Generate a sine wave with some noise on it
+    x = np.linspace(0, 4*np.pi, samples)
+    sine = np.sin(x)
+    noise = np.random.uniform(-1, 1, size=len(x)) * noiselevel
+    noisysine = sine + noise
+
+    # Run the IIR filter over the entire input dataset
+    while current < len(x):
+        current+=1
+        # Add one sample to the IIR filter
+        avg = iirAddValue(avg, alpha, noisysine[current-1])
+        # Plot IIR filtered value
+        iirvals.append(avg);
+        print ("%d: %g" % (current, avg))
+
+    # Display the results
+    plt.title("Sine Wave Input vs. IIR Output \n (Alpha: %g, Noise Level: %g)"
+        % (alpha, noiselevel))
+    plt.xlabel('Samples')
+    plt.ylabel('Values')
+    plt.ylim(noisysine.min()*1.1, noisysine.max()*1.1)
+    plt.grid(True)
+    plt.plot(noisysine,
+        color="blue",
+        alpha = 0.4,
+        linestyle="-",
+        label="Raw Input")
+    plt.plot(iirvals,
+        color="red",
+        linewidth='1.5',
+        linestyle="-",
+        label="IIR Output")
+    plt.legend()
+    plt.show()
+
+    pass
+
+def iirAddValue(avg, alpha, val):
+    "Adds a new value to the IIR filter"
+    return alpha * val + (1.0 - alpha) * avg
+
+if __name__ == '__main__':
+    main()
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/python/iir_f_response_test.py b/reform2-lpc-fw/src/drivers/filters/iir/python/iir_f_response_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..16655301ee43c498d224b265f6d5f289f99533a0
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/iir/python/iir_f_response_test.py
@@ -0,0 +1,62 @@
+#-------------------------------------------------------------------------------
+# Name:        iir_f_response_test
+#
+# Purpose:     Shows the response of an IIR filter over time. Used to determine
+#              how many samples are required to reach n percent of the new
+#              input value.
+#
+# Author:      K. Townsend (microBuilder.eu)
+#
+# Created:     05/05/2013
+# Copyright:   (c) K. Townsend 2013
+# Licence:     BSD
+#
+# This module requires the following libs
+# matplotlib - http://matplotlib.org/
+# numpy      - http://www.numpy.org/
+#-------------------------------------------------------------------------------
+from array import array
+import matplotlib.pyplot as plt
+
+def main():
+    avg = 0.0
+    samples = 0
+    values = []
+
+    # Get alpha
+    alpha = float(input("IIR alpha (0..1.0): "))
+
+    # Check alpha bounds
+    if (alpha > 1.0):
+        print ('Setting alpha to 1.0')
+        alpha = 1.0
+    if (alpha < 0):
+        print ('Setting alpha to 0.0')
+        alpha = 0.0
+
+    # Run the filter until we arrive at 99.9% of newval
+    values.append(0.0)
+    while avg < 1.0 * 0.999:
+        samples+=1
+        avg = iirAddValue(avg, alpha, 1.0)
+        # Plot value in percent
+        values.append(avg/0.01);
+        print ("%d: %g" % (samples, avg))
+
+    # Display the results
+    plt.title("IIR Response Over Time (Alpha = %g)" % (alpha))
+    plt.ylim(0, 110)
+    plt.xlabel('Samples')
+    plt.ylabel('IIR Output (%)')
+    plt.plot(values)
+    plt.grid(True)
+    plt.show()
+
+    pass
+
+def iirAddValue(avg, alpha, val):
+    "Adds a new value to the IIR filter"
+    return alpha * val + (1.0 - alpha) * avg
+
+if __name__ == '__main__':
+    main()
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/python/iir_i_noisysine_test.py b/reform2-lpc-fw/src/drivers/filters/iir/python/iir_i_noisysine_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..7775bda0ec9f48dc151a9828af3c4d93baf35443
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/iir/python/iir_i_noisysine_test.py
@@ -0,0 +1,92 @@
+#-------------------------------------------------------------------------------
+# Name:        iir_i_tester
+#
+# Purpose:     Displays IIR output of a sine wave with optional random noise
+#
+# Author:      K. Townsend (microBuilder.eu)
+#
+# Created:     05/05/2013
+# Copyright:   (c) K. Townsend 2013
+# Licence:     BSD
+#
+# This module requires the following libs
+# matplotlib - http://matplotlib.org/
+# numpy      - http://www.numpy.org/
+#-------------------------------------------------------------------------------
+import numpy as np
+import matplotlib.pyplot as plt
+
+def main():
+    avg = 0.0
+    current = 0
+    iirvals = []
+
+    # Get alpha (determines how 'quickly' the filter responds to changes)
+    alpha = int(input("IIR alpha (0..255): "))
+
+    # Set the noise level for the input sine wave
+    noiselevel = float(input("Input noise level [0..1.0]: "))
+
+    # Set the number of samples to use
+    samples = float(input("Number of samples: "))
+
+    # Check bounds
+    if (alpha > 255):
+        print ('Setting alpha to 255')
+        alpha = 255
+    if (alpha < 0):
+        print ('Setting alpha to 0')
+        alpha = 0
+    if (noiselevel > 1.0):
+        print ('Setting noise level to 1.0')
+        noiselevel = 1.0
+    if (noiselevel < 0):
+        print ('Setting noise level to 0.0')
+        noiselevel = 0.0
+    if (samples < 0):
+        print ('Setting samples to 100')
+        samples = 100
+
+    # Generate a sine wave with some noise on it
+    x = np.linspace(0, 4*np.pi, samples)
+    sine = np.sin(x)
+    noise = np.random.uniform(-1, 1, size=len(x)) * noiselevel
+    noisysine = sine*1000 + noise*1000
+
+    # Run the IIR filter over the entire input dataset
+    while current < len(x):
+        current+=1
+        # Add one sample to the IIR filter
+        avg = iirAddValue(avg, alpha, noisysine[current-1])
+        # Plot IIR filtered value
+        iirvals.append(avg);
+        print ("%d: %g" % (current, avg))
+
+    # Display the results
+    plt.title("Sine Wave Input vs. Int IIR Output \n (Alpha: %g, Noise Level: %g)"
+        % (alpha, noiselevel))
+    plt.xlabel('Samples')
+    plt.ylabel('Values')
+    plt.ylim(noisysine.min()*1.1, noisysine.max()*1.1)
+    plt.grid(True)
+    plt.plot(noisysine,
+        color="blue",
+        alpha = 0.4,
+        linestyle="-",
+        label="Raw Input")
+    plt.plot(iirvals,
+        color="red",
+        linewidth='1.5',
+        linestyle="-",
+        label="IIR Output")
+    plt.legend()
+    plt.show()
+
+    pass
+
+def iirAddValue(avg, alpha, val):
+    "Adds a new value to the IIR filter"
+    return (int)((val*alpha+avg*(256-alpha))/256)
+
+if __name__ == '__main__':
+    main()
diff --git a/reform2-lpc-fw/src/drivers/filters/iir/python/iir_i_response_test.py b/reform2-lpc-fw/src/drivers/filters/iir/python/iir_i_response_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ace6a15f166164c0ad129dc2f52eba081acd42b
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/iir/python/iir_i_response_test.py
@@ -0,0 +1,74 @@
+#-------------------------------------------------------------------------------
+# Name:        iir_i_response_test
+#
+# Purpose:     Shows the response of an IIR filter over time. Used to determine
+#              how many samples are required to reach n percent of the new
+#              input value.
+#
+# Author:      K. Townsend (microBuilder.eu)
+#
+# Created:     05/05/2013
+# Copyright:   (c) K. Townsend 2013
+# Licence:     BSD
+#
+# This module requires the following libs
+# matplotlib - http://matplotlib.org/
+# numpy      - http://www.numpy.org/
+#-------------------------------------------------------------------------------
+from array import array
+import matplotlib.pyplot as plt
+
+def main():
+    avg = 0
+    samples = 0
+    values = []
+
+    # Get alpha
+    alpha = int(input("IIR alpha (0..255): "))
+
+    # Check alpha bounds
+    if (alpha > 255):
+        print ('Setting alpha to 255')
+        alpha = 255
+    if (alpha < 0):
+        print ('Setting alpha to 0')
+        alpha = 0
+
+    # Start with a known value (0)
+    values.append(0)
+
+    # Run the filter until we arrive at 99% of newval or 500 samples
+    # if we are using a small alpha since the integer filter will never
+    # stabilize at 99.9% of the new value with heaver alpha values
+    if (alpha < 24):
+        while samples < 500:
+            samples+=1
+            avg = iirAddValue(avg, alpha, 1000)
+            # Plot value in percent
+            values.append(avg/10);
+            print ("%d: %d" % (samples, avg))
+    else:
+        while avg < 990:
+            samples+=1
+            avg = iirAddValue(avg, alpha, 1000)
+            # Plot value in percent
+            values.append(avg/10);
+            print ("%d: %d" % (samples, avg))
+
+    # Display the results
+    plt.title("IIR Response Over Time (Alpha = %d)" % (alpha))
+    plt.ylim(0, 110)
+    plt.xlabel('Samples')
+    plt.ylabel('IIR Output (%)')
+    plt.plot(values)
+    plt.grid(True)
+    plt.show()
+
+    pass
+
+def iirAddValue(avg, alpha, val):
+    "Adds a new value to the IIR filter"
+    return (int)((val*alpha+avg*(256-alpha))/256)
+
+if __name__ == '__main__':
+    main()
diff --git a/reform2-lpc-fw/src/drivers/filters/ma/README.md b/reform2-lpc-fw/src/drivers/filters/ma/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..d0940f42262e5d4102531aabaec18ad9e1d6e983
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/ma/README.md
@@ -0,0 +1,138 @@
+# Simple Moving Average Filter (sma_*) #
+
+The **simple moving average** is a type of **FIR** filter, and is probably the most common filter type used due to it's speed and simplicity. Don't understimate or overlook it due to it's relative simplicity, though, since you can solve many problems admirably with this unassuming little filter!  
+
+Effectively, the filter works by setting a 'window size', which defines the number of samples we want to average together.  We then move through our dataset, averaging the last 'n' samples, where 'n' is your window size. As new samples are added, the oldest sample is dropped to make room for the new one, and a new average is calculate based on the data in the current window range.
+
+**For example**: We set a window size of eight, and we get ready to transmit 100 ADC samples in the moving average filter one by one.  The first seven samples will be meaningless since the filter is still setting up, filling the circular buffer. After the eighth sample is added, though, we will have an average of the previous eight samples, which is the output for our filter.  When we add sample number nine, the earliest sample from our ADC -- sample number one -- will be pushed out of the buffer, and the latest sample will take it's place.
+
+## What are the advantage of the Moving Average Filter ##
+
+One of the key advantages of the moving average filter (aside from it's speed an simplicity!) is that you don't have to deal with accumulated errors over time the way you do with something like an IIR filter.  
+
+Because you are working with a continuously moving subset of your data (the 'window'), the rest of the historical data has no weight and the only accumulated error is over the small data subset in the current window.
+
+The moving average filter is a good choice for removing random noise or spikes in the data, while still maintaining excellent responsivity to changes in the signal.  It's an excellent choice for filters in the time domain, since it is very responsive to changes over time, without introducing as much 'phase shift' or instability as an IIR filter might.
+
+## Filter Results ##
+
+You can see the results of the simple moving average filter in the images below, using a variety of window sizes on an integer sine wave with a little bit of noisy added on to it (since this is the most common problem you use an ma filter to solve).  A larger window increases the phase shift and requires more memory (for the larger window buffer), but results in smoother data.  Take note of the 'setup period' at the start of the images where the filter output is 0:
+
+![Integer MA Window 4](images/ma_u16_win4_noise0_025_12-bitrange.png?raw=true)
+![Integer MA Window 8](images/ma_u16_win8_noise0_025_12-bitrange.png?raw=true)
+![Integer MA Window 16](images/ma_u16_win16_noise0_025_12-bitrange.png?raw=true)
+![Integer MA Window 32](images/ma_u16_win32_noise0_025_12-bitrange.png?raw=true)
+
+## Which Filter Version Should I Use (float, int32\_t, or uint16\_t)? ##
+
+Three versions of this filter are included, one that uses single-precision floating point values (ma\_f.c), one that uses uses signed 32-bit integers (ma\_i.c), and another that uses unsigned 16-bit integers (ma\_u16.c).
+
+There are advantages and tradeoffs to both of these implementations that you should be aware of when using them, but this will almost certainly be dictated by the data you wish 
+
+## How Do I Use This Code? ##
+
+### 1. Allocate Memory for the Window Buffer ###
+The moving average filter requires a buffer to store the 'windowed' data, so before we can do anything with this filter, we need to set a chunk of SRAM aside for the filter to work with behind the scenes.  We do this by declaring an array with the right type and ^2 in length (meaning that the array must be 2, 4, 8, 16, 32, etc. values wide).
+
+The following code will create an 8 sample buffer using floating point data (meaning 32 bytes of memory will be used, since a single float takes 4 bytes, multiplied by our window size of 8 samples):
+```
+  // Create a buffer named 'bufsma' 8 float values wide
+  float bufsma[8];
+```
+To do the same for uint16\_t data, we would use the following code, which would require half of the memory since uint16_t uses 2 bytes instead of the four bytes in float:
+```
+  // Create a buffer named 'bufsma' 8 uint16_t values wide
+  uint16_t bufsma[8];
+```
+### 2. Declare the Filter Object ###
+The current filter code is based on a single 'struct' that contains all of the implementation details for our filter, including the buffer.  The benefit of this approach is that we can have many 'instances' of the filter, each encapsulated in a single 'variable', and we can cascade them by running the filter once, and then running those results through another filter a second time.
+
+To declare a field that will hold the filter data, we use the following code, being careful to use the same window size (.size) and buffer name (.buffer) that we declared above!):
+
+```
+  // Now declare the filter with the window size and a buffer pointer
+  sma_f_t sma = { .k = 0,
+                  .size = 8,
+                  .avg = 0,
+                  .buffer = sma_buffer };
+```
+... or for uint16\_t data this would be:
+```
+  // Now declare the filter with the window size and a buffer pointer
+  sma_u16_t sma = { .k = 0,
+                    .size = 8,
+                    .avg = 0,
+                    .buffer = sma_buffer };
+```
+### 3. Initialise the Filter ###
+After declaring a placeholder **sma\_f\_t** (for floating point math), **sma\_i\_t** (for 32-bit signed integer math) object, or **sma\_u16\_t** (for unsigned 16-bit integers), we need to call the init function and supply a reference to our ma placeholder.
+
+This function essentially just does some basic error checking, and will return **false** if for some reason the filter couldn't be initialised, such as a problem with the window size (**which must be a ^2 value!**).
+
+We'll use the floating point version below as an example.
+```
+  // Initialise the moving average filter (mostly error checks)
+  if (sma_f_init(&sma))
+  {
+    printf("Something failed during filter init!\n");
+  }
+```
+... or the uint16\_t version would look like this
+```
+  // Initialise the moving average filter (mostly error checks)
+  if (sma_u16_init(&sma))
+  {
+    printf("Something failed during filter init!\n");
+  }
+```
+### 4. Start Adding Values! ###
+After initialising the filter, you continually add in your samples via the **sma\_*\_add** functions, and read the current 'sma.avg' value whenever you need it.
+
+For example, for the floating point version we could use the following code:
+```
+  // Add some values
+  sma_f_add(&sma, 10.0F);
+  sma_f_add(&sma, 20.0F);
+  sma_f_add(&sma, 30.15F);
+  sma_f_add(&sma, 35.0F);
+  sma_f_add(&sma, 12.0F);
+  sma_f_add(&sma, -6.7);
+  sma_f_add(&sma, 30.3F);
+  sma_f_add(&sma, 20.0F);  // We should have an avg value starting here
+  sma_f_add(&sma, 0.0F);
+  sma_f_add(&sma, 10.0F);
+
+  printf("WINDOW SIZE   : %d\n", sma.size);
+  printf("TOTAL SAMPLES : %d\n", sma.k);
+  printf("CURRENT AVG   : %f\n", sma.avg);
+  printf("\n");
+```
+... or for the uint16_t version:
+```
+  // Add some values
+  sma_u16_add(&sma, 10);
+  sma_u16_add(&sma, 20);
+  sma_u16_add(&sma, -30);
+  sma_u16_add(&sma, 37);
+  sma_u16_add(&sma, 11);  
+  sma_u16_add(&sma, 31);
+  sma_u16_add(&sma, 30);
+  sma_u16_add(&sma, 20);  // We should have an avg value starting here
+  sma_u16_add(&sma, 3);
+  sma_u16_add(&sma, 10);
+
+  printf("WINDOW SIZE   : %d\n", sma.size);
+  printf("TOTAL SAMPLES : %d\n", sma.k);
+  printf("CURRENT AVG   : %d\n", sma.avg);
+  printf("\n");
+```
+
+## Implementation Warning ##
+
+A major strength of the 'simple moving average' is that it is one of the fastest filters, particulary if you use a ^2 window size (2, 4, 8, 16, 32, etc.).  The ^2 window means the expensive division operator can be replaced with a single-cycle right-shift.
+
+To avoid extra overhead, the current sma implementation will only allow you to init a filter with a ^2 window size.
+
+## Further Reading ##
+
+For more information on simple moving average filters, see [Moving Average Filters](http://www.dspguide.com/ch15.htm) in Steven Smith's excellent book **The Scientist and Engineer's Guide to Digital Signal Processing**.
diff --git a/reform2-lpc-fw/src/drivers/filters/ma/images/ma_u16_win16_noise0_025_12-bitrange.png b/reform2-lpc-fw/src/drivers/filters/ma/images/ma_u16_win16_noise0_025_12-bitrange.png
new file mode 100644
index 0000000000000000000000000000000000000000..7b4e0f01d993654f2d35feb5fc6f92ba604d4c30
Binary files /dev/null and b/reform2-lpc-fw/src/drivers/filters/ma/images/ma_u16_win16_noise0_025_12-bitrange.png differ
diff --git a/reform2-lpc-fw/src/drivers/filters/ma/images/ma_u16_win32_noise0_025_12-bitrange.png b/reform2-lpc-fw/src/drivers/filters/ma/images/ma_u16_win32_noise0_025_12-bitrange.png
new file mode 100644
index 0000000000000000000000000000000000000000..215a5c1e5ec82fd3715503d9d62410be4a096b17
Binary files /dev/null and b/reform2-lpc-fw/src/drivers/filters/ma/images/ma_u16_win32_noise0_025_12-bitrange.png differ
diff --git a/reform2-lpc-fw/src/drivers/filters/ma/images/ma_u16_win4_noise0_025_12-bitrange.png b/reform2-lpc-fw/src/drivers/filters/ma/images/ma_u16_win4_noise0_025_12-bitrange.png
new file mode 100644
index 0000000000000000000000000000000000000000..00329ed510b905f2c3f8be54a5a48424773bf889
Binary files /dev/null and b/reform2-lpc-fw/src/drivers/filters/ma/images/ma_u16_win4_noise0_025_12-bitrange.png differ
diff --git a/reform2-lpc-fw/src/drivers/filters/ma/images/ma_u16_win8_noise0_025_12-bitrange.png b/reform2-lpc-fw/src/drivers/filters/ma/images/ma_u16_win8_noise0_025_12-bitrange.png
new file mode 100644
index 0000000000000000000000000000000000000000..811e4dd497af79a6d93eccf682c5946049657099
Binary files /dev/null and b/reform2-lpc-fw/src/drivers/filters/ma/images/ma_u16_win8_noise0_025_12-bitrange.png differ
diff --git a/reform2-lpc-fw/src/drivers/filters/ma/python/ma_u16_noisysine_test.py b/reform2-lpc-fw/src/drivers/filters/ma/python/ma_u16_noisysine_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..8fefe1a104ed6908380bcb35aec61ce34a52e0fe
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/ma/python/ma_u16_noisysine_test.py
@@ -0,0 +1,126 @@
+#-------------------------------------------------------------------------------
+# Name:        ma_u16_tester
+#
+# Purpose:     Displays simple moving average output of a sine wave with
+#              optional random noise
+#
+# Author:      K. Townsend (microBuilder.eu)
+#
+# Created:     19/05/2013
+# Copyright:   (c) K. Townsend 2013
+# Licence:     BSD
+#
+# This module requires the following libs
+# matplotlib - http://matplotlib.org/
+# numpy      - http://www.numpy.org/
+#-------------------------------------------------------------------------------
+import numpy as np
+import matplotlib.pyplot as plt
+from collections import deque
+
+
+class RingBuffer(deque):
+    def __init__(self, size_max):
+        deque.__init__(self)
+        self.size_max = size_max
+    def append(self, datum):
+        deque.append(self, datum)
+        if len(self) > self.size_max:
+            self.popleft( )
+    def tolist(self):
+        return list(self)
+
+def main():
+    current = 0
+    avg = 0
+    total = 0
+    mavals = []
+
+    # Set the noise level for the input sine wave
+    noiselevel = float(input("Input noise level [0..1.0]: "))
+
+    # Get window size (how many 'samples' are averaged together)
+    windowsize = int(input("Windows size (0..65535): "))
+
+    # Get amplitude (the numeric range of the data)
+    amplitude = int(input("Peak amplitude (0..32767): "))
+
+    # Set the number of samples to use
+    samples = int(input("Number of samples: "))
+
+    # Check bounds
+    if (noiselevel > 1.0):
+        print ('Setting noise level to 1.0')
+        noiselevel = 1.0
+    if (noiselevel < 0):
+        print ('Setting noise level to 0.0')
+        noiselevel = 0.0
+    if (windowsize > 65535):
+        print ('Setting window size to 65535')
+        windowsize = 65535
+    if (windowsize < 1):
+        print ('Setting window size to 1')
+        windowsize = 1
+    if (amplitude > 32767):
+        print ('Setting amplitude to 32767')
+        amplitude = 32767
+    if (amplitude < 1):
+        print ('Setting amplitude to 1')
+        amplitude = 1
+    if (samples < windowsize):
+        printf('Setting samples to match window size')
+        samples = windowsize
+
+    # Create a circular buffer for our window view
+    window = RingBuffer(size_max=windowsize)
+
+    # Generate a sine wave with some noise on it
+    x = np.linspace(0, 4*np.pi, samples)
+    sine = np.sin(x)
+    noise = np.random.uniform(-1, 1, size=len(x)) * noiselevel
+    noisysine = sine*amplitude + noise*amplitude
+
+    # Run the ma filter over the entire input dataset
+    while current < len(x):
+        current+=1
+        # Make sure we've reached 'windowlength' samples in the buffer
+        if (current <= windowsize):
+            window.append(noisysine[current-1])
+            mavals.append(0)
+        else:
+            # Add the current sample to the 'window' ring buffer
+            window.append(noisysine[current-1])
+            # Get the current average based on the window content
+            li = window.tolist()
+            total = 0
+            for i in li:
+                total += i
+            avg = (int)(total/windowsize)
+            # Append ma output for plotting below
+            mavals.append(avg);
+            print ("%d: %d" % (current, avg))
+
+    # Display the results
+    plt.title("Sine Wave Input vs. U16 MA Output \n(Window Size: %d, Noise Level: %g)"
+        % (windowsize, noiselevel))
+    plt.xlabel('Samples')
+    plt.ylabel('Values')
+    plt.ylim(noisysine.min()*1.1, noisysine.max()*1.1)
+    plt.grid(True)
+    plt.plot(noisysine,
+        color="blue",
+        alpha = 0.4,
+        linestyle="-",
+        label="Raw Input")
+    plt.plot(mavals,
+        color="red",
+        linewidth='1.5',
+        linestyle="-",
+        label="MA Output")
+    plt.legend()
+    plt.show()
+
+    pass
+
+if __name__ == '__main__':
+    main()
diff --git a/reform2-lpc-fw/src/drivers/filters/ma/sma_f.c b/reform2-lpc-fw/src/drivers/filters/ma/sma_f.c
new file mode 100644
index 0000000000000000000000000000000000000000..28be54c9265ad63a8b71208fb490dc62f42d70bc
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/ma/sma_f.c
@@ -0,0 +1,147 @@
+/**************************************************************************/
+/*!
+    @file     sma_f.c
+    @author   Nguyen Quang Huy, Nguyen Thien Tin
+    @brief    A simple moving average filter using float values
+
+    @code
+
+    // Declare a data buffer 8 values wide
+    float sma_buffer[8];
+
+    // Now declare the filter with the window size and a buffer pointer
+    sma_f_t sma = { .k = 0,
+                    .size = 8,
+                    .avg = 0,
+                    .buffer = sma_buffer };
+
+    // Initialise the moving average filter
+    if (sma_f_init(&sma))
+    {
+      printf("Something failed during filter init!\n");
+    }
+
+    // Add some values
+    sma_f_add(&sma, 1.0);
+    sma_f_add(&sma, 2.1);
+    sma_f_add(&sma, -30.2);
+    sma_f_add(&sma, -35.3);
+    sma_f_add(&sma, 11.4);
+    sma_f_add(&sma, 35.5);
+    sma_f_add(&sma, 30.6);
+    sma_f_add(&sma, 20.7); // We should have an avg value starting here
+    sma_f_add(&sma, 3.8);
+    sma_f_add(&sma, 10.9);
+
+    printf("WINDOW SIZE   : %f\n", sma.size);
+    printf("TOTAL SAMPLES : %f\n", sma.k);
+    printf("CURRENT AVG   : %f\n", sma.avg);
+    printf("\n");
+
+    @endcode
+    
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    
+ */
+/**************************************************************************/
+#include "sma_f.h"
+
+/**************************************************************************/
+/*!
+     @brief Initialises the sma_f_t instance
+
+     @param[in]  sma
+                 Pointer to the sma_f_t instance that includes the
+                 window size, a pointer to the data buffer,
+                 the current average (the output value), etc.
+*/
+/**************************************************************************/
+err_t sma_f_init ( sma_f_t *sma )
+{
+  // check if the window size is valid (!= 0 and is a power of 2)
+  if ((0 == sma->size) || ( sma->size & (sma->size - 1) )) return ERROR_UNEXPECTEDVALUE;
+
+  sma->avg = 0;
+  sma->k = 0;
+  sma->total = 0;
+
+  // update the exponential number
+  sma->exponent = 0;
+  uint16_t windowSize = sma->size;
+  while (windowSize > 1)
+  {
+    windowSize = windowSize >> 1;
+    sma->exponent++;
+  }
+
+  // Fill the buffer with zero value
+  for (uint16_t i = 0; i < sma->size; i++)
+  {
+    *(sma->buffer + i) = 0;
+  }
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+     @brief Adds a new value to the sma_f_t instances
+
+     @param[in]  sma
+                 Pointer to the sma_f_t instances
+     @param[in]  x
+                 Value to insert
+*/
+/**************************************************************************/
+void sma_f_add(sma_f_t *sma, float x)
+{
+  float *pSource = sma->buffer + (sma->k % sma->size);
+
+  // Subtract oldest value from the total sum
+  sma->total -= *pSource;
+
+  // Add new value into the data buffer of the filter
+  *pSource = x;
+
+  // Add new value into the total value of current window
+  sma->total += x;
+
+  // increase the total sample processed
+  sma->k++;
+
+  // Wait for 'window-size' worth of samples before averaging
+  if (sma->k < sma->size)
+    return;
+
+  // Update the current average value
+  double tmp_total = sma->total;
+  uint64_t *ptr = (uint64_t *)(&tmp_total);
+  *ptr -= ((uint64_t)(sma->exponent)) << 52;  // Subtract exponent of window size from exponent of total value
+                                              // refer to double precision for more details
+  sma->avg = (float)(tmp_total);
+}
diff --git a/reform2-lpc-fw/src/drivers/filters/ma/sma_f.h b/reform2-lpc-fw/src/drivers/filters/ma/sma_f.h
new file mode 100644
index 0000000000000000000000000000000000000000..e28141e4472a9e2ce12c4ab7be52033f7e153b52
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/ma/sma_f.h
@@ -0,0 +1,62 @@
+/**************************************************************************/
+/*!
+    @file     sma_f.h
+    @author   Nguyen Quang Huy, Nguyen Thien Tin
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __SMA_F_H__
+#define __SMA_F_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+typedef struct sma_f_s
+{
+  uint32_t        k;            /**< Total number of samples processed so far                           */
+  uint16_t const  size;         /**< Window size (number of samples to average)                         */
+  float           avg;          /**< Current average                                                    */
+  uint16_t        exponent;     /**< Exponential number (size=window)                                   */
+  float          *buffer;       /**< Pointer to the input data buffer (size=window)                     */
+  double          total;        /**< Total value of current window (use double for overflow prevention) */
+} sma_f_t;
+
+err_t sma_f_init ( sma_f_t *sma );
+void    sma_f_add  ( sma_f_t *sma, float x );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SMA_F_H__ */
diff --git a/reform2-lpc-fw/src/drivers/filters/ma/sma_i.c b/reform2-lpc-fw/src/drivers/filters/ma/sma_i.c
new file mode 100644
index 0000000000000000000000000000000000000000..74949e9ef6737ef4d16b3e5ddc7496dac53d19a5
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/ma/sma_i.c
@@ -0,0 +1,143 @@
+/**************************************************************************/
+/*!
+    @file     sma_i.c
+    @author   Nguyen Quang Huy, Nguyen Thien Tin
+    @brief    A simple moving average filter using int32_t values
+
+    @code
+
+    // Declare a data buffer 8 values wide
+    int32_t sma_buffer[8];
+
+    // Now declare the filter with the window size and a buffer pointer
+    sma_i_t sma = { .k = 0,
+                    .size = 8,
+                    .avg = 0,
+                    .buffer = sma_buffer };
+
+    // Initialise the moving average filter
+    if (sma_i_init(&sma))
+    {
+      printf("Something failed during filter init!\n");
+    }
+
+    // Add some values
+    sma_i_add(&sma, 10);
+    sma_i_add(&sma, 20);
+    sma_i_add(&sma, -30);
+    sma_i_add(&sma, -35);
+    sma_i_add(&sma, 11);
+    sma_i_add(&sma, 35);
+    sma_i_add(&sma, 30);
+    sma_i_add(&sma, 20); // We should have an avg value starting here
+    sma_i_add(&sma, 3);
+    sma_i_add(&sma, 10);
+
+    printf("WINDOW SIZE   : %d\n", sma.size);
+    printf("TOTAL SAMPLES : %d\n", sma.k);
+    printf("CURRENT AVG   : %d\n", sma.avg);
+    printf("\n");
+
+    @endcode
+    
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    
+ */
+/**************************************************************************/
+#include "sma_i.h"
+
+/**************************************************************************/
+/*!
+     @brief Initialises the sma_i_t instance
+
+     @param[in]  sma
+                 Pointer to the sma_i_t instance that includes the
+                 window size, a pointer to the data buffer,
+                 the current average (the output value), etc.
+*/
+/**************************************************************************/
+err_t sma_i_init ( sma_i_t *sma )
+{
+  // check if the window size is valid (!= 0 and is a power of 2)
+  if ((0 == sma->size) || ( sma->size & (sma->size - 1) )) return ERROR_UNEXPECTEDVALUE;
+
+  sma->avg = 0;
+  sma->k = 0;
+  sma->total = 0;
+
+  // update the exponential number
+  sma->exponent = 0;
+  int windowSize = sma->size;
+  while (windowSize > 1)
+  {
+    windowSize = windowSize >> 1;
+    sma->exponent++;
+  }
+
+  // Fill the buffer with zero value
+  for (int i = 0; i < sma->size; i++)
+  {
+    *(sma->buffer + i) = 0;
+  }
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+     @brief Adds a new value to the sma_i_t instances
+
+     @param[in]  sma
+                 Pointer to the sma_i_t instances
+     @param[in]  x
+                 Value to insert
+*/
+/**************************************************************************/
+void sma_i_add(sma_i_t *sma, int32_t x)
+{
+  int32_t *pSource = sma->buffer + (sma->k % sma->size);
+
+  // Subtract oldest value from the total sum
+  sma->total -= *pSource;
+
+  // Add new value into the data buffer of the filter
+  *pSource = x;
+
+  // Add new value into the total value of current window
+  sma->total += x;
+
+  // increase the total sample processed
+  sma->k++;
+
+  // Wait for 'window-size' worth of samples before averaging
+  if (sma->k < sma->size)
+    return;
+
+  // Update the current average value
+  sma->avg = (int32_t)(sma->total >> sma->exponent);
+}
diff --git a/reform2-lpc-fw/src/drivers/filters/ma/sma_i.h b/reform2-lpc-fw/src/drivers/filters/ma/sma_i.h
new file mode 100644
index 0000000000000000000000000000000000000000..7d4d3c96882ebbd0d27289cf2cd6c71f7eba25e0
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/ma/sma_i.h
@@ -0,0 +1,62 @@
+/**************************************************************************/
+/*!
+    @file     sma_i.h
+    @author   Nguyen Quang Huy, Nguyen Thien Tin
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __SMA_I_H__
+#define __SMA_I_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+typedef struct sma_i_s
+{
+  uint32_t        k;            /**< Total number of samples processed so far                           */
+  uint16_t const  size;         /**< Window size (number of samples to average)                         */
+  int32_t         avg;          /**< Current average                                                    */
+  uint16_t        exponent;     /**< Exponential number (size=window)                                   */
+  int32_t        *buffer;       /**< Pointer to the input data buffer (size=window)                     */
+  int64_t         total;        /**< Total value of current window (use int64 for overflow prevention)  */
+} sma_i_t;
+
+err_t sma_i_init ( sma_i_t *sma );
+void    sma_i_add  ( sma_i_t *sma, int32_t x );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SMA_I_H__ */
diff --git a/reform2-lpc-fw/src/drivers/filters/ma/sma_u16.c b/reform2-lpc-fw/src/drivers/filters/ma/sma_u16.c
new file mode 100644
index 0000000000000000000000000000000000000000..4e9b4976c88fb43781dda8561458006a9cabced8
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/ma/sma_u16.c
@@ -0,0 +1,143 @@
+/**************************************************************************/
+/*!
+    @file     sma_u16.c
+    @author   Nguyen Quang Huy, Nguyen Thien Tin
+    @brief    A simple moving average filter using uint16_t values
+
+    @code
+
+    // Declare a data buffer 8 values wide
+    uint16_t sma_buffer[8];
+
+    // Now declare the filter with the window size and a buffer pointer
+    sma_u16_t sma = { .k = 0,
+                      .size = 8,
+                      .avg = 0,
+                      .buffer = sma_buffer };
+
+    // Initialise the moving average filter
+    if (sma_u16_init(&sma))
+    {
+      printf("Something failed during filter init!\n");
+    }
+
+    // Add some values
+    sma_u16_add(&sma, 10);
+    sma_u16_add(&sma, 20);
+    sma_u16_add(&sma, 30);
+    sma_u16_add(&sma, 35);
+    sma_u16_add(&sma, 11);
+    sma_u16_add(&sma, 35);
+    sma_u16_add(&sma, 30);
+    sma_u16_add(&sma, 20); // We should have an avg value starting here
+    sma_u16_add(&sma, 3);
+    sma_u16_add(&sma, 10);
+
+    printf("WINDOW SIZE   : %d\n", sma.size);
+    printf("TOTAL SAMPLES : %d\n", sma.k);
+    printf("CURRENT AVG   : %d\n", sma.avg);
+    printf("\n");
+
+    @endcode
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    
+ */
+/**************************************************************************/
+#include "sma_u16.h"
+
+/**************************************************************************/
+/*!
+     @brief Initialises the sma_u16_t instance
+
+     @param[in]  sma
+                 Pointer to the sma_u16_t instance that includes the
+                 window size, a pointer to the data buffer,
+                 the current average (the output value), etc.
+*/
+/**************************************************************************/
+err_t sma_u16_init ( sma_u16_t *sma )
+{
+  // check if the window size is valid (!= 0 and is a power of 2)
+  if ((0 == sma->size) || ( sma->size & (sma->size - 1) )) return ERROR_UNEXPECTEDVALUE;
+
+  sma->avg = 0;
+  sma->k = 0;
+  sma->total = 0;
+
+  // update the exponential number
+  sma->exponent = 0;
+  uint16_t windowSize = sma->size;
+  while (windowSize > 1)
+  {
+    windowSize = windowSize >> 1;
+    sma->exponent++;
+  }
+
+  // Fill the buffer with zero value
+  for (uint16_t i = 0; i < sma->size; i++)
+  {
+    *(sma->buffer + i) = 0;
+  }
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+     @brief Adds a new value to the sma_u16_t instances
+
+     @param[in]  sma
+                 Pointer to the sma_u16_t instances
+     @param[in]  x
+                 Value to insert
+*/
+/**************************************************************************/
+void sma_u16_add(sma_u16_t *sma, uint16_t x)
+{
+  uint16_t *pSource = sma->buffer + (sma->k % sma->size);
+
+  // Subtract oldest value from the total sum
+  sma->total -= *pSource;
+
+  // Add new value into the data buffer of the filter
+  *pSource = x;
+
+  // Add new value into the total value of current window
+  sma->total += x;
+
+  // increase the total sample processed
+  sma->k++;
+
+  // Wait for 'window-size' worth of samples before averaging
+  if (sma->k < sma->size)
+    return;
+
+  // Update the current average value
+  sma->avg = (uint16_t)(sma->total >> sma->exponent);
+}
diff --git a/reform2-lpc-fw/src/drivers/filters/ma/sma_u16.h b/reform2-lpc-fw/src/drivers/filters/ma/sma_u16.h
new file mode 100644
index 0000000000000000000000000000000000000000..d13a63f9546a64882ea112055883e26c05c1b64a
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/ma/sma_u16.h
@@ -0,0 +1,62 @@
+/**************************************************************************/
+/*!
+    @file     sma_u16.h
+    @author   Nguyen Quang Huy, Nguyen Thien Tin
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __SMA_U16_H__
+#define __SMA_U16_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+typedef struct sma_u16_s
+{
+  uint32_t        k;            /**< Total number of samples processed so far                           */
+  uint16_t const  size;         /**< Window size (number of samples to average)                         */
+  uint16_t        avg;          /**< Current average                                                    */
+  uint16_t        exponent;     /**< Exponential number (size=window)                                   */
+  uint16_t       *buffer;       /**< Pointer to the input data buffer (size=window)                     */
+  uint32_t        total;        /**< Total value of current window (use uint32 for overflow prevention) */
+} sma_u16_t;
+
+err_t sma_u16_init ( sma_u16_t *sma );
+void    sma_u16_add  ( sma_u16_t *sma, uint16_t x );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SMA_U16_H__ */
diff --git a/reform2-lpc-fw/src/drivers/filters/ma/wma_f.c b/reform2-lpc-fw/src/drivers/filters/ma/wma_f.c
new file mode 100644
index 0000000000000000000000000000000000000000..f85f901b2767d20832bdf87c6e1322cc0e14dd9e
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/ma/wma_f.c
@@ -0,0 +1,138 @@
+/**************************************************************************/
+/*!
+    @file     wma_f.c
+    @author   Nguyen Quang Huy, Nguyen Thien Tin
+    @brief    A simple moving average filter using float values
+
+    @code
+
+    // Declare a data buffer 8 values wide
+    float wma_buffer[8];
+    float wma_weight[8] = { 0.1F, 0.1F, 0.125F, 0.125F, 0.25F, 0.25F, 0.5F, 1.0F }
+
+    // Now declare the filter with the window size and a buffer pointer
+    wma_f_t wma = { .k = 0,
+                    .size = 8,
+                    .avg = 0,
+                    .weight = wma_weight,
+                    .buffer = wma_buffer };
+
+    // Initialise the moving average filter
+    if (wma_f_init(&wma))
+    {
+      printf("Something failed during filter init!\n");
+    }
+
+    // Add some values
+    wma_f_add(&wma, 1.0);
+    wma_f_add(&wma, 2.1);
+    wma_f_add(&wma, -30.2);
+    wma_f_add(&wma, -35.3);
+    wma_f_add(&wma, 11.4);
+    wma_f_add(&wma, 35.5);
+    wma_f_add(&wma, 30.6);
+    wma_f_add(&wma, 20.7); // We should have an avg value starting here
+    wma_f_add(&wma, 3.8);
+    wma_f_add(&wma, 10.9);
+
+    printf("WINDOW SIZE   : %f\n", wma.size);
+    printf("TOTAL SAMPLES : %f\n", wma.k);
+    printf("CURRENT AVG   : %f\n", wma.avg);
+    printf("\n");
+
+    @endcode
+    
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    
+ */
+/**************************************************************************/
+#include "wma_f.h"
+
+/**************************************************************************/
+/*!
+     @brief Initialises the wma_f_t instance
+
+     @param[in]  wma
+                 Pointer to the wma_f_t instance that includes the
+                 window size, a pointer to the data buffer,
+                 the current average (the output value), etc.
+*/
+/**************************************************************************/
+err_t wma_f_init ( wma_f_t *wma )
+{
+  /* Check if the window size is valid (!= 0 and is a power of 2) */
+  if (0 == wma->size) return ERROR_UNEXPECTEDVALUE;
+
+  wma->avg = 0;
+  wma->k = 0;
+  wma->sum_weight = 0;
+  
+  for (uint16_t i = 0; i < wma->size; i++)
+  {
+    wma->sum_weight += wma->weight[i];
+  }
+  
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+     @brief Adds a new value to the wma_f_t instances
+
+     @param[in]  wma
+                 Pointer to the wma_f_t instances
+     @param[in]  x
+                 Value to insert
+*/
+/**************************************************************************/
+void wma_f_add(wma_f_t *wma, float x)
+{
+  float *pSource = wma->buffer + wma->k % wma->size;
+
+  /* Add new value into the data buffer of the filter */
+  *pSource = x;
+
+  /* Increase the total samples processed */
+  wma->k++;
+
+  /* Wait for 'window-size' worth of samples before averaging */
+  if (wma->k < wma->size)
+    return;
+
+  /* Recalculate the total value over the entire buffer */
+  double total = 0;
+  uint16_t current_pos = wma->k % wma->size;
+  for (uint16_t i = 0; i < wma->size; i++)
+  {
+    total += wma->buffer[(i + current_pos) % wma->size] * wma->weight[i];
+  }
+
+  /* Update the current average value */
+  wma->avg = (float)(total / wma->sum_weight);
+}
diff --git a/reform2-lpc-fw/src/drivers/filters/ma/wma_f.h b/reform2-lpc-fw/src/drivers/filters/ma/wma_f.h
new file mode 100644
index 0000000000000000000000000000000000000000..ba326f707070eda5b8cf88981abb19a55ba4ec1e
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/ma/wma_f.h
@@ -0,0 +1,62 @@
+/**************************************************************************/
+/*!
+    @file     wma_f.h
+    @author   Nguyen Quang Huy, Nguyen Thien Tin
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __WMA_F_H__
+#define __WMA_F_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+typedef struct wma_f_s
+{
+  uint32_t        k;            /**< Total number of samples processed so far                           */
+  uint16_t const  size;         /**< Window size (number of samples to average)                         */
+  float           avg;          /**< Current average                                                    */
+  float          *weight;       /**< Pointer to a weighted array of each sample                         */
+  float           sum_weight;   /**< The sum of the individual weights                                  */
+  float          *buffer;       /**< Pointer to the input data buffer (size=window)                     */
+} wma_f_t;
+
+err_t wma_f_init ( wma_f_t *wma );
+void    wma_f_add  ( wma_f_t *wma, float x );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __WMA_F_H__ */
diff --git a/reform2-lpc-fw/src/drivers/filters/ma/wma_i.c b/reform2-lpc-fw/src/drivers/filters/ma/wma_i.c
new file mode 100644
index 0000000000000000000000000000000000000000..3a631c33a9bce3b987ec95468aa706dfa89fb321
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/ma/wma_i.c
@@ -0,0 +1,138 @@
+/**************************************************************************/
+/*!
+    @file     wma_i.c
+    @author   Nguyen Quang Huy, Nguyen Thien Tin
+    @brief    A simple moving average filter using int32_t values
+
+    @code
+
+    // Declare a data buffer 8 values wide
+    int32_t wma_buffer[8];
+    uint8_t wma_weight[8] = {8, 8, 16, 16, 32, 32, 128, 255};
+
+    // Now declare the filter with the window size, a buffer pointer and a weighted array
+    wma_i_t wma = { .k = 0,
+                    .size = 8,
+                    .avg = 0,
+                    .weight = wma_weight,
+                    .buffer = wma_buffer };
+
+    // Initialise the moving average filter
+    if (wma_i_init(&wma))
+    {
+      printf("Something failed during filter init!\n");
+    }
+
+    // Add some values
+    wma_i_add(&wma, 10);
+    wma_i_add(&wma, 20);
+    wma_i_add(&wma, -30);
+    wma_i_add(&wma, -35);
+    wma_i_add(&wma, 11);
+    wma_i_add(&wma, 35);
+    wma_i_add(&wma, 30);
+    wma_i_add(&wma, 20); // We should have an avg value starting here
+    wma_i_add(&wma, 3);
+    wma_i_add(&wma, 10);
+
+    printf("WINDOW SIZE   : %d\n", wma.size);
+    printf("TOTAL SAMPLES : %d\n", wma.k);
+    printf("CURRENT AVG   : %d\n", wma.avg);
+    printf("\n");
+
+    @endcode
+    
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    
+ */
+/**************************************************************************/
+#include "wma_i.h"
+
+/**************************************************************************/
+/*!
+     @brief Initialises the wma_i_t instance
+
+     @param[in]  wma
+                 Pointer to the wma_i_t instance that includes the
+                 window size, a pointer to the data buffer,
+                 the current average (the output value), etc.
+*/
+/**************************************************************************/
+err_t wma_i_init ( wma_i_t *wma )
+{
+  /* Check if the window size is valid (!= 0 and is a power of 2) */
+  if (0 == wma->size) return ERROR_UNEXPECTEDVALUE;
+
+  wma->avg = 0;
+  wma->k = 0;
+  wma->sum_weight = 0;
+  
+  for (uint16_t i = 0; i < wma->size; i++)
+  {
+    wma->sum_weight += wma->weight[i];
+  }
+  
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+     @brief Adds a new value to the wma_i_t instances
+
+     @param[in]  wma
+                 Pointer to the wma_i_t instances
+     @param[in]  x
+                 Value to insert
+*/
+/**************************************************************************/
+void wma_i_add(wma_i_t *wma, int32_t x)
+{
+  int32_t *pSource = wma->buffer + wma->k % wma->size;
+
+  /* Add new value into the data buffer of the filter */
+  *pSource = x;
+
+  /* Increase the total samples processed */
+  wma->k++;
+
+  /* Wait for 'window-size' worth of samples before averaging */
+  if (wma->k < wma->size)
+    return;
+
+  /* Recalculate the total value over the entire buffer */
+  int64_t total = 0;
+  uint16_t current_pos = wma->k % wma->size;
+  for (uint16_t i = 0; i < wma->size; i++)
+  {
+    total += wma->buffer[(i + current_pos) % wma->size] * wma->weight[i];
+  }
+
+  /* Update the current average value */
+  wma->avg = (int32_t)(total / wma->sum_weight);
+}
diff --git a/reform2-lpc-fw/src/drivers/filters/ma/wma_i.h b/reform2-lpc-fw/src/drivers/filters/ma/wma_i.h
new file mode 100644
index 0000000000000000000000000000000000000000..d9670568817f9499ad854505ecd1fbcde07cad3a
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/ma/wma_i.h
@@ -0,0 +1,62 @@
+/**************************************************************************/
+/*!
+    @file     wma_i.h
+    @author   Nguyen Quang Huy, Nguyen Thien Tin
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __WMA_I_H__
+#define __WMA_I_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+typedef struct wma_i_s
+{
+  uint32_t        k;            /**< Total number of samples processed so far                           */
+  uint16_t const  size;         /**< Window size (number of samples to average)                         */
+  int32_t         avg;          /**< Current average                                                    */
+  uint8_t        *weight;       /**< Pointer to a weighted array of each sample                         */
+  uint16_t        sum_weight;   /**< The sum of the individual weights                                  */
+  int32_t        *buffer;       /**< Pointer to the input data buffer (size=window)                     */
+} wma_i_t;
+
+err_t wma_i_init ( wma_i_t *wma );
+void    wma_i_add  ( wma_i_t *wma, int32_t x );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __WMA_I_H__ */
diff --git a/reform2-lpc-fw/src/drivers/filters/ma/wma_u16.c b/reform2-lpc-fw/src/drivers/filters/ma/wma_u16.c
new file mode 100644
index 0000000000000000000000000000000000000000..09be0e41522ebb2ee80e6ae2de7fde0e1ebb9b51
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/ma/wma_u16.c
@@ -0,0 +1,138 @@
+/**************************************************************************/
+/*!
+    @file     wma_u16.c
+    @author   Nguyen Quang Huy, Nguyen Thien Tin
+    @brief    A simple moving average filter using uint16_t values
+
+    @code
+
+    // Declare a data buffer 8 values wide
+    uint16_t wma_buffer[8];
+    uint8_t wma_weight[8] = {8, 8, 16, 16, 32, 32, 128, 255};
+
+    // Now declare the filter with the window size and a buffer pointer
+    wma_u16_t wma = { .k = 0,
+                      .size = 8,
+                      .avg = 0,
+                      .weight = wma_weight,
+                      .buffer = wma_buffer };
+
+    // Initialise the moving average filter
+    if (wma_u16_init(&wma))
+    {
+      printf("Something failed during filter init!\n");
+    }
+
+    // Add some values
+    wma_u16_add(&wma, 10);
+    wma_u16_add(&wma, 20);
+    wma_u16_add(&wma, 30);
+    wma_u16_add(&wma, 35);
+    wma_u16_add(&wma, 11);
+    wma_u16_add(&wma, 35);
+    wma_u16_add(&wma, 30);
+    wma_u16_add(&wma, 20); // We should have an avg value starting here
+    wma_u16_add(&wma, 3);
+    wma_u16_add(&wma, 10);
+
+    printf("WINDOW SIZE   : %d\n", wma.size);
+    printf("TOTAL SAMPLES : %d\n", wma.k);
+    printf("CURRENT AVG   : %d\n", wma.avg);
+    printf("\n");
+
+    @endcode
+    
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    
+ */
+/**************************************************************************/
+#include "wma_u16.h"
+
+/**************************************************************************/
+/*!
+     @brief Initialises the wma_u16_t instance
+
+     @param[in]  wma
+                 Pointer to the wma_u16_t instance that includes the
+                 window size, a pointer to the data buffer,
+                 the current average (the output value), etc.
+*/
+/**************************************************************************/
+err_t wma_u16_init ( wma_u16_t *wma )
+{
+  /* Check if the window size is valid (!= 0 and is a power of 2) */
+  if (0 == wma->size) return ERROR_UNEXPECTEDVALUE;
+
+  wma->avg = 0;
+  wma->k = 0;
+  wma->sum_weight = 0;
+  
+  for (uint16_t i = 0; i < wma->size; i++)
+  {
+    wma->sum_weight += wma->weight[i];
+  }
+  
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+     @brief Adds a new value to the wma_u16_t instances
+
+     @param[in]  wma
+                 Pointer to the wma_u16_t instances
+     @param[in]  x
+                 Value to insert
+*/
+/**************************************************************************/
+void wma_u16_add(wma_u16_t *wma, uint16_t x)
+{
+  uint16_t *pSource = wma->buffer + wma->k % wma->size;
+
+  /* Add new value into the data buffer of the filter */
+  *pSource = x;
+
+  /* Increase the total samples processed */
+  wma->k++;
+
+  /* Wait for 'window-size' worth of samples before averaging */
+  if (wma->k < wma->size)
+    return;
+
+  /* Recalculate the total value over the entire buffer */
+  uint32_t total = 0;
+  uint16_t current_pos = wma->k % wma->size;
+  for (uint16_t i = 0; i < wma->size; i++)
+  {
+    total += wma->buffer[(i + current_pos) % wma->size] * wma->weight[i];
+  }
+
+  /* Update the current average value */
+  wma->avg = (uint16_t)(total / wma->sum_weight);
+}
diff --git a/reform2-lpc-fw/src/drivers/filters/ma/wma_u16.h b/reform2-lpc-fw/src/drivers/filters/ma/wma_u16.h
new file mode 100644
index 0000000000000000000000000000000000000000..7cb00e5479bea74871fdc7c728a6bb115d23724c
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/ma/wma_u16.h
@@ -0,0 +1,62 @@
+/**************************************************************************/
+/*!
+    @file     wma_u16.h
+    @author   Nguyen Quang Huy, Nguyen Thien Tin
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __WMA_U16_H__
+#define __WMA_U16_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+typedef struct wma_u16_s
+{
+  uint32_t        k;            /**< Total number of samples processed so far                           */
+  uint16_t const  size;         /**< Window size (number of samples to average)                         */
+  uint16_t        avg;          /**< Current average                                                    */
+  uint8_t        *weight;       /**< Pointer to a weighted array of each sample                         */
+  uint16_t        sum_weight;   /**< The sum of the individual weights                                  */
+  uint16_t       *buffer;       /**< Pointer to the input data buffer (size=window)                     */
+} wma_u16_t;
+
+err_t wma_u16_init ( wma_u16_t *wma );
+void    wma_u16_add  ( wma_u16_t *wma, uint16_t x );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __WMA_U16_H__ */
diff --git a/reform2-lpc-fw/src/drivers/filters/ringbuffer.h b/reform2-lpc-fw/src/drivers/filters/ringbuffer.h
new file mode 100644
index 0000000000000000000000000000000000000000..354925e5bc1acce8edf0aaf66e8db7e4d36f694f
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/filters/ringbuffer.h
@@ -0,0 +1,157 @@
+/**************************************************************************/
+/*!
+    @file     ringbuffer.h
+    @author   Nguyen Quang Huy, Nguyen Thien Tin
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+
+#ifndef __RINGBUFFER_H__
+#define __RINGBUFFER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+typedef struct _ringbuffer_t
+{
+           void *   const buffer    ; ///< buffer pointer
+           uint16_t const depth     ; ///< max items
+           uint16_t const item_size ; ///< size of each item
+  volatile uint16_t wr_idx          ; ///< write pointer
+} ringbuffer_t;
+
+#define RINGBUFFER_DEF(name, ff_depth, type) \
+  type name##_buffer[ff_depth];              \
+  ringbuffer_t name = {                      \
+      .buffer       = name##_buffer,         \
+      .depth        = ff_depth,              \
+      .item_size    = sizeof(type),          \
+  }
+
+static inline void ring_memcpy(void *pDestination, const void *pSource, size_t num) INLINE_POST;
+static inline void ring_memcpy(void *pDestination, const void *pSource, size_t num)
+{
+  unsigned char *pByteDestination;
+  unsigned char *pByteSource;
+  unsigned int  *pAlignedSource = (unsigned int *) pSource;
+  unsigned int  *pAlignedDestination = (unsigned int *) pDestination;
+
+  // If "rBuffer->item_size" is more than 4 bytes, and both dest. and source are aligned,
+  // then copy dwords
+  if ((((unsigned int) pAlignedDestination & 0x3) == 0)
+    && (((unsigned int) pAlignedSource & 0x3) == 0)
+    && (num >= 4))
+  {
+    while (num)
+    {
+      *pAlignedDestination++ = *pAlignedSource++;
+      num -= 4;
+    }
+  }
+
+  // Copy remaining bytes
+  pByteDestination = (unsigned char *) pAlignedDestination;
+  pByteSource = (unsigned char *) pAlignedSource;
+  while (num--)
+  {
+    *pByteDestination++ = *pByteSource++;
+  }
+}
+/**************************************************************************/
+/*!
+    @brief Write one byte into the ring buffer.
+
+    This function will write one byte into the array index specified by
+    the write pointer and increment the write index with no error checking
+
+    @param[in]  rBuffer
+                Pointer to the ring buffer to manipulate
+    @param[in]  pData
+                Data to add to the ring buffer
+*/
+/**************************************************************************/
+static inline void ringbuffer_write(ringbuffer_t *rBuffer, void const *pData) INLINE_POST;
+static inline void ringbuffer_write(ringbuffer_t *rBuffer, void const *pData)
+{
+  ring_memcpy( rBuffer->buffer + (rBuffer->wr_idx * rBuffer->item_size),
+               pData,
+               rBuffer->item_size );
+
+  rBuffer->wr_idx = (rBuffer->wr_idx + 1) % rBuffer->depth;
+}
+
+/**************************************************************************/
+/*!
+     @brief Copy the value at "position" of ring buffer to pBuffer
+
+     @param[in]  rBuffer
+                 Pointer to the ring buffer to manipulate
+     @param[in]  position
+                 Position of ring buffer to be read the value
+     @param[in]  pBuffer
+                 Pointer to place holder for data read from ring buffer
+*/
+/**************************************************************************/
+static inline void ringbuffer_peek(ringbuffer_t *rBuffer, uint16_t position, void * pBuffer) INLINE_POST;
+static inline void ringbuffer_peek(ringbuffer_t *rBuffer, uint16_t position, void * pBuffer)
+{
+  ring_memcpy( pBuffer,
+               rBuffer->buffer + position * rBuffer->item_size,
+               rBuffer->item_size );
+}
+
+/**************************************************************************/
+/*!
+     @brief Assign pointer "pBuffer" to the element at "position" of ring buffer
+            instead of copying its value
+
+     @param[in]  rBuffer
+                 Pointer to the ring buffer to manipulate
+     @param[in]  position
+                 Position of ring buffer to be read the value
+     @param[in]  pBuffer
+                 Returned pointer
+*/
+/**************************************************************************/
+static inline void ringbuffer_ref(ringbuffer_t *rBuffer, uint16_t position, void ** pBuffer) INLINE_POST;
+static inline void ringbuffer_ref(ringbuffer_t *rBuffer, uint16_t position, void ** pBuffer)
+{
+  *pBuffer = rBuffer->buffer + position * rBuffer->item_size;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __RINGBUFFER_H__ */
diff --git a/reform2-lpc-fw/src/drivers/motor/stepper/stepper.c b/reform2-lpc-fw/src/drivers/motor/stepper/stepper.c
new file mode 100644
index 0000000000000000000000000000000000000000..c5e67812d19601ee2ba5e393c9529548ad5186d1
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/motor/stepper/stepper.c
@@ -0,0 +1,297 @@
+/**************************************************************************/
+/*!
+    @file     stepper.c
+    @author   Based on original code by Tom Igoe
+              Modified by K. Townsend (microBuilder.eu)
+
+
+    @brief    Simple bi-polar stepper motor controller, based on the
+              Arduino stepper library by Tom Igoe.  Includes simple
+              position handling methods to keep track of the motor's
+              relative position and the spindle's current rotation.
+              Requires an H-Bridge such as the L293D or SN754410N.
+
+    @section Example
+
+    @code
+
+    stepperInit(200);         // Initialise driver for 200-step motor
+    stepperSetSpeed(60);      // Set speed to 120 rpm (2 revolutions per second)
+
+    while (1)
+    {
+      stepperStep(400);       // Move forward 400 steps
+      stepperStep(-200);      // Move backward 200 steps
+      delay(1000);     // Wait one second
+
+      // Move 'home' after 10 loops (current position = 2000)
+      if (stepperGetPosition() == 2000)
+      {
+        stepperMoveHome();    // Move back to the starting position
+        delay(1000);   // Wait one second
+      }
+    }
+
+    @endcode
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_STEPPER
+
+#include <stdlib.h>
+
+#include "stepper.h"
+#include "core/gpio/gpio.h"
+#include "core/timer32/timer32.h"
+
+static int64_t  stepperPosition = 0;          // The current position (in steps) relative to 'Home'
+static uint32_t stepperStepNumber = 0;        // The current position (in steps) relative to 0°
+static uint32_t stepperStepsPerRotation = 0;  // Number of steps in a full 360° rotation
+static uint32_t stepperStepDelay = 0;         // Delay in CPU ticks between individual steps
+
+/**************************************************************************/
+/*!
+    Private - Cause the motor to step forward or backward one step
+*/
+/**************************************************************************/
+void stepMotor(uint32_t thisStep)
+{
+  switch (thisStep)
+  {
+    case 0: // 1010
+      LPC_GPIO->SET[CFG_STEPPER_IN1_PORT] =  (1 << CFG_STEPPER_IN1_PIN);
+      LPC_GPIO->CLR[CFG_STEPPER_IN2_PORT] =  (1 << CFG_STEPPER_IN2_PIN);
+      LPC_GPIO->SET[CFG_STEPPER_IN3_PORT] =  (1 << CFG_STEPPER_IN3_PIN);
+      LPC_GPIO->CLR[CFG_STEPPER_IN4_PORT] =  (1 << CFG_STEPPER_IN4_PIN);
+      break;
+    case 1: // 0110
+      LPC_GPIO->CLR[CFG_STEPPER_IN1_PORT] =  (1 << CFG_STEPPER_IN1_PIN);
+      LPC_GPIO->SET[CFG_STEPPER_IN2_PORT] =  (1 << CFG_STEPPER_IN2_PIN);
+      LPC_GPIO->SET[CFG_STEPPER_IN3_PORT] =  (1 << CFG_STEPPER_IN3_PIN);
+      LPC_GPIO->CLR[CFG_STEPPER_IN4_PORT] =  (1 << CFG_STEPPER_IN4_PIN);
+      break;
+    case 2: // 0101
+      LPC_GPIO->CLR[CFG_STEPPER_IN1_PORT] =  (1 << CFG_STEPPER_IN1_PIN);
+      LPC_GPIO->SET[CFG_STEPPER_IN2_PORT] =  (1 << CFG_STEPPER_IN2_PIN);
+      LPC_GPIO->CLR[CFG_STEPPER_IN3_PORT] =  (1 << CFG_STEPPER_IN3_PIN);
+      LPC_GPIO->SET[CFG_STEPPER_IN4_PORT] =  (1 << CFG_STEPPER_IN4_PIN);
+      break;
+    case 3: // 1001
+      LPC_GPIO->SET[CFG_STEPPER_IN1_PORT] =  (1 << CFG_STEPPER_IN1_PIN);
+      LPC_GPIO->CLR[CFG_STEPPER_IN2_PORT] =  (1 << CFG_STEPPER_IN2_PIN);
+      LPC_GPIO->CLR[CFG_STEPPER_IN3_PORT] =  (1 << CFG_STEPPER_IN3_PIN);
+      LPC_GPIO->SET[CFG_STEPPER_IN4_PORT] =  (1 << CFG_STEPPER_IN4_PIN);
+      break;
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief      Initialises the GPIO pins and delay timer and sets any
+                default values.
+
+    @param[in]  steps
+                The number of steps per rotation (typically 200 or 400)
+*/
+/**************************************************************************/
+void stepperInit(uint32_t steps)
+{
+  // Setup motor control pins
+  LPC_GPIO->DIR[CFG_STEPPER_IN1_PORT] |=  (1 << CFG_STEPPER_IN1_PIN);
+  LPC_GPIO->DIR[CFG_STEPPER_IN2_PORT] |=  (1 << CFG_STEPPER_IN2_PIN);
+  LPC_GPIO->DIR[CFG_STEPPER_IN3_PORT] |=  (1 << CFG_STEPPER_IN3_PIN);
+  LPC_GPIO->DIR[CFG_STEPPER_IN4_PORT] |=  (1 << CFG_STEPPER_IN4_PIN);
+
+  LPC_GPIO->CLR[CFG_STEPPER_IN1_PORT] =  (1 << CFG_STEPPER_IN1_PIN);
+  LPC_GPIO->CLR[CFG_STEPPER_IN2_PORT] =  (1 << CFG_STEPPER_IN2_PIN);
+  LPC_GPIO->CLR[CFG_STEPPER_IN3_PORT] =  (1 << CFG_STEPPER_IN3_PIN);
+  LPC_GPIO->CLR[CFG_STEPPER_IN4_PORT] =  (1 << CFG_STEPPER_IN4_PIN);
+
+  // Initialise 32-bit timer (used for delays)
+  timer32Init(CFG_STEPPER_TIMER32);
+  timer32Enable(CFG_STEPPER_TIMER32);
+
+  // Set the number of steps per rotation
+  stepperStepsPerRotation = steps;
+
+  // Set the default speed (2 rotations per second)
+  stepperSetSpeed(120);
+}
+
+/**************************************************************************/
+/*!
+    @brief    Gets the current position (in steps) relative to 'Home'.
+
+    @return   The difference (in steps) of the motor's current position
+              from the original 'Home' position. Value can be negative or
+              positive depending on the direction of previous movements.
+*/
+/**************************************************************************/
+int64_t stepperGetPosition()
+{
+  return stepperPosition;
+}
+
+/**************************************************************************/
+/*!
+    @brief    Gets the motor's current rotation (in steps) relative to
+              the spindle's 'Zero' position.
+
+    @return   The current step (0 .. steps per rotation) on the motor's
+              spindle relative to 0°.  Value is always positive.
+*/
+/**************************************************************************/
+uint32_t stepperGetRotation()
+{
+  return stepperStepNumber;
+}
+
+/**************************************************************************/
+/*!
+    @brief    Sets the motor's current position to 'Home', meaning that
+              any future movement will be relative to the current
+              position.
+*/
+/**************************************************************************/
+void stepperSetHome()
+{
+  stepperPosition = 0;
+}
+
+/**************************************************************************/
+/*!
+    @brief    Moves the motor back to the original 'Home' position.
+*/
+/**************************************************************************/
+void stepperMoveHome()
+{
+  stepperStep(stepperPosition * -1);
+}
+
+/**************************************************************************/
+/*!
+    @brief    Saves the spindle's current angle/position as 0°.  Each
+              step the spindle takes will now be relative to the spindle's
+              current position.
+*/
+/**************************************************************************/
+void stepperSetZero()
+{
+  stepperStepNumber = 0;
+}
+
+/**************************************************************************/
+/*!
+    @brief    Moves the motor to its original rotation value. For example,
+              if a 200-step motor is currently rotated to step 137, it
+              will move the motor forward 63 steps to end at step 0 or 0°.
+*/
+/**************************************************************************/
+void stepperMoveZero()
+{
+  if (!stepperStepNumber)
+  {
+    stepperStep(stepperStepsPerRotation - stepperStepNumber);
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief    Sets the motor speed in rpm, meaning the number of times the
+              motor will fully rotate in a one minute period.
+
+    @param[in]  rpm
+                Motor speed in revolutions per minute (RPM)
+
+    @warning  Not all motors will function at all speeds, and some trial
+              and error may be required to find an appropriate speed for
+              the motor.
+*/
+/**************************************************************************/
+void stepperSetSpeed(uint32_t rpm)
+{
+  uint32_t ticksOneRPM = (SystemCoreClock / stepperStepsPerRotation) * 60;
+
+  // Set stepper RPM
+  stepperStepDelay = ticksOneRPM / rpm;
+}
+
+/**************************************************************************/
+/*!
+    @brief      Moves the motor forward or backward the specified number
+                of steps.  A positive number moves the motor forward,
+                while a negative number moves the motor backwards.
+
+    @param[in]  steps
+                The number of steps to move foreward (positive) or
+                backward (negative)
+*/
+/**************************************************************************/
+void stepperStep(int32_t steps)
+{
+  uint32_t stepsLeft = abs(steps);          // Force number to be positive
+
+  while (stepsLeft > 0)
+  {
+    // Wait x ticks between individual steps
+    timer32DelayTicks(CFG_STEPPER_TIMER32, stepperStepDelay);
+
+    // Increment or decrement step counters (depending on direction)
+    if (steps > 0)
+    {
+      stepperPosition++;          // Increment global position counter
+      stepperStepNumber++;        // Increment single rotation counter
+      if (stepperStepNumber == stepperStepsPerRotation)
+      {
+        stepperStepNumber = 0;
+      }
+    }
+    else
+    {
+      stepperPosition--;          // Decrement global position counter
+      if (stepperStepNumber == 0)
+      {
+        stepperStepNumber = stepperStepsPerRotation;
+      }
+      stepperStepNumber--;        // Decrement single rotation counter
+    }
+
+    // Decrement number of remaining steps
+    stepsLeft--;
+
+    // Step the motor one step
+    stepMotor(stepperStepNumber % 4);
+  }
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/motor/stepper/stepper.h b/reform2-lpc-fw/src/drivers/motor/stepper/stepper.h
new file mode 100644
index 0000000000000000000000000000000000000000..f29669d75b274b8e8cbab8c9085603e6d20bd0a8
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/motor/stepper/stepper.h
@@ -0,0 +1,52 @@
+/**************************************************************************/
+/*!
+    @file     stepper.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+
+#ifndef _STEPPER_H_
+#define _STEPPER_H_
+
+#include "projectconfig.h"
+
+void     stepperInit( uint32_t steps );
+void     stepperSetSpeed( uint32_t rpm );
+int64_t  stepperGetPosition();
+uint32_t stepperGetRotation();
+void     stepperMoveHome();
+void     stepperSetHome();
+void     stepperMoveZero();
+void     stepperSetZero();
+void     stepperStep( int32_t steps );
+
+#endif
\ No newline at end of file
diff --git a/reform2-lpc-fw/src/drivers/pwm/pca9685/pca9685.c b/reform2-lpc-fw/src/drivers/pwm/pca9685/pca9685.c
new file mode 100644
index 0000000000000000000000000000000000000000..37693466a4c32c0332b633a04d60d927e63f541f
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/pwm/pca9685/pca9685.c
@@ -0,0 +1,255 @@
+/**************************************************************************/
+/*!
+    @file     pca9685.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Drivers for NXP's PCA9685 12-bit 16-channel PWM Driver
+
+    @section DESCRIPTION
+
+    The PCA9685 is an I2C-bus controlled 16-channel LED controller
+    optimized for LCD Red/Green/Blue/Amber (RGBA) color backlighting
+    applications. Each LED output has its own 12-bit resolution (4096
+    steps) fixed frequency individual PWM controller that operates at a
+    programmable frequency from 40 Hz to 1000 Hz with a duty cycle that
+    is adjustable from 0 % to 100 % to allow the LED to be set to a
+    specific brightness value. All outputs are set to the same PWM
+    frequency.
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <string.h>
+#include "pca9685.h"
+#include "core/gpio/gpio.h"
+#include "core/delay/delay.h"
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+static bool _pca9685Initialised = false;
+static uint8_t _pca9685Address = PCA9685_ADDRESS;
+
+/**************************************************************************/
+/*!
+    @brief  Writes the specified number of bytes over I2C
+*/
+/**************************************************************************/
+err_t pca9685WriteBytes(uint8_t reg, uint8_t *buffer, size_t length)
+{
+  uint32_t i;
+
+  /* Try to avoid buffer overflow */
+  ASSERT(length <= I2C_BUFSIZE - 2, ERROR_BUFFEROVERFLOW);
+
+  /* Fill write buffer */
+  for ( i = 2; i < length+2; i++ )
+  {
+    I2CMasterBuffer[i] = buffer[i-2];
+  }
+
+  /* Write transaction */
+  I2CWriteLength = 2+length;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = _pca9685Address;
+  I2CMasterBuffer[1] = reg;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the specified number of bytes over I2C
+*/
+/**************************************************************************/
+err_t pca9685ReadBytes(uint8_t reg, uint8_t *buffer, size_t length)
+{
+  uint32_t i;
+
+  /* Try to avoid buffer overflow */
+  ASSERT(length <= I2C_BUFSIZE, ERROR_BUFFEROVERFLOW);
+
+  /* Read and write need to be handled in separate transactions or the
+     PCA9685 increments the current register one step ahead of where
+     we should be. */
+
+  /* Write transaction */
+  I2CWriteLength = 2;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = _pca9685Address;
+  I2CMasterBuffer[1] = reg;
+  i2cEngine();
+
+  /* Read transaction */
+  I2CWriteLength = 0;
+  I2CReadLength = length;
+  I2CMasterBuffer[0] = _pca9685Address | PCA9685_READBIT;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  /* Fill the buffer with the I2C response */
+  for ( i = 0; i < length; i++ )
+  {
+    buffer[i] = I2CSlaveBuffer[i];
+  }
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Writes an 8 bit value over I2C
+*/
+/**************************************************************************/
+err_t pca9685Write8 (uint8_t reg, uint8_t value)
+{
+  uint8_t buffer = value;
+  return pca9685WriteBytes(reg, &buffer, 1);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads a single byte over I2C
+*/
+/**************************************************************************/
+err_t pca9685Read8(uint8_t reg, uint8_t *result)
+{
+  return pca9685ReadBytes(reg, result, 1);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Initialises the I2C block
+
+    @param address  The device I2C address (left-shifted 1 bit)
+*/
+/**************************************************************************/
+err_t pca9685Init(uint8_t address)
+{
+  // Initialise I2C
+  i2cInit(I2CMASTER);
+
+  /* Ping the I2C device first to see if it exists! */
+  ASSERT(!(i2cCheckAddress(_pca9685Address)), ERROR_I2C_DEVICENOTFOUND);
+
+  ASSERT_STATUS(pca9685Write8(PCA9685_REG_MODE1, 0x00));
+
+  _pca9685Initialised = true;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the PWM clock frequency (40-1000Hz)
+
+    @param freqHz  Approximate frequency in Hz (40-1000)
+*/
+/**************************************************************************/
+err_t pca9685SetFrequency(uint16_t freqHz)
+{
+  uint32_t prescaleValue;
+  uint8_t oldMode, newMode;
+
+  ASSERT(_pca9685Initialised, ERROR_DEVICENOTINITIALISED);
+
+  if (freqHz < 40)
+  {
+    freqHz = 40;
+  }
+
+  if (freqHz > 1000)
+  {
+    freqHz = 1000;
+  }
+
+  // prescaleValue = round(25MHz / (4096*updateRate)) - 1
+  prescaleValue = 25000000;   // 25 MHz
+  prescaleValue /= 4096;      // 12-bit
+  prescaleValue /= freqHz;
+  prescaleValue -= 1;
+
+  ASSERT_STATUS(pca9685Read8(PCA9685_REG_MODE1, &oldMode));
+  newMode = (oldMode & 0x7F) | 0x10;
+
+  // Go to sleep
+  ASSERT_STATUS(pca9685Write8(PCA9685_REG_MODE1, newMode));
+
+  // Set prescale
+  ASSERT_STATUS(pca9685Write8(PCA9685_REG_PRESCALE, prescaleValue & 0xFF));
+
+  // Wakeup
+  ASSERT_STATUS(pca9685Write8(PCA9685_REG_MODE1, oldMode));
+  delay(5);
+  ASSERT_STATUS(pca9685Write8(PCA9685_REG_MODE1, oldMode | 0x80));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the PWM output of the specified channel
+
+    @param channel  The channel number [0..15]
+    @param on       The 12-bit start point (low to high transition)
+    @param off      The 12-bit stop point (high to low transition)
+*/
+/**************************************************************************/
+err_t pca9685SetPWM(uint16_t channel, uint16_t on, uint16_t off)
+{
+  ASSERT(_pca9685Initialised, ERROR_DEVICENOTINITIALISED);
+
+  if (on > 0xFFF)
+  {
+    on = 0xFFF;
+  }
+
+  if (off < on)
+  {
+    off = on;
+  }
+
+  if (off > 0xFFF)
+  {
+    off = 0xFFF;
+  }
+
+  /* Set the on and off values */
+  ASSERT_STATUS(pca9685Write8(PCA9685_REG_LED0_ON_L+4*channel, on & 0xFF));
+  ASSERT_STATUS(pca9685Write8(PCA9685_REG_LED0_ON_H+4*channel, on >> 8));
+  ASSERT_STATUS(pca9685Write8(PCA9685_REG_LED0_OFF_L+4*channel, off & 0xFF));
+  ASSERT_STATUS(pca9685Write8(PCA9685_REG_LED0_OFF_H+4*channel, off >> 8));
+
+  return ERROR_NONE;
+}
+
diff --git a/reform2-lpc-fw/src/drivers/pwm/pca9685/pca9685.h b/reform2-lpc-fw/src/drivers/pwm/pca9685/pca9685.h
new file mode 100644
index 0000000000000000000000000000000000000000..564364157712c6ac7c92a6cb0458a020332e4d58
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/pwm/pca9685/pca9685.h
@@ -0,0 +1,74 @@
+/**************************************************************************/
+/*!
+    @file     pca9685.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012 K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _PCA9685_H_
+#define _PCA9685_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "core/i2c/i2c.h"
+
+#define PCA9685_ADDRESS           (0x40<<1)    // 1000000
+#define PCA9685_READBIT           (0x01)
+
+enum
+{
+  PCA9685_REG_SUBADR1            = 0x02,
+  PCA9685_REG_SUBADR2            = 0x03,
+  PCA9685_REG_SUBADR3            = 0x04,
+  PCA9685_REG_MODE1              = 0x00,
+  PCA9685_REG_PRESCALE           = 0xFE,
+  PCA9685_REG_LED0_ON_L          = 0x06,
+  PCA9685_REG_LED0_ON_H          = 0x07,
+  PCA9685_REG_LED0_OFF_L         = 0x08,
+  PCA9685_REG_LED0_OFF_H         = 0x09,
+  PCA9685_REG_ALLLED_ON_L        = 0xFA,
+  PCA9685_REG_ALLLED_ON_H        = 0xFB,
+  PCA9685_REG_ALLLED_OFF_L       = 0xFC,
+  PCA9685_REG_ALLLED_OFF_H       = 0xFD
+};
+
+err_t pca9685Init (uint8_t address);
+err_t pca9685SetFrequency (uint16_t freqHz);
+err_t pca9685SetPWM (uint16_t channel, uint16_t on, uint16_t off);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb.c b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb.c
new file mode 100644
index 0000000000000000000000000000000000000000..07a7fbd641f03294cdf9d490d12d1f1a5dc3a445
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb.c
@@ -0,0 +1,236 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_CHIBI
+
+#include <stdio.h>
+#include <string.h>
+
+#include "chb.h"
+#include "chb_drvr.h"
+#include "chb_buf.h"
+
+static chb_pcb_t chibi_pcb;
+// these are for the duplicate checking and rejection
+static U8 prev_seq = 0xFF;
+static U16 prev_src_addr = 0xFFFE;
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+err_t chb_init()
+{
+    memset(&chibi_pcb, 0, sizeof(chb_pcb_t));
+    chibi_pcb.src_addr = chb_get_short_addr();
+    return chb_drvr_init();
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+chb_pcb_t *chb_get_pcb()
+{
+    return &chibi_pcb;
+}
+
+/**************************************************************************/
+/*!
+    Requires the dest addr, location to store data, and len of payload.
+    Returns the length of the hdr.
+*/
+/**************************************************************************/
+static U8 chb_gen_hdr(U8 *hdr, U16 addr, U8 len)
+{
+    U8 *hdr_ptr = hdr;
+
+    // calc frame size and put in 0 position of array
+    // frame size = hdr sz + payload len + fcs len
+    *hdr_ptr++ = CHB_HDR_SZ + len + CHB_FCS_LEN;
+
+    // use default fcf byte 0 val but test for ack request. we won't request
+    // ack if broadcast. all other cases we will.
+    *hdr_ptr++ = CHB_FCF_BYTE_0 | ((addr != 0xFFFF) << CHB_ACK_REQ_POS);
+    *hdr_ptr++ = CHB_FCF_BYTE_1;
+
+    *hdr_ptr++ = chibi_pcb.seq++;
+
+    // fill out dest pan ID, dest addr, src addr
+    *(U16 *)hdr_ptr = CFG_CHIBI_PANID;
+    hdr_ptr += sizeof(U16);
+    *(U16 *)hdr_ptr = addr;
+    hdr_ptr += sizeof(U16);
+    *(U16 *)hdr_ptr = chibi_pcb.src_addr;
+    hdr_ptr += sizeof(U16);
+
+    // return the len of the header
+    return hdr_ptr - hdr;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+U8 chb_write(U16 addr, U8 *data, U8 len)
+{
+    // U8 status, frm_len, hdr_len, hdr[CHB_HDR_SZ + 1];
+    U8 status, frm_len, hdr[CHB_HDR_SZ + 1];
+
+    while (len > 0)
+    {
+        // calculate which frame len to use. if greater than max payload, split
+        // up operation.
+        frm_len = (len > CHB_MAX_PAYLOAD) ? CHB_MAX_PAYLOAD : len;
+
+        // gen frame header
+        // hdr_len = chb_gen_hdr(hdr, addr, frm_len);
+        chb_gen_hdr(hdr, addr, frm_len);
+
+        // send data to chip
+        status = chb_tx(hdr, data, frm_len);
+
+        if (status != CHB_SUCCESS)
+        {
+            switch (status)
+            {
+            case RADIO_SUCCESS:
+                // fall through
+            case CHB_SUCCESS_DATA_PENDING:
+                chibi_pcb.txd_success++;
+                break;
+
+            case CHB_NO_ACK:
+                chibi_pcb.txd_noack++;
+                break;
+
+            case CHB_CHANNEL_ACCESS_FAILURE:
+                chibi_pcb.txd_channel_fail++;
+                break;
+
+            default:
+                break;
+            }
+            return status;
+        }
+
+        // adjust len and restart
+        len = len - frm_len;
+    }
+    return CHB_SUCCESS;
+}
+
+/**************************************************************************/
+/*!
+    Read data from the buffer. Need to pass in a buffer of at leasts max frame
+    size and two 16-bit containers for the src and dest addresses.
+
+    The read function will automatically populate the addresses and the data with
+    the frm payload. It will then return the len of the payload.
+*/
+/**************************************************************************/
+U8 chb_read(chb_rx_data_t *rx)
+{
+    U8 i, len, seq, *data_ptr;
+
+    data_ptr = rx->data;
+
+    // first byte is always len. check it to make sure
+    // we have a valid len byte.
+    if ((len = chb_buf_read()) > CHB_MAX_FRAME_LENGTH)
+    {
+        return 0;
+    }
+    *data_ptr++ = len;
+
+    // load the rest of the data into buffer
+    for (i=0; i<len; i++)
+    {
+        *data_ptr++ = chb_buf_read();
+    }
+
+    // we're using the buffer that's fed in as an argument as a temp
+    // buffer as well to save resources.
+    // we'll use it as temp storage to parse the frame. then move the frame
+    // down so that only the payload will be in the buffer.
+
+    // extract the sequence number
+    data_ptr = rx->data + 3;    // location of sequence number
+    seq = *data_ptr;
+
+    // parse the buffer and extract the dest and src addresses
+    data_ptr = rx->data + 6;                // location of dest addr
+    rx->dest_addr = *(U16 *)data_ptr;
+    data_ptr += sizeof(U16);
+    rx->src_addr = *(U16 *)data_ptr;
+    data_ptr += sizeof(U16);
+
+    // if the data in the rx buf is 0, then clear the rx_flag. otherwise, keep it raised
+    if (!chb_buf_get_len())
+    {
+        chibi_pcb.data_rcv = false;
+    }
+
+#if (CFG_CHIBI_PROMISCUOUS == 1)
+    // if we're in promiscuous mode, we don't want to do any duplicate rejection and we don't want to move the payload
+    // to the front of the buffer. We want to capture the full frame so just keep the frame intact and return the length.
+    return len;
+#else
+    // duplicate frame check (dupe check). we want to remove frames that have been already been received since they
+    // are just retries.
+    // note: this dupe check only removes duplicate frames from the previous transfer. if another frame from a different
+    // node comes in between the dupes, then the dupe will show up as a received frame.
+    if ((seq == prev_seq) && (rx->src_addr == prev_src_addr))
+    {
+        // this is a duplicate frame from a retry. the remote node thinks we didn't receive
+        // it properly. discard.
+        return 0;
+    }
+    else
+    {
+        prev_seq = seq;
+        prev_src_addr = rx->src_addr;
+    }
+
+    // move the payload down to the beginning of the data buffer
+    memmove(rx->data, data_ptr, len - CHB_HDR_SZ);
+    // finally, return the len of the payload
+    return len - CHB_HDR_SZ - CHB_FCS_LEN;
+#endif
+}
+
+#endif /* CFG_CHIBI */
diff --git a/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb.h b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb.h
new file mode 100644
index 0000000000000000000000000000000000000000..3aceec63b4902a5e173e84e7b6c3167db1e2dc9d
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb.h
@@ -0,0 +1,109 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+#ifndef CHIBI_H
+#define CHIBI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "types.h"
+#include "errors.h"
+
+#define CHB_HDR_SZ        9    // FCF + seq + pan_id + dest_addr + src_addr (2 + 1 + 2 + 2 + 2)
+#define CHB_FCS_LEN       2
+#define CHB_MAX_PAYLOAD   100
+
+
+// frame_type = data
+// security enabled = false
+// frame pending = false
+// ack request = false
+// pan ID compression = true
+#define CHB_FCF_BYTE_0    0x41
+
+// dest addr = 16-bit
+// frame version = 802.15.4 (not 2003)
+// src addr = 16-bit
+#define CHB_FCF_BYTE_1    0x98
+
+#define CHB_ACK_REQ_POS   5
+
+enum
+{
+    CHB_SUCCESS                 = 0,
+    CHB_SUCCESS_DATA_PENDING    = 1,
+    CHB_CHANNEL_ACCESS_FAILURE  = 3,
+    CHB_NO_ACK                  = 5,
+    CHB_INVALID                 = 7
+};
+
+// Chibi Protocol control block
+typedef struct
+{
+    U16 src_addr;
+    U8 seq;
+    volatile bool data_rcv;
+    volatile bool tx_end;
+
+    // stats
+    U16 rcvd_xfers;
+    U16 txd_success;
+    U16 txd_noack;
+    U16 txd_channel_fail;
+    U16 overflow;
+    U16 underrun;
+    U8 battlow;
+    U8 ed;
+    U8 crc;
+} chb_pcb_t;
+
+typedef struct
+{
+    U8 len;
+    U16 src_addr;
+    U16 dest_addr;
+    U8 data[CHB_MAX_PAYLOAD];
+} chb_rx_data_t;
+
+err_t chb_init(void);
+chb_pcb_t *chb_get_pcb(void);
+U8 chb_write(U16 addr, U8 *data, U8 len);
+U8 chb_read(chb_rx_data_t *rx);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_buf.c b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_buf.c
new file mode 100644
index 0000000000000000000000000000000000000000..228ec1e830b0eeb6bd38688efe005229cad2fa15
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_buf.c
@@ -0,0 +1,100 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_CHIBI
+
+#include <stdio.h>
+#include "chb_buf.h"
+
+static U8 chb_buf[CFG_CHIBI_BUFFERSIZE];
+
+static volatile U32 rd_ptr, wr_ptr;
+static volatile U32 len;
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_buf_init()
+{
+    rd_ptr = 0;
+    wr_ptr = 0;
+    len = 0;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_buf_write(U8 data)
+{
+    chb_buf[wr_ptr] = data;
+    wr_ptr = (wr_ptr + 1) % CFG_CHIBI_BUFFERSIZE;
+    len++;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+U8 chb_buf_read()
+{
+    U8 data;
+    data = chb_buf[rd_ptr];
+    rd_ptr = (rd_ptr + 1) % CFG_CHIBI_BUFFERSIZE;
+
+    // Protect the len update, otherwise it could get corrupted if an
+    // interrupt occurs here
+    __disable_irq();
+    len--;
+    __enable_irq();
+
+    return data;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+U32 chb_buf_get_len()
+{
+    return len;
+}
+
+#endif /* CFG_CHIBI */
diff --git a/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_buf.h b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_buf.h
new file mode 100644
index 0000000000000000000000000000000000000000..07c68de4d19eef74671deb4c016983e00b470b5f
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_buf.h
@@ -0,0 +1,52 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+#ifndef CHB_BUF_H
+#define CHB_BUF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "types.h"
+
+void chb_buf_init(void);
+void chb_buf_write(U8 data);
+U8 chb_buf_read(void);
+U32 chb_buf_get_len(void);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_drvr.c b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_drvr.c
new file mode 100644
index 0000000000000000000000000000000000000000..832e53d2c5113dfeb758376b6c7f9210b32f408c
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_drvr.c
@@ -0,0 +1,909 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_CHIBI
+
+#include <stdio.h>
+#include "chb.h"
+#include "chb_drvr.h"
+#include "chb_buf.h"
+#include "chb_spi.h"
+#include "chb_eeprom.h"
+
+// #if defined CFG_MCU_LPC1347FBD48
+//   #include "core/dwt/dwt.h"           // Cortex M3 only!
+// #endif
+
+// store string messages in flash rather than RAM
+const char chb_err_overflow[] = "BUFFER FULL. TOSSING INCOMING DATA\r\n";
+const char chb_err_init[] = "RADIO NOT INITIALIZED PROPERLY\r\n";
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+static U8 chb_get_state()
+{
+    return chb_reg_read(TRX_STATUS) & 0x1f;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+static U8 chb_get_status()
+{
+    return chb_reg_read(TRX_STATE) >> CHB_TRAC_STATUS_POS;
+}
+
+/**************************************************************************/
+/*!
+    Cause a blocking delay for x microseconds
+*/
+/**************************************************************************/
+static void chb_delay_us(U16 usec)
+{
+//  uint32_t ticks = (SystemCoreClock / 1000000) * usec;
+//  #if defined CFG_MCU_FAMILY_LPC13UXX
+//    dwtDelay(ticks);
+//  #endif
+//
+//  #if defined CFG_MCU_FAMILY_LPC11UXX
+    uint32_t i;
+    for (i = (SystemCoreClock / 1000000) * usec; i; i--)
+    {
+      __NOP();
+    }
+//  #endif
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+err_t chb_reset()
+{
+    CHB_RST_DISABLE();
+    CHB_SLPTR_DISABLE();
+
+    // wait a bit while transceiver wakes up
+    chb_delay_us(TIME_P_ON_TO_CLKM_AVAIL);
+
+    // reset the device
+    CHB_RST_ENABLE();
+    chb_delay_us(TIME_RST_PULSE_WIDTH);
+    CHB_RST_DISABLE();
+
+    // check that we have the part number that we're expecting
+    // if you're stuck here, that means that you're not reading
+    // the version and part number register correctly. possible that version number
+    // changes. if so, update version num in header file
+    if ((chb_reg_read(VERSION_NUM) == CHB_AT86RF212_VER_NUM) && (chb_reg_read(PART_NUM) == CHB_AT86RF212_PART_NUM))
+    {
+      return ERROR_NONE;
+    }
+    else
+    {
+      return ERROR_DEVICENOTINITIALISED;
+    }
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+U8 chb_reg_read(U8 addr)
+{
+    U8 val = 0;
+
+    /* Add the register read command to the register address. */
+    addr |= 0x80;
+
+    CHB_ENTER_CRIT();
+    CHB_SPI_ENABLE();
+
+    /*Send Register address and read register content.*/
+    val = chb_xfer_byte(addr);
+    val = chb_xfer_byte(val);
+
+    CHB_SPI_DISABLE();
+    CHB_LEAVE_CRIT();
+
+    return val;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+U16 chb_reg_read16(U8 addr)
+{
+    U8 i;
+    U16 val = 0;
+
+    for (i=0; i<2; i++)
+    {
+        addr |= chb_reg_read(addr + i) << (8 * i);
+    }
+    return val;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_reg_write(U8 addr, U8 val)
+{
+    /* Add the Register Write command to the address. */
+    addr |= 0xC0;
+
+    CHB_ENTER_CRIT();
+    CHB_SPI_ENABLE();
+
+    /*Send Register address and write register content.*/
+    chb_xfer_byte(addr);
+    chb_xfer_byte(val);
+
+    CHB_SPI_DISABLE();
+    CHB_LEAVE_CRIT();
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_reg_write16(U8 addr, U16 val)
+{
+    U8 i;
+
+    for (i=0; i<2; i++)
+    {
+        chb_reg_write(addr + i, val >> (8 * i));
+    }
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_reg_write64(U8 addr, U8 *val)
+{
+    U8 i;
+
+    for (i=0; i<8; i++)
+    {
+        chb_reg_write(addr + i, *(val + i));
+    }
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_reg_read_mod_write(U8 addr, U8 val, U8 mask)
+{
+    U8 tmp;
+
+    tmp = chb_reg_read(addr);
+    val &= mask;                // mask off stray bits from val
+    tmp &= ~mask;               // mask off bits in reg val
+    tmp |= val;                 // copy val into reg val
+    chb_reg_write(addr, tmp);   // write back to reg
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_frame_write(U8 *hdr, U8 hdr_len, U8 *data, U8 data_len)
+{
+    U8 i;
+
+    // dont allow transmission longer than max frame size
+    if ((hdr_len + data_len) > 127)
+    {
+        return;
+    }
+
+    // initiate spi transaction
+    CHB_ENTER_CRIT();
+    CHB_SPI_ENABLE();
+
+    // send fifo write command
+    chb_xfer_byte(CHB_SPI_CMD_FW);
+
+    // write hdr contents to fifo
+    for (i=0; i<hdr_len; i++)
+    {
+        chb_xfer_byte(*hdr++);
+    }
+
+    // write data contents to fifo
+    for (i=0; i<data_len; i++)
+    {
+        chb_xfer_byte(*data++);
+    }
+
+    // terminate spi transaction
+    CHB_SPI_DISABLE();
+    CHB_LEAVE_CRIT();
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+static void chb_frame_read()
+{
+    U8 i, len, data;
+
+    // CHB_ENTER_CRIT();
+    CHB_SPI_ENABLE();
+
+    /*Send frame read command and read the length.*/
+    chb_xfer_byte(CHB_SPI_CMD_FR);
+    len = chb_xfer_byte(0);
+
+    /*Check for correct frame length.*/
+    if ((len >= CHB_MIN_FRAME_LENGTH) && (len <= CHB_MAX_FRAME_LENGTH))
+    {
+        // check to see if there is room to write the frame in the buffer. if not, then drop it
+        if (len < (CFG_CHIBI_BUFFERSIZE - chb_buf_get_len()))
+        {
+            chb_buf_write(len);
+
+            for (i=0; i<len; i++)
+            {
+                data = chb_xfer_byte(0);
+                chb_buf_write(data);
+            }
+        }
+        else
+        {
+            // we've overflowed the buffer. toss the data and do some housekeeping
+            chb_pcb_t *pcb = chb_get_pcb();
+
+            // read out the data and throw it away
+            for (i=0; i<len; i++)
+            {
+                data = chb_xfer_byte(0);
+            }
+
+            // Increment the overflow stat
+            pcb->overflow++;
+
+            // print the error message
+            printf(chb_err_overflow);
+        }
+    }
+
+    CHB_SPI_DISABLE();
+    CHB_LEAVE_CRIT();
+}
+
+/**************************************************************************/
+/*!
+    Read directly from the SRAM on the radio. This is only used for debugging
+    purposes.
+*/
+/**************************************************************************/
+#ifdef CHB_DEBUG
+void chb_sram_read(U8 addr, U8 len, U8 *data)
+{
+    U8 i, dummy;
+
+    CHB_ENTER_CRIT();
+    CHB_SPI_ENABLE();
+
+    /*Send SRAM read command.*/
+    dummy = chb_xfer_byte(CHB_SPI_CMD_SR);
+
+    /*Send address where to start reading.*/
+    dummy = chb_xfer_byte(addr);
+
+    for (i=0; i<len; i++)
+    {
+        *data++ = chb_xfer_byte(0);
+    }
+
+    CHB_SPI_DISABLE();
+    CHB_LEAVE_CRIT();
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_sram_write(U8 addr, U8 len, U8 *data)
+{
+    U8 i, dummy;
+
+    CHB_ENTER_CRIT();
+    CHB_SPI_ENABLE();
+
+    /*Send SRAM write command.*/
+    dummy = chb_xfer_byte(CHB_SPI_CMD_SW);
+
+    /*Send address where to start writing to.*/
+    dummy = chb_xfer_byte(addr);
+
+    for (i=0; i<len; i++)
+    {
+        dummy = chb_xfer_byte(*data++);
+    }
+
+    CHB_SPI_DISABLE();
+    CHB_LEAVE_CRIT();
+}
+#endif
+
+/**************************************************************************/
+/*!
+    Set the channel mode, BPSK, OQPSK, etc...
+*/
+/**************************************************************************/
+void chb_set_mode(U8 mode)
+{
+    switch (mode)
+    {
+    case OQPSK_868MHZ:
+        chb_reg_read_mod_write(TRX_CTRL_2, 0x08, 0x3f);                 // 802.15.4-2006, channel page 2, channel 0 (868 MHz, Europe)
+        chb_reg_read_mod_write(RF_CTRL_0, CHB_OQPSK_TX_OFFSET, 0x3);    // this is according to table 7-16 in at86rf212 datasheet
+        break;
+    case OQPSK_915MHZ:
+        chb_reg_read_mod_write(TRX_CTRL_2, 0x0c, 0x3f);                 // 802.15.4-2006, channel page 2, channels 1-10 (915 MHz, US)
+        chb_reg_read_mod_write(RF_CTRL_0, CHB_OQPSK_TX_OFFSET, 0x3);    // this is according to table 7-16 in at86rf212 datasheet
+        break;
+    case OQPSK_780MHZ:
+        chb_reg_read_mod_write(TRX_CTRL_2, 0x1c, 0x3f);                 // 802.15.4-2006, channel page 5, channel 0-3 (780 MHz, China)
+        chb_reg_read_mod_write(RF_CTRL_0, CHB_OQPSK_TX_OFFSET, 0x3);    // this is according to table 7-16 in at86rf212 datasheet
+        break;
+    case BPSK40_915MHZ:
+        chb_reg_read_mod_write(TRX_CTRL_2, 0x00, 0x3f);                 // 802.15.4-2006, BPSK, 40 kbps
+        chb_reg_read_mod_write(RF_CTRL_0, CHB_BPSK_TX_OFFSET, 0x3);     // this is according to table 7-16 in at86rf212 datasheet
+        break;
+    case BPSK20_868MHZ:
+        chb_reg_read_mod_write(TRX_CTRL_2, 0x00, 0x3f);                 // 802.15.4-2006, BPSK, 20 kbps
+        chb_reg_read_mod_write(RF_CTRL_0, CHB_BPSK_TX_OFFSET, 0x3);     // this is according to table 7-16 in at86rf212 datasheet
+        break;
+    }
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+U8 chb_set_channel(U8 channel)
+{
+    U8 state;
+
+#if (CHB_CHINA == 1)
+
+    // this if for China only which uses a 780 MHz frequency band
+    if ((chb_reg_read(TRX_CTRL2) & 0x3f) != 0x1c)
+    {
+        chb_reg_read_mod_write(TRX_CTRL2, 0x1c, 0x3f);
+    }
+
+    if (channel > 3)
+    {
+        channel = 0;
+    }
+
+    channel = (channel << 1) + 11;
+
+    chb_reg_read_mod_write(CC_CTRL_1, 0x4, 0x7);                // set 769 MHz base frequency for China
+    chb_reg_write(CC_CTRL_0, channel);                          // set the center frequency for the channel
+
+#else
+    //if (channel == 0)
+    //{
+    //    // Channel 0 is for European use only. make sure we are using channel page 2,
+    //    // channel 0 settings for 100 kbps
+    //    if ((chb_reg_read(TRX_CTRL_2) & 0x3f) != 0x08)
+    //    {
+    //        chb_reg_read_mod_write(TRX_CTRL_2, 0x08, 0x3f);
+    //    }
+    //}
+    //else if (channel > 10)
+    //{
+    //    // if the channel is out of bounds for page 2, then default to channel 1 and
+    //    // assume we're on the US frequency of 915 MHz
+    //    channel = 1;
+    //    if ((chb_reg_read(TRX_CTRL_2) & 0x3f) != 0x0c)
+    //    {
+    //        chb_reg_read_mod_write(TRX_CTRL_2, 0x0c, 0x3f);
+    //    }
+    //}
+    //else
+    //{
+    //    // Channels 1-10 are for US frequencies of 915 MHz
+    //    if ((chb_reg_read(TRX_CTRL_2) & 0x3f) != 0x0c)
+    //    {
+    //        chb_reg_read_mod_write(TRX_CTRL_2, 0x0c, 0x3f);
+    //    }
+    //}
+
+    chb_reg_read_mod_write(PHY_CC_CCA, channel, 0x1f);
+#endif
+
+    // add a delay to allow the PLL to lock if in active mode.
+    state = chb_get_state();
+    if ((state == RX_ON) || (state == PLL_ON))
+    {
+        chb_delay_us(TIME_PLL_LOCK_TIME);
+    }
+
+    return ((chb_reg_read(PHY_CC_CCA) & 0x1f) == channel) ? RADIO_SUCCESS : RADIO_TIMED_OUT;
+}
+
+/**************************************************************************/
+/*!
+    Set the power level
+*/
+/**************************************************************************/
+void chb_set_pwr(U8 val)
+{
+    chb_reg_write(PHY_TX_PWR, val);
+}
+
+/**************************************************************************/
+/*!
+    Set the TX/RX state machine state. Some manual manipulation is required
+    for certain operations. Check the datasheet for more details on the state
+    machine and manipulations.
+*/
+/**************************************************************************/
+U8 chb_set_state(U8 state)
+{
+    U8 curr_state, delay;
+
+    // if we're sleeping then don't allow transition
+    if (GPIOGetPinValue(CFG_CHIBI_SLPTRPORT, CFG_CHIBI_SLPTRPIN))
+    {
+        return RADIO_WRONG_STATE;
+    }
+
+    // if we're in a transition state, wait for the state to become stable
+    curr_state = chb_get_state();
+    if ((curr_state == BUSY_TX_ARET) || (curr_state == BUSY_RX_AACK) || (curr_state == BUSY_RX) || (curr_state == BUSY_TX))
+    {
+        while (chb_get_state() == curr_state);
+    }
+
+    // At this point it is clear that the requested new_state is:
+    // TRX_OFF, RX_ON, PLL_ON, RX_AACK_ON or TX_ARET_ON.
+    // we need to handle some special cases before we transition to the new state
+    switch (state)
+    {
+    case TRX_OFF:
+        /* Go to TRX_OFF from any state. */
+        CHB_SLPTR_DISABLE();
+        chb_reg_read_mod_write(TRX_STATE, CMD_FORCE_TRX_OFF, 0x1f);
+        chb_delay_us(TIME_ALL_STATES_TRX_OFF);
+        break;
+
+    case TX_ARET_ON:
+        if (curr_state == RX_AACK_ON)
+        {
+            /* First do intermediate state transition to PLL_ON, then to TX_ARET_ON. */
+            chb_reg_read_mod_write(TRX_STATE, CMD_PLL_ON, 0x1f);
+            chb_delay_us(TIME_RX_ON_PLL_ON);
+        }
+        break;
+
+    case RX_AACK_ON:
+        if (curr_state == TX_ARET_ON)
+        {
+            /* First do intermediate state transition to RX_ON, then to RX_AACK_ON. */
+            chb_reg_read_mod_write(TRX_STATE, CMD_PLL_ON, 0x1f);
+            chb_delay_us(TIME_RX_ON_PLL_ON);
+        }
+        break;
+    }
+
+    /* Now we're okay to transition to any new state. */
+    chb_reg_read_mod_write(TRX_STATE, state, 0x1f);
+
+    /* When the PLL is active most states can be reached in 1us. However, from */
+    /* TRX_OFF the PLL needs time to activate. */
+    delay = (curr_state == TRX_OFF) ? TIME_TRX_OFF_PLL_ON : TIME_RX_ON_PLL_ON;
+    chb_delay_us(delay);
+
+    if (chb_get_state() == state)
+    {
+        return RADIO_SUCCESS;
+    }
+    return RADIO_TIMED_OUT;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_set_ieee_addr(U8 *addr)
+{
+    chb_eeprom_write((U8*)CFG_EEPROM_CHIBI_IEEEADDR, addr, 8);
+    chb_reg_write64(IEEE_ADDR_0, addr);
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_get_ieee_addr(U8 *addr)
+{
+    chb_eeprom_read((U8*)CFG_EEPROM_CHIBI_IEEEADDR, addr, 8);
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_set_short_addr(U16 addr)
+{
+    chb_pcb_t *pcb = chb_get_pcb();
+
+    chb_eeprom_write((U8*)CFG_EEPROM_CHIBI_NODEADDR, (U8*)&addr, 2);
+    chb_reg_write16(SHORT_ADDR_0, addr);
+    pcb->src_addr = addr;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+U16 chb_get_short_addr()
+{
+    int16_t addr;
+
+    chb_eeprom_read((U8*)CFG_EEPROM_CHIBI_NODEADDR, (U8*)&addr, 2);
+    return addr;
+}
+
+/**************************************************************************/
+/*!
+    Set the high gain mode pin for the CC1190
+*/
+/**************************************************************************/
+#if (CHB_CC1190_PRESENT)
+void chb_set_hgm(U8 enb)
+{
+    if (enb)
+    {
+        LPC_GPIO->SET[CFG_CHIBI_CC1190_HGM_PORT] = (1 << CFG_CHIBI_CC1190_HGM_PIN);
+    }
+    else
+    {
+        LPC_GPIO->CLR[CFG_CHIBI_CC1190_HGM_PORT] = (1 << CFG_CHIBI_CC1190_HGM_PIN);
+    }
+}
+#endif
+
+/**************************************************************************/
+/*!
+    Load the data into the fifo, initiate a transmission attempt,
+    and return the status of the transmission attempt.
+*/
+/**************************************************************************/
+U8 chb_tx(U8 *hdr, U8 *data, U8 len)
+{
+    U8 state = chb_get_state();
+    chb_pcb_t *pcb = chb_get_pcb();
+
+    if ((state == BUSY_TX) || (state == BUSY_TX_ARET))
+    {
+        return RADIO_WRONG_STATE;
+    }
+
+    // TODO: check why we need to transition to the off state before we go to tx_aret_on
+    chb_set_state(TRX_OFF);
+    chb_set_state(TX_ARET_ON);
+
+    // TODO: try and start the frame transmission by writing TX_START command instead of toggling
+    // sleep pin...i just feel like it's kind of weird...
+
+    // write frame to buffer. first write header into buffer (add 1 for len byte), then data.
+    chb_frame_write(hdr, CHB_HDR_SZ + 1, data, len);
+
+    //Do frame transmission
+    chb_reg_read_mod_write(TRX_STATE, CMD_TX_START, 0x1F);
+
+    // wait for the transmission to end, signalled by the TRX END flag
+    while (!pcb->tx_end);
+    pcb->tx_end = false;
+
+    // check the status of the transmission
+    return chb_get_status();
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+static err_t chb_radio_init()
+{
+    U8 ieee_addr[8];
+
+    // reset chip (this can fail if there is a HW or config problem)
+    err_t error = chb_reset();
+    if (error)
+    {
+      return error;
+    }
+
+    // disable intps while we config the radio
+    chb_reg_write(IRQ_MASK, 0);
+
+    // force transceiver off while we configure the intps
+    chb_reg_read_mod_write(TRX_STATE, CMD_FORCE_TRX_OFF, 0x1F);
+
+    // make sure the transceiver is in the off state before proceeding
+    while ((chb_reg_read(TRX_STATUS) & 0x1f) != TRX_OFF);
+
+    // set radio cfg parameters
+    // **note** uncomment if these will be set to something other than default
+    //chb_reg_read_mod_write(XAH_CTRL_0, CHB_MAX_FRAME_RETRIES << CHB_MAX_FRAME_RETRIES_POS, 0xF << CHB_MAX_FRAME_RETRIES_POS);
+    //chb_reg_read_mod_write(XAH_CTRL_0, CHB_MAX_CSMA_RETRIES << CHB_MAX_CSMA_RETIRES_POS, 0x7 << CHB_MAX_CSMA_RETIRES_POS);
+    //chb_reg_read_mod_write(CSMA_SEED_1, CHB_CSMA_SEED1 << CHB_CSMA_SEED1_POS, 0x7 << CHB_CSMA_SEED1_POS);
+    //chb_ret_write(CSMA_SEED0, CHB_CSMA_SEED0);
+    //chb_reg_read_mod_write(PHY_CC_CCA, CHB_CCA_MODE << CHB_CCA_MODE_POS,0x3 << CHB_CCA_MODE_POS);
+    //chb_reg_write(CCA_THRES, CHB_CCA_ED_THRES);
+
+    // set frame version that we'll accept
+    chb_reg_read_mod_write(CSMA_SEED_1, CHB_FRM_VER << CHB_FVN_POS, 3 << CHB_FVN_POS);
+
+    // set interrupt mask
+    // re-enable intps while we config the radio
+    chb_reg_write(IRQ_MASK, (1<<IRQ_RX_START) | (1<<IRQ_TRX_END));
+
+    #if (CFG_CHIBI_PROMISCUOUS == 0)
+      // set autocrc mode
+      chb_reg_read_mod_write(TRX_CTRL_1, 1 << CHB_AUTO_CRC_POS, 1 << CHB_AUTO_CRC_POS);
+    #endif
+    // set up default phy modulation, data rate and power (Ex. OQPSK, 100 kbps, 868 MHz, 3dBm)
+    chb_set_mode(CFG_CHIBI_MODE);       // Defined in projectconfig.h
+    chb_set_pwr(CFG_CHIBI_POWER);       // Defined in projectconfig.h
+    chb_set_channel(CFG_CHIBI_CHANNEL); // Defined in projectconfig.h
+
+    // set fsm state
+    // put trx in rx auto ack mode
+    chb_set_state(RX_STATE);
+
+    // set pan ID
+    chb_reg_write16(PAN_ID_0, CFG_CHIBI_PANID); // Defined in projectconfig.h
+
+    // set short addr
+    // NOTE: Possibly get this from EEPROM
+    chb_reg_write16(SHORT_ADDR_0, chb_get_short_addr());
+
+    // set long addr
+    // NOTE: Possibly get this from EEPROM
+    chb_get_ieee_addr(ieee_addr);
+    chb_reg_write64(IEEE_ADDR_0, ieee_addr);
+
+#if (CHB_CC1190_PRESENT)
+    // set high gain mode pin to output and init to zero
+    LPC_GPIO->DIR[CFG_CHIBI_CC1190_HGM_PORT] |= (1 << CFG_CHIBI_CC1190_HGM_PIN);
+    LPC_GPIO->CLR[CFG_CHIBI_CC1190_HGM_PORT] = (1 << CFG_CHIBI_CC1190_HGM_PIN);
+
+    // set external power amp on AT86RF212
+    chb_reg_read_mod_write(TRX_CTRL_1, 1<<CHB_PA_EXT_EN_POS, 1<<CHB_PA_EXT_EN_POS);
+
+    // set power to lowest level possible
+    chb_set_pwr(0xd);   // set to -11 dBm
+#endif
+
+    // set interrupt/gpio pin to input
+    LPC_GPIO->DIR[CFG_CHIBI_EINTPORT] &= ~(1 << CFG_CHIBI_EINTPIN);
+
+    // Channel 0, sense (0=edge, 1=level), polarity (0=low/falling, 1=high/rising)
+    GPIOSetPinInterrupt( 0, CFG_CHIBI_EINTPORT, CFG_CHIBI_EINTPIN, 0, 1 );
+
+    // Enable interrupt
+    // GPIOPinIntEnable( 0, 0 );
+
+    if (chb_get_state() != RX_STATE)
+    {
+        // ERROR occurred initializing the radio. Print out error message.
+        printf(chb_err_init);
+        return ERROR_DEVICENOTINITIALISED;
+    }
+
+    return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+err_t chb_drvr_init()
+{
+    // config SPI for at86rf230 access
+    chb_spi_init();
+
+    // Set sleep and reset as output
+    LPC_GPIO->DIR[CFG_CHIBI_SLPTRPORT] |= (1 << CFG_CHIBI_SLPTRPIN);
+    LPC_GPIO->DIR[CFG_CHIBI_RSTPORT] |= (1 << CFG_CHIBI_RSTPIN);
+
+    // configure IOs
+    LPC_GPIO->SET[CFG_CHIBI_SLPTRPORT] = (1 << CFG_CHIBI_SLPTRPIN); // Set sleep high
+    LPC_GPIO->SET[CFG_CHIBI_RSTPORT] = (1 << CFG_CHIBI_RSTPIN);     // Set reset high
+
+    // config radio
+    return chb_radio_init();
+}
+
+/**************************************************************************/
+/*!
+    Enable or disable the radio's sleep mode.
+*/
+/**************************************************************************/
+void chb_sleep(U8 enb)
+{
+  if (enb)
+  {
+    // first we need to go to TRX OFF state
+    chb_set_state(TRX_OFF);
+
+    // set the SLPTR pin
+    CHB_SLPTR_ENABLE();
+  }
+  else
+  {
+    // make sure the SLPTR pin is low first
+    CHB_SLPTR_DISABLE();
+
+    // we need to allow some time for the PLL to lock
+    chb_delay_us(TIME_SLEEP_TO_TRX_OFF);
+
+    // Turn the transceiver back on
+    chb_set_state(RX_STATE);
+  }
+}
+
+/**************************************************************************/
+/*!
+    GPIO IRQ Handler (triggers on AT86RF212 IRQ line)
+*/
+/**************************************************************************/
+#if defined CFG_MCU_FAMILY_LPC11UXX
+void FLEX_INT0_IRQHandler(void)
+#elif defined CFG_MCU_FAMILY_LPC13UXX
+void PIN_INT0_IRQHandler(void)
+#else
+  #error "chb_drvr.c: No MCU defined"
+#endif
+{
+    if ( LPC_GPIO_PIN_INT->IST & (0x1<<0) )
+    {
+        U8 state, intp_src = 0;
+        chb_pcb_t *pcb = chb_get_pcb();
+
+        CHB_ENTER_CRIT();
+
+        /*Read Interrupt source.*/
+        CHB_SPI_ENABLE();
+
+        /*Send Register address and read register content.*/
+        chb_xfer_byte(IRQ_STATUS | CHB_SPI_CMD_RR);
+        intp_src = chb_xfer_byte(0);
+
+        CHB_SPI_DISABLE();
+
+        while (intp_src)
+        {
+            /*Handle the incomming interrupt. Prioritized.*/
+            if ((intp_src & CHB_IRQ_RX_START_MASK))
+            {
+                intp_src &= ~CHB_IRQ_RX_START_MASK;
+            }
+            else if (intp_src & CHB_IRQ_TRX_END_MASK)
+            {
+                state = chb_get_state();
+
+                if ((state == RX_ON) || (state == RX_AACK_ON) || (state == BUSY_RX_AACK))
+                {
+                    // get the ed measurement
+                    pcb->ed = chb_reg_read(PHY_ED_LEVEL);
+
+                    // get the crc
+                    pcb->crc = (chb_reg_read(PHY_RSSI) & (1<<7)) ? 1 : 0;
+
+                    // if the crc is not valid, then do not read the frame and set the rx flag
+                    if (pcb->crc)
+                    {
+                        // get the data
+                        chb_frame_read();
+                        pcb->rcvd_xfers++;
+                        pcb->data_rcv = true;
+                    }
+                }
+                else
+                {
+                    pcb->tx_end = true;
+                }
+                intp_src &= ~CHB_IRQ_TRX_END_MASK;
+                while (chb_set_state(RX_STATE) != RADIO_SUCCESS);
+            }
+            else if (intp_src & CHB_IRQ_TRX_UR_MASK)
+            {
+                intp_src &= ~CHB_IRQ_TRX_UR_MASK;
+                pcb->underrun++;
+            }
+            else if (intp_src & CHB_IRQ_PLL_UNLOCK_MASK)
+            {
+                intp_src &= ~CHB_IRQ_PLL_UNLOCK_MASK;
+            }
+            else if (intp_src & CHB_IRQ_PLL_LOCK_MASK)
+            {
+                intp_src &= ~CHB_IRQ_PLL_LOCK_MASK;
+            }
+            else if (intp_src & CHB_IRQ_BAT_LOW_MASK)
+            {
+                intp_src &= ~CHB_IRQ_BAT_LOW_MASK;
+                pcb->battlow++;
+            }
+            else
+            {
+            }
+        }
+        CHB_LEAVE_CRIT();
+
+        // Clear the interrupt
+        LPC_GPIO_PIN_INT->IST = 0x1<<0;
+    }
+    return;
+}
+
+#endif /* CFG_CHIBI */
diff --git a/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_drvr.h b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_drvr.h
new file mode 100644
index 0000000000000000000000000000000000000000..b4c58f5a11c149ae8b906d430f20e58edf59228f
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_drvr.h
@@ -0,0 +1,361 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+#ifndef CHIBI_DRVR_H
+#define CHIBI_DRVR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "types.h"
+#include "projectconfig.h"
+#include "core/gpio/gpio.h"
+#include "errors.h"
+
+#define CHB_CC1190_PRESENT      0       /// Set to 1 if CC1190 is being used
+#define CHB_CHINA               0
+#define CHB_EEPROM_IEEE_ADDR    CFG_CHIBI_EEPROM_IEEEADDR
+#define CHB_EEPROM_SHORT_ADDR   CFG_CHIBI_EEPROM_SHORTADDR
+#define CHB_AT86RF212_VER_NUM   0x01
+#define CHB_AT86RF212_PART_NUM  0x07
+// #define CHB_BPSK                0       // set to 1 if want to use BPSK rather than OQPSK
+
+#define CHB_SPI_CMD_RW          0xC0    /**<  Register Write (short mode). */
+#define CHB_SPI_CMD_RR          0x80    /**<  Register Read (short mode). */
+#define CHB_SPI_CMD_FW          0x60    /**<  Frame Transmit Mode (long mode). */
+#define CHB_SPI_CMD_FR          0x20    /**<  Frame Receive Mode (long mode). */
+#define CHB_SPI_CMD_SW          0x40    /**<  SRAM Write. */
+#define CHB_SPI_CMD_SR          0x00    /**<  SRAM Read. */
+#define CHB_SPI_CMD_RADDRM      0x7F    /**<  Register Address Mask. */
+
+#define CHB_IRQ_BAT_LOW_MASK    0x80  /**< Mask for the BAT_LOW interrupt. */
+#define CHB_IRQ_TRX_UR_MASK     0x40  /**< Mask for the TRX_UR interrupt. */
+#define CHB_IRQ_TRX_END_MASK    0x08  /**< Mask for the TRX_END interrupt. */
+#define CHB_IRQ_RX_START_MASK   0x04  /**< Mask for the RX_START interrupt. */
+#define CHB_IRQ_PLL_UNLOCK_MASK 0x02  /**< Mask for the PLL_UNLOCK interrupt. */
+#define CHB_IRQ_PLL_LOCK_MASK   0x01  /**< Mask for the PLL_LOCK interrupt. */
+
+#define CHB_ENTER_CRIT()    __disable_irq()
+#define CHB_LEAVE_CRIT()    __enable_irq()
+#define CHB_RST_ENABLE()    do { LPC_GPIO->CLR[CFG_CHIBI_RSTPORT] = (1 << CFG_CHIBI_RSTPIN); } while(0)
+#define CHB_RST_DISABLE()   do { LPC_GPIO->SET[CFG_CHIBI_RSTPORT] = (1 << CFG_CHIBI_RSTPIN); } while(0)
+#define CHB_SLPTR_ENABLE()  do { LPC_GPIO->SET[CFG_CHIBI_SLPTRPORT] = (1 << CFG_CHIBI_SLPTRPIN); } while(0)
+#define CHB_SLPTR_DISABLE() do { LPC_GPIO->CLR[CFG_CHIBI_SLPTRPORT] = (1 << CFG_CHIBI_SLPTRPIN); } while(0)
+
+// CCA constants
+enum
+{
+    CCA_ED                    = 1,    /**< Use energy detection above threshold mode. */
+    CCA_CARRIER_SENSE         = 2,    /**< Use carrier sense mode. */
+    CCA_CARRIER_SENSE_WITH_ED = 3     /**< Use a combination of both energy detection and carrier sense. */
+};
+
+// configuration parameters
+enum
+{
+    CHB_CHANNEL             = 1,        // Replaced in projectconfig.h with CFG_CHIBI_CHANNEL
+    CHB_PAN_ID              = 0x1234,   // Replaced in projectconfig.h with CFG_CHIBI_PANID
+    CHB_TX_PWR              = 0x0,
+    CHB_SHORT_ADDR          = 0x0,
+    CHB_IEEE_ADDR           = 0x0,
+    CHB_MAX_FRAME_RETRIES   = 3,
+    CHB_MAX_CSMA_RETRIES    = 4,
+    CHB_CCA_MODE            = CCA_ED,
+    CHB_MIN_BE              = 3,
+    CHB_MAX_BE              = 5,
+    CHB_CCA_ED_THRES        = 0x7,
+    CHB_CSMA_SEED0          = 0,
+    CHB_CSMA_SEED1          = 0,
+    CHB_FRM_VER             = 1         // accept 802.15.4 ver 0 or 1 frames
+};
+
+// register addresses
+enum
+{
+    TRX_STATUS              = 0x01,
+    TRX_STATE               = 0x02,
+    TRX_CTRL_0              = 0x03,
+    TRX_CTRL_1              = 0x04,
+    PHY_TX_PWR              = 0x05,
+    PHY_RSSI                = 0x06,
+    PHY_ED_LEVEL            = 0x07,
+    PHY_CC_CCA              = 0x08,
+    CCA_THRES               = 0x09,
+    RX_CTRL                 = 0x0a,
+    SFD_VALUE               = 0x0b,
+    TRX_CTRL_2              = 0x0c,
+    ANT_DIV                 = 0x0d,
+    IRQ_MASK                = 0x0e,
+    IRQ_STATUS              = 0x0f,
+    VREG_CTRL               = 0x10,
+    BATMON                  = 0x11,
+    XOSC_CTRL               = 0x12,
+    CC_CTRL_0               = 0x13,
+    CC_CTRL_1               = 0x14,
+    RX_SYN                  = 0x15,
+    RF_CTRL_0               = 0x16,
+    XAH_CTRL_1              = 0x17,
+    FTN_CTRL                = 0x18,
+    RF_CTRL_1               = 0x19,
+    PLL_CF                  = 0x1a,
+    PLL_DCU                 = 0x1b,
+    PART_NUM                = 0x1c,
+    VERSION_NUM             = 0x1d,
+    MAN_ID_0                = 0x1e,
+    MAN_ID_1                = 0x1f,
+    SHORT_ADDR_0            = 0x20,
+    SHORT_ADDR_1            = 0x21,
+    PAN_ID_0                = 0x22,
+    PAN_ID_1                = 0x23,
+    IEEE_ADDR_0             = 0x24,
+    IEEE_ADDR_1             = 0x25,
+    IEEE_ADDR_2             = 0x26,
+    IEEE_ADDR_3             = 0x27,
+    IEEE_ADDR_4             = 0x28,
+    IEEE_ADDR_5             = 0x29,
+    IEEE_ADDR_6             = 0x2a,
+    IEEE_ADDR_7             = 0x2b,
+    XAH_CTRL_0              = 0x2c,
+    CSMA_SEED_0             = 0x2d,
+    CSMA_SEED_1             = 0x2e,
+    CSMA_BE                 = 0x2f
+};
+
+// random defines
+enum
+{
+    CHB_MAX_FRAME_RETRIES_POS   = 4,
+    CHB_MAX_CSMA_RETIRES_POS    = 1,
+    CHB_CSMA_SEED1_POS          = 0,
+    CHB_CCA_MODE_POS            = 5,
+    CHB_AUTO_CRC_POS            = 5,
+    CHB_TRX_END_POS             = 3,
+    CHB_TRAC_STATUS_POS         = 5,
+    CHB_FVN_POS                 = 6,
+    CHB_OQPSK_TX_OFFSET         = 2,
+    CHB_BPSK_TX_OFFSET          = 3,
+    CHB_MIN_FRAME_LENGTH        = 3,
+    CHB_MAX_FRAME_LENGTH        = 0x7f,
+    CHB_PA_EXT_EN_POS           = 7
+};
+
+// transceiver timing
+enum{
+    TIME_RST_PULSE_WIDTH        = 1,
+    TIME_P_ON_TO_CLKM_AVAIL     = 380,
+    TIME_SLEEP_TO_TRX_OFF       = 240,
+    TIME_TRX_OFF_TO_SLEEP       = 35,
+    TIME_PLL_ON_TRX_OFF         = 1,
+    TIME_TRX_OFF_RX_ON          = 110,
+    TIME_RX_ON_TRX_OFF          = 1,
+    TIME_PLL_ON_RX_ON           = 1,
+    TIME_RX_ON_PLL_ON           = 1,
+    TIME_PLL_LOCK_TIME          = 110,
+    TIME_BUSY_TX_PLL_ON         = 32,
+    TIME_ALL_STATES_TRX_OFF     = 1,
+    TIME_RESET_TRX_OFF          = 26,
+    TIME_TRX_IRQ_DELAY          = 9,
+    TIME_TRX_OFF_PLL_ON         = 110,
+    TIME_IRQ_PROCESSING_DLY     = 32
+};
+
+// trac status
+enum{
+    TRAC_SUCCESS               = 0,
+    TRAC_SUCCESS_DATA_PENDING  = 1,
+    TRAC_WAIT_FOR_ACK          = 2,
+    TRAC_CHANNEL_ACCESS_FAIL   = 3,
+    TRAC_NO_ACK                = 5,
+    TRAC_INVALID               = 7
+};
+
+// radio statuses
+enum{
+    RADIO_SUCCESS = 0x40,                       /**< The requested service was performed successfully. */
+    RADIO_UNSUPPORTED_DEVICE,                   /**< The connected device is not an Atmel AT86RF212. */
+    RADIO_INVALID_ARGUMENT,                     /**< One or more of the supplied function arguments are invalid. */
+    RADIO_TIMED_OUT,                            /**< The requested service timed out. */
+    RADIO_WRONG_STATE,                          /**< The end-user tried to do an invalid state transition. */
+    RADIO_BUSY_STATE,                           /**< The radio transceiver is busy receiving or transmitting. */
+    RADIO_STATE_TRANSITION_FAILED,              /**< The requested state transition could not be completed. */
+    RADIO_CCA_IDLE,                             /**< Channel is clear, available to transmit a new frame. */
+    RADIO_CCA_BUSY,                             /**< Channel busy. */
+    RADIO_TRX_BUSY,                             /**< Transceiver is busy receiving or transmitting data. */
+    RADIO_BAT_LOW,                              /**< Measured battery voltage is lower than voltage threshold. */
+    RADIO_BAT_OK,                               /**< Measured battery voltage is above the voltage threshold. */
+    RADIO_CRC_FAILED,                           /**< The CRC failed for the actual frame. */
+    RADIO_CHANNEL_ACCESS_FAILURE,               /**< The channel access failed during the auto mode. */
+    RADIO_NO_ACK,                               /**< No acknowledge frame was received. */
+};
+
+// transceiver commands
+enum
+{
+    CMD_NOP                 = 0,
+    CMD_TX_START            = 2,
+    CMD_FORCE_TRX_OFF       = 3,
+    CMD_FORCE_PLL_ON        = 4,
+    CMD_RX_ON               = 6,
+    CMD_TRX_OFF             = 8,
+    CMD_PLL_ON              = 9,
+    CMD_RX_AACK_ON          = 22,
+    CMD_TX_ARET_ON          = 25
+};
+
+// transceiver states
+enum
+{
+    P_ON               = 0,
+    BUSY_RX            = 1,
+    BUSY_TX            = 2,
+    RX_ON              = 6,
+    TRX_OFF            = 8,
+    PLL_ON             = 9,
+    SLEEP              = 15,
+    BUSY_RX_AACK       = 17,
+    BUSY_TX_ARET       = 18,
+    RX_AACK_ON         = 22,
+    TX_ARET_ON         = 25,
+    RX_ON_NOCLK        = 28,
+    RX_AACK_ON_NOCLK   = 29,
+    BUSY_RX_AACK_NOCLK = 30,
+    TRANS_IN_PROG      = 31
+};
+
+// transceiver interrupt register
+enum
+{
+    IRQ_PLL_LOCK                = 0,
+    IRQ_PLL_UNLOCK              = 1,
+    IRQ_RX_START                = 2,
+    IRQ_TRX_END                 = 3,
+    IRQ_CCA_ED_READY            = 4,
+    IRQ_AMI                     = 5,
+    IRQ_TRX_UR                  = 6,
+    IRQ_BAT_LOW                 = 7
+};
+
+// transceiver modes
+enum
+{
+    OQPSK_868MHZ    = 0,
+    OQPSK_915MHZ    = 1,
+    OQPSK_780MHZ    = 2,
+    BPSK40_915MHZ   = 3,
+    BPSK20_868MHZ   = 4
+};
+
+// See Table 7-15 for details
+enum
+{
+  CHB_PWR_EU1_2DBM   = 0x63,    // EU (868MHz) Linearized PA mode
+  CHB_PWR_EU1_1DBM   = 0x64,    // Note: BPSK 20kbit/s only!
+  CHB_PWR_EU1_0DBM   = 0x65,
+  CHB_PWR_EU2_5DBM   = 0xE7,    // EU (868MHz) Boost mode (but > supply current)
+  CHB_PWR_EU2_4DBM   = 0xE8,    // 4-5dBM BPSK 20 kbit/s only!
+  CHB_PWR_EU2_3DBM   = 0xE9,    // 0-3dBM O-QPSK 100/200/400 kbit/s or BPSK
+  CHB_PWR_EU2_2DBM   = 0xEA,
+  CHB_PWR_EU2_1DBM   = 0xCB,
+  CHB_PWR_EU2_0DBM   = 0xAB,
+  CHB_PWR_NA_10DBM   = 0xC0,    // North America (915MHz)
+  CHB_PWR_NA_9DBM    = 0xA1,
+  CHB_PWR_NA_8DBM    = 0x81,
+  CHB_PWR_NA_7DBM    = 0x82,
+  CHB_PWR_NA_6DBM    = 0x83,
+  CHB_PWR_NA_5DBM    = 0x60,
+  CHB_PWR_NA_4DBM    = 0x61,
+  CHB_PWR_NA_3DBM    = 0x41,
+  CHB_PWR_NA_2DBM    = 0x42,
+  CHB_PWR_NA_1DBM    = 0x22,
+  CHB_PWR_NA_0DBM    = 0x23,
+  CHB_PWR_CHINA_5DBM = 0xE7,    // China (780MHz)
+  CHB_PWR_CHINA_4DBM = 0xE8,
+  CHB_PWR_CHINA_3DBM = 0xE9,
+  CHB_PWR_CHINA_2DBM = 0xEA,
+  CHB_PWR_CHINA_1DBM = 0xCA,
+  CHB_PWR_CHINA_0DBM = 0xAA
+};
+
+// define receive state based on promiscuous mode setting
+#if (CFG_CHIBI_PROMISCUOUS == 1)
+    #define RX_STATE RX_ON
+#else
+    #define RX_STATE RX_AACK_ON
+#endif
+// init
+err_t chb_drvr_init(void);
+
+// data access
+U8 chb_reg_read(U8 addr);
+U16 chb_reg_read16(U8 addr);
+void chb_reg_write(U8 addr, U8 val);
+void chb_reg_write16(U8 addr, U16 val);
+void chb_reg_write64(U8 addr, U8 *val);
+void chb_reg_read_mod_write(U8 addr, U8 val, U8 mask);
+void chb_frame_write(U8 *hdr, U8 hdr_len, U8 *data, U8 data_len);
+
+// general configuration
+void chb_set_mode(U8 mode);
+U8 chb_set_channel(U8 channel);
+void chb_set_pwr(U8 val);
+// void chb_set_ieee_addr(U8 *addr);
+void chb_get_ieee_addr(U8 *addr);
+void chb_set_short_addr(U16 addr);
+U16 chb_get_short_addr(void);
+U8 chb_set_state(U8 state);
+
+// Power management
+void chb_sleep(U8 enb);
+
+// data transmit
+U8 chb_tx(U8 *hdr, U8 *data, U8 len);
+
+#if (CHB_CC1190_PRESENT)
+    void chb_set_hgm(U8 enb);
+#endif
+
+#ifdef CHB_DEBUG
+// sram access
+void chb_sram_read(U8 addr, U8 len, U8 *data);
+void chb_sram_write(U8 addr, U8 len, U8 *data);
+#endif
+
+void chb_ISR_Handler (void);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
+
diff --git a/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_eeprom.c b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_eeprom.c
new file mode 100644
index 0000000000000000000000000000000000000000..495d9ab272c11da23e6d0b443c510121521226f0
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_eeprom.c
@@ -0,0 +1,68 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+/*!
+    \file
+    \ingroup
+
+
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_CHIBI
+
+#include "chb_eeprom.h"
+#include "core/eeprom/eeprom.h"
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_eeprom_write(uint8_t* addr, uint8_t *buf, uint16_t size)
+{
+  writeEEPROM((uint8_t*)addr, buf, size);
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_eeprom_read(uint8_t* addr, uint8_t *buf, uint16_t size)
+{
+  readEEPROM((uint8_t*)addr, buf, size);
+}
+
+#endif /* CFG_CHIBI */
diff --git a/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_eeprom.h b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_eeprom.h
new file mode 100644
index 0000000000000000000000000000000000000000..5459e82d469135079169f673557f4b67a28ec616
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_eeprom.h
@@ -0,0 +1,58 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+/*!
+    \file
+    \ingroup
+
+
+*/
+/**************************************************************************/
+#ifndef CHB_EEPROM_H
+#define CHB_EEPROM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "types.h"
+
+void chb_eeprom_write(U8* addr, U8 *buf, U16 size);
+void chb_eeprom_read(U8* addr, U8 *buf, U16 size);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_spi.c b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_spi.c
new file mode 100644
index 0000000000000000000000000000000000000000..4f260ba62eb27f403da888e1d0c2f10bda7c68c6
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_spi.c
@@ -0,0 +1,106 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+/*!
+    \file
+    \ingroup
+
+
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_CHIBI
+
+#include "chb.h"
+#include "chb_spi.h"
+#if CFG_CHIBI_SPIPORT == 0
+  #include "core/ssp0/ssp0.h"
+#elif CFG_CHIBI_SPIPORT == 1
+  #include "core/ssp1/ssp1.h"
+#endif
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_spi_init()
+{
+    // Set slave select to output and high
+    LPC_GPIO->DIR[CFG_CHIBI_SSPORT] |= (1 << CFG_CHIBI_SSPIN);
+
+    // set the slave select to idle
+    CHB_SPI_DISABLE();
+
+    // Initialise SPI (use Mode 0 - SSEL active low and clock starts low)
+    #if CFG_CHIBI_SPIPORT == 0
+      ssp0Init();
+    #elif CFG_CHIBI_SPIPORT == 1
+      ssp1Init();
+    #endif
+}
+
+/**************************************************************************/
+/*!
+    This function both reads and writes data. For write operations, include data
+    to be written as argument. For read ops, use dummy data as arg. Returned
+    data is read byte val.
+*/
+/**************************************************************************/
+U8 chb_xfer_byte(U8 data)
+{
+    #if CFG_CHIBI_SPIPORT == 0
+      /* Move on only if NOT busy and TX FIFO not full */
+      while ((LPC_SSP0->SR & (SSP0_SR_TNF_NOTFULL | SSP0_SR_BSY_BUSY)) != SSP0_SR_TNF_NOTFULL);
+      LPC_SSP0->DR = data;
+
+      /* Wait until the busy bit is cleared and receive buffer is not empty */
+      while ( (LPC_SSP0->SR & (SSP0_SR_BSY_BUSY|SSP0_SR_RNE_NOTEMPTY)) != SSP0_SR_RNE_NOTEMPTY );
+
+      // Read the queue
+      return LPC_SSP0->DR;
+    #elif CFG_CHIBI_SPIPORT == 1
+      /* Move on only if NOT busy and TX FIFO not full */
+      while ((LPC_SSP1->SR & (SSP1_SR_TNF_NOTFULL | SSP1_SR_BSY_BUSY)) != SSP1_SR_TNF_NOTFULL);
+      LPC_SSP1->DR = data;
+
+      /* Wait until the busy bit is cleared and receive buffer is not empty */
+      while ( (LPC_SSP1->SR & (SSP1_SR_BSY_BUSY|SSP1_SR_RNE_NOTEMPTY)) != SSP1_SR_RNE_NOTEMPTY );
+
+      // Read the queue
+      return LPC_SSP1->DR;
+    #endif
+}
+
+#endif /* CFG_CHIBI */
diff --git a/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_spi.h b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_spi.h
new file mode 100644
index 0000000000000000000000000000000000000000..2c61f15f5610ff6af99cba4d1b823f4d849e7e2d
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/chb_spi.h
@@ -0,0 +1,62 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+/*!
+    \file
+    \ingroup
+
+
+*/
+/**************************************************************************/
+
+#ifndef CHB_SPI_H
+#define CHB_SPI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "core/gpio/gpio.h"
+
+#define CHB_SPI_ENABLE()    do { LPC_GPIO->CLR[CFG_CHIBI_SSPORT] = (1 << CFG_CHIBI_SSPIN); } while(0)   // Drive SSEL low
+#define CHB_SPI_DISABLE()   do { LPC_GPIO->SET[CFG_CHIBI_SSPORT] = (1 << CFG_CHIBI_SSPIN); } while(0)   // Drive SSEL high
+
+void chb_spi_init(void);
+U8 chb_xfer_byte(U8 data);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/messages.c b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/messages.c
new file mode 100644
index 0000000000000000000000000000000000000000..12a530d4e7f08f72a33f3f7c295e591c2f0f6293
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/messages.c
@@ -0,0 +1,167 @@
+/**************************************************************************/
+/*!
+    @file     messages.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section DESCRIPTION
+
+    Common message handling functions (send, receive, etc.)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_CHIBI
+
+#include <string.h>
+
+#include "messages.h"
+#include "core/delay/delay.h"
+#include "chb.h"
+#include "chb_drvr.h"
+
+static uint8_t  _msg[CHB_MAX_PAYLOAD];     // Buffer used when sending messages
+static uint16_t _msg_msgID;                // Auto-incrementing ID for message envelopes
+static uint32_t _msg_alert_uniqueID;       // Auto-incrementing ID for alert messages
+
+/**************************************************************************/
+/*!
+    @brief Sends the specified message over the air
+
+    @note  Possible error IDs:
+
+           ERROR_CHIBI_NOACK
+           ERROR_CHIBI_CHANACCESSFAILURE
+           ERROR_CHIBI_PAYLOADOVERFLOW
+
+    @section EXAMPLE
+
+    @code
+
+    // Read some sensor data
+    err_t error;
+    sensors_event_t event;
+    error = mpl115a2GetSensorEvent(&event);
+
+    if (!error)
+    {
+      // Serialize the data before transmitting
+      uint8_t msgbuf[sizeof(event)];
+      sensorsSerializeSensorsEvent(msgbuf, &event);
+
+      // Broadcase the sensor event data over the air
+      if(msgSend(0xFFFF, MSG_MESSAGETYPE_SENSOREVENT, msgbuf, sizeof(event)))
+      {
+        printf("Message TX failure%s", CFG_PRINTF_NEWLINE);
+      }
+    }
+
+    @endcode
+*/
+/**************************************************************************/
+err_t msgSend(uint16_t targetAddr, msg_MessageType_t msgType, uint8_t *payload, uint8_t payloadLength)
+{
+  uint8_t msgLength = payloadLength + 9;
+  uint8_t results;
+  uint32_t timestamp;
+
+  /* Make sure payload is within limits */
+  /* ToDo: Throw proper error code/msg */
+  if (msgLength > CHB_MAX_PAYLOAD)
+    return ERROR_CHIBI_PAYLOADOVERFLOW;
+
+  /* Clear message buffer */
+  memset(&_msg, 0x00, CHB_MAX_PAYLOAD);
+
+  /* Message Envelope (9 bytes) + Payload
+  ==========================================================================
+  U16   Message ID        Sequential message ID
+  U8    Message Type      Sensor results, Alert, File, etc.
+  U32   Timestamp         Current second tick count
+  U8    Reserved          Reserved
+  U8    Payload Length    Payload length in bytes
+  ...   Payload           Message payload
+  ------------------------------------------------------------------------*/
+  /* Sequential Message ID (U16) */
+  *(uint16_t*)&_msg = _msg_msgID++;
+
+  /* Message Type (U8) */
+  _msg[2] = msgType;
+
+  /* Timestamp (U32) */
+  /* Need to use memcpy here since the M0 can't do unaligned accesses! */
+  timestamp = delayGetSecondsActive();
+  memcpy(&_msg[3], &timestamp, 4);
+
+  /* Reserved (U8) */
+  _msg[7] = 0x00;
+
+  /* Payload Length (U8) */
+  _msg[8] = payloadLength;
+
+  /* Message Payload (91 bytes max) */
+  memcpy(&_msg[9], payload, payloadLength);
+  /*===================================================================== */
+
+  do
+  {
+    /* Send message via Chibi */
+    // chb_pcb_t *pcb = chb_get_pcb();
+    GPIOSetBitValue(CFG_LED_PORT, CFG_LED_PIN, CFG_LED_ON);
+    results = chb_write(targetAddr, _msg, msgLength);
+    GPIOSetBitValue(CFG_LED_PORT, CFG_LED_PIN, CFG_LED_OFF);
+  } while(0);
+
+  /* Return an appropriate error code depending on the write status */
+  switch(results)
+  {
+    case CHB_NO_ACK:
+      return ERROR_CHIBI_NOACK;
+    case CHB_CHANNEL_ACCESS_FAILURE:
+      return ERROR_CHIBI_CHANACCESSFAILURE;
+    default:
+      return ERROR_NONE;
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief Creates a new 'Alert Message' instance (msg_Alert_t)
+*/
+/**************************************************************************/
+void msgCreateAlert(msg_Alert_t *msg)
+{
+  // Clear memory and assign unique ID
+  memset(msg, 0, sizeof(msg_Alert_t));
+  msg->uniqueID = _msg_alert_uniqueID++;
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/messages.h b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/messages.h
new file mode 100644
index 0000000000000000000000000000000000000000..73ccebd0f8167de5b47b8e9483d806665d1fa5ab
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/messages.h
@@ -0,0 +1,103 @@
+/**************************************************************************/
+/*!
+    @file     messages.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012 K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __MESSAGES_H__
+#define __MESSAGES_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "drivers/sensors/sensors.h"
+
+/* This type is used to indicate the message format/contents, and
+   determines how the message will be parsed by the messaging engine.
+   Note: Message Type is uint8_t ... keep the IDs within an unsigned
+   8-bit limit!                                                           */
+typedef enum msg_MessageType_s
+{
+  MSG_MESSAGETYPE_NONE          = 0,
+  MSG_MESSAGETYPE_ALERT         = 1,
+  MSG_MESSAGETYPE_PROTOCOLDATA  = 10,
+  MSG_MESSAGETYPE_SENSORDETAILS = 20,
+  MSG_MESSAGETYPE_SENSOREVENT   = 21,
+  MSG_MESSAGETYPE_FILEDETAILS   = 30,
+  MSG_MESSAGETYPE_FILEDATA      = 31
+} msg_MessageType_t;
+
+/* Message Structs */
+
+/* Alert Frame: 12 bytes */
+typedef struct
+{
+  uint32_t    uniqueID;           // Unique ID to track this alert
+  uint16_t    alertType;          // ID indicating the type of alert
+  uint8_t     reserved1;
+  uint8_t     reserved2;
+  uint8_t     payload[4];         // Alert payload (max 4 bytes)
+} msg_Alert_t;
+
+/* File Details Frame: 15-78 bytes */
+typedef struct
+{
+  uint16_t    fileId;             // Unique file ID to associate FileData
+  uint32_t    size;               // Total file size in bytes
+  uint8_t     filetype;           // TBD: Binary, text, etc.
+  uint32_t    checksum;           // 32-bit CRC value for entire file
+  uint8_t     reserved1;
+  uint8_t     reserved2;
+  uint8_t     filenameLength;     // Length of the filename (max 64 chars)
+  uint8_t     filename[64];       // Filename string
+} msg_FileDetails_t;
+
+/* File Data Frame: 9-72 bytes */
+typedef struct
+{
+  uint16_t    fileID;             // Associates data chunk with FileDetails
+  uint32_t    chunkID;            // Sequential ID of data chunk
+  uint8_t     reserved1;
+  uint8_t     payloadLength;      // Length in bytes of .payload
+  uint8_t     payload[64];        // Up to 64 bytes of data
+} msg_FileData_t;
+
+err_t msgSend ( uint16_t targetAddr, msg_MessageType_t msgType, uint8_t *payload, uint8_t payloadLength );
+void    msgCreateAlert ( msg_Alert_t *msg );
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/messages.txt b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/messages.txt
new file mode 100644
index 0000000000000000000000000000000000000000..13fa5ce51233302bd3707bc40e2e75306a95490f
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/messages.txt
@@ -0,0 +1,136 @@
+Message Overview
+----------------
+
+messages.c/h provides a common envelope for wireless messages, inserting a
+unique message ID, a timestamp, and a uint8_t message type to indicate how
+the message payload should be intepretted.
+
+Endianness
+----------
+
+All values larger than 8-bits are expected to be little endian, such as the 
+command IDs, and the payload contents.  Any deviation from this rule should
+be clearly documentated.
+
+Message Envelope
+----------------
+
+Every payload is wrapped in a standardised 9-byte envelope with the following
+format:
+
+|-----------------------+---------+-------------------------------------------|
+| Field                 | Type    | Meaning                                   |
+|-----------------------+---------+-------------------------------------------|
+| Message ID            | U16     | Sequential message ID (auto-incrementing) |
+| Message Type          | U8      | Message type (msg_MessageType_t)          |
+| Timestamp             | U32     | Millisecond tick counter                  |
+| Reserved              | U8      |                                           |
+| Payload Length        | U8      | Payload length in bytes                   |
+| Payload               | ...     | Payload (max 91 bytes)                    |
+|-----------------------+---------+-------------------------------------------|
+
+Message Types
+-------------
+
+In order to determine how a message should be handled, or how the payload
+should be interpretted, each message includes a one-byte 'Message Type', based
+on the following values:
+
+|-------------------------------+-----+---------------------------------------|
+| Message Type                  | ID  | Meaning                               |
+|-------------------------------+-----+---------------------------------------|
+| MSG_MESSAGETYPE_NONE          | 0   | Normally not used                     |
+| MSG_MESSAGETYPE_ALERT         | 1   | Alert message (not yet implemented)   |
+| MSG_MESSAGETYPE_PROTOCOLDATA  | 10  | 64 byte payload for the simple binary |
+|                               |     | protocol (see src/protocol)           |
+| MSG_MESSAGETYPE_SENSORDETAILS | 20  | sensor_details_t payload              |
+| MSG_MESSAGETYPE_SENSOREVENT   | 21  | sensors_event_t payload               |
+| MSG_MESSAGETYPE_FILEDETAILS   | 30  | File meta data (not yet implemented)  |
+| MSG_MESSAGETYPE_FILEDATA      | 31  | File data chunk (not yet implemented) |
+|-------------------------------+-----+---------------------------------------|
+
+Sending Messages (msgSend)
+--------------------------
+
+messages.c include a simple helper function that can be used to send messages,
+auto-incrementing the message ID, inserting the appropriate timestamp, etc.
+
+To send a SENSOREVENT message, for example, we could call msgSend with the
+following parameters:
+
+void sendSensorEvent(void)
+{
+  error_t error;
+  sensors_event_t event;
+
+  // Change this to whatever sensor you want/have!
+  error = lsm303accelGetSensorEvent(&event);
+
+  if (!error)
+  {
+    // Serialize the data before transmitting
+    uint8_t msgbuf[sizeof(event)];
+    sensorsSerializeSensorsEvent(msgbuf, &event);
+
+    // Broadcast the sensor event data over the air
+    if(msgSend(0xFFFF, MSG_MESSAGETYPE_SENSOREVENT, msgbuf, sizeof(event)))
+    {
+      printf("Message TX failure%s", CFG_PRINTF_NEWLINE);
+    }
+  }
+}
+
+Reading Messages
+----------------
+
+Reading and interpretting messages is an application specific task, but one
+possible approach to read SENSOREVENT data and parse it, and then simply
+display any other message type can be seen below:
+
+void checkForMessages(void)
+{
+  chb_pcb_t *pcb = chb_get_pcb();
+
+  while (pcb->data_rcv)
+  {
+    // Enable LED to indicate message reception
+    boardLED(CFG_LED_ON);
+    // get the length of the data
+    rx_data.len = chb_read(&rx_data);
+    // make sure the length is nonzero
+    if (rx_data.len)
+    {
+      uint8_t msgType = rx_data.data[2];
+      sensors_event_t *event;
+      int dbm = edToDBM(pcb->ed);
+      /* Handle the message based on the msgType */
+      switch(msgType)
+      {
+        case (MSG_MESSAGETYPE_SENSOREVENT):
+          event = (sensors_event_t*)&rx_data.data[9];
+          printf("%04X,%d,", rx_data.src_addr, event->timestamp);
+          printf("%f,%f,%f%s", event->acceleration.x, event->acceleration.y, event->acceleration.z, CFG_PRINTF_NEWLINE);
+          break;
+        default:
+          printf("Message received from node 0x%04X (len=%d, dBm=%d):%s", rx_data.src_addr, rx_data.len, dbm, CFG_PRINTF_NEWLINE);
+          printf("  Message ID:   0x%04X%s", *(uint16_t*)&rx_data.data[0], CFG_PRINTF_NEWLINE);
+          printf("  Message Type: 0x%02X%s", *(uint8_t*)&rx_data.data[2], CFG_PRINTF_NEWLINE);
+          printf("  Timestamp:    %d%s", *(uint32_t*)&rx_data.data[3], CFG_PRINTF_NEWLINE);
+          printf("  Payload:      %d bytes%s", *(uint8_t*)&rx_data.data[8], CFG_PRINTF_NEWLINE);
+          if (rx_data.data[8])
+          {
+            uint8_t i;
+            printf("%s", CFG_PRINTF_NEWLINE);
+            for (i = 0; i < rx_data.data[8]; i++)
+            {
+              printf("0x%02X ", *(uint8_t*)&rx_data.data[9+i]);
+            }
+          }
+          printf("%s", CFG_PRINTF_NEWLINE);
+          break;
+      }
+    }
+    // Disable LED
+    boardLED(CFG_LED_OFF);
+  }
+}
diff --git a/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/types.h b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/types.h
new file mode 100644
index 0000000000000000000000000000000000000000..a2a780886ef2f35eb68367b70351a98b30987908
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/802.15.4/chibi/types.h
@@ -0,0 +1,62 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+*******************************************************************/
+/*!
+    \file types.h
+    \ingroup usb
+*/
+/*******************************************************************/
+#ifndef TYPES_H
+#define TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+#include <stdint.h>
+
+// Standard data types
+typedef uint8_t     U8;     /// Generic 8 bit unsigned data type
+typedef uint16_t    U16;    /// Generic 16 bit unsigned data type
+typedef uint32_t    U32;    /// Generic 32 bit unsigned data type
+typedef uint64_t    U64;    /// Generic 64 bit unsigned data type
+
+typedef int8_t     S8;     /// Generic 8 bit signed data type
+typedef int16_t    S16;    /// Generic 16 bit signed data type
+typedef int32_t    S32;    /// Generic 32 bit signed data type
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_config.c b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_config.c
new file mode 100644
index 0000000000000000000000000000000000000000..3410e40757b55b062862ffff7cdab7dd99d35769
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_config.c
@@ -0,0 +1,89 @@
+/**************************************************************************/
+/*!
+    @file pn532_config.c
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_PN532
+
+#include <string.h>
+
+#include "../pn532.h"
+#include "../pn532_bus.h"
+#include "pn532_config.h"
+
+#include "core/delay/delay.h"
+
+/**************************************************************************/
+/*!
+    @brief     Sets the MxRtyPassiveActivation byte of the
+               RFConfiguration register
+
+    @param     maxRetries    0xFF to wait forever, 0x00..0xFE to timeout
+                             after maxRetries
+*/
+/**************************************************************************/
+pn532_error_t pn532_config_SetPassiveActivationRetries(uint8_t maxRetries)
+{
+  pn532_error_t error;
+  byte_t abtCommand[5];
+  byte_t abtResponse[16];
+  size_t szLen;
+
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Updating Passive Activation Max Retries: 0x%02X (%d)%s", maxRetries, maxRetries, CFG_PRINTF_NEWLINE);
+  #endif
+
+  /* Send RFConfiguration command to adjust config item 5 (MaxRetries)    */
+  abtCommand[0] = PN532_COMMAND_RFCONFIGURATION;
+  abtCommand[1] = 5;                        /* Config item 5 (MaxRetries) */
+  abtCommand[2] = 0xFF;                     /* MxRtyATR (default = 0xFF)  */
+  abtCommand[3] = 0x01;                     /* MxRtyPSL (default = 0x01)  */
+  abtCommand[4] = maxRetries;
+  error = pn532Write(abtCommand, sizeof(abtCommand));
+  if (error)
+    return error;
+
+  /* Wait until we get a valid response or a timeout                      */
+  do
+  {
+    delay(25);
+    error = pn532Read(abtResponse, &szLen);
+  } while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
+  if (error)
+    return error;
+
+  return PN532_ERROR_NONE;
+}
+
+#endif  // #ifdef CFG_PN532
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_config.h b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_config.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b859afb3bae041c3fd270470843ef8722cbb0d9
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_config.h
@@ -0,0 +1,50 @@
+/**************************************************************************/
+/*!
+    @file pn532_config.h
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __PN532_CONFIG_H__
+#define __PN532_CONFIG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+pn532_error_t pn532_config_SetPassiveActivationRetries(uint8_t maxRetries);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_gpio.c b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_gpio.c
new file mode 100644
index 0000000000000000000000000000000000000000..e496892ff5690095c3515112d70417edbe05458f
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_gpio.c
@@ -0,0 +1,170 @@
+/**************************************************************************/
+/*!
+    @file pn532_gpio.c
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_PN532
+
+#include <string.h>
+
+#include "../pn532.h"
+#include "../pn532_bus.h"
+#include "pn532_gpio.h"
+
+#include "core/delay/delay.h"
+
+/**************************************************************************/
+/*!
+    @brief   Writes an 8-bit value that sets the state of the PN532's
+                 GPIO pins
+
+    @warning This function is provided exclusively for board testing and
+             is dangerous since it will throw an error if any pin other
+             than the ones marked "Can be used as GPIO" are modified!  All
+             pins that can not be used as GPIO should ALWAYS be left high
+             (value = 1) or the system will become unstable and a HW reset
+             will be required to recover the PN532.
+
+             pinState[0]  = P30     Can be used as GPIO
+             pinState[1]  = P31     Can be used as GPIO
+             pinState[2]  = P32     *** RESERVED (Must be 1!) ***
+             pinState[3]  = P33     Can be used as GPIO
+             pinState[4]  = P34     *** RESERVED (Must be 1!) ***
+             pinState[5]  = P35     Can be used as GPIO
+*/
+/**************************************************************************/
+pn532_error_t pn532_gpio_WriteGPIO (uint8_t pinState)
+{
+  pn532_error_t error;
+  byte_t _pn532_gpio_abtResponse[PN532_GPIO_RESPONSELENGTH];
+  size_t szLen;
+
+  /* Make sure pinstate does not try to toggle P32 or P34                 */
+  pinState |= (1 << PN532_GPIO_P32) | (1 << PN532_GPIO_P34);
+
+  /* Send GPIO Write command (only P3 pins used since P7 is used by I2C)  */
+  byte_t abtCommand[] = { PN532_COMMAND_WRITEGPIO,             /* Command */
+                          PN532_GPIO_VALIDATIONBIT | pinState, /* P3 Pins */
+                          0x00 };                              /* P7 Pins */
+  error = pn532Write(abtCommand, sizeof(abtCommand));
+  if (error)
+    return error;
+
+  /* Wait until we get a valid response or a timeout                      */
+  do
+  {
+    delay(25);
+    error = pn532Read(_pn532_gpio_abtResponse, &szLen);
+  } while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
+  if (error)
+    return error;
+
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Writing P3 GPIO: 0x%X%s", abtCommand[1], CFG_PRINTF_NEWLINE);
+  #endif
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief   Reads the state of the PN532's GPIO pins into pinState
+
+             pinState[0]  = P30
+             pinState[1]  = P31
+             pinState[2]  = P32
+             pinState[3]  = P33
+             pinState[4]  = P34
+             pinState[5]  = P35
+*/
+/**************************************************************************/
+pn532_error_t pn532_gpio_ReadGPIO (uint8_t * pinState)
+{
+  pn532_error_t error;
+  byte_t _pn532_gpio_abtResponse[PN532_GPIO_RESPONSELENGTH];
+  size_t szLen;
+
+  /* Send the command (0x0C) */
+  byte_t abtCommand[] = { PN532_COMMAND_READGPIO };
+  error = pn532Write(abtCommand, sizeof(abtCommand));
+  if (error)
+    return error;
+
+  /* Wait for a response */
+  do
+  {
+    delay(25);
+    error = pn532Read(_pn532_gpio_abtResponse, &szLen);
+  }
+  while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
+  if (error)
+    return error;
+
+  /* READGPIO response should be in the following format:
+
+    byte            Description
+    -------------   ------------------------------------------
+    b0..6           Frame header and preamble
+    b7              P3 GPIO Pins
+    b8              P7 GPIO Pins (not used ... taken by I2C)
+    b9              Interface Mode Pins (not used ... bus select pins)
+    b10             checksum */
+
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("P3 GPIO: 0x%02X%s", _pn532_gpio_abtResponse[7], CFG_PRINTF_NEWLINE);
+    PN532_DEBUG("P7 GPIO: 0x%02X%s", _pn532_gpio_abtResponse[8], CFG_PRINTF_NEWLINE);
+    PN532_DEBUG("IO GPIO: 0x%02X%s", _pn532_gpio_abtResponse[9], CFG_PRINTF_NEWLINE);
+    /* Note: You can use the IO GPIO value to detect the serial bus being used */
+    switch(_pn532_gpio_abtResponse[9])
+    {
+      case 0x00:    // Using UART
+        PN532_DEBUG("Using UART (IO = 0x00)%s", CFG_PRINTF_NEWLINE);
+        break;
+      case 0x01:    // Using I2C
+        PN532_DEBUG("Using I2C (IO = 0x01)%s", CFG_PRINTF_NEWLINE);
+        break;
+      case 0x02:    // Using I2C
+        PN532_DEBUG("Using I2C (IO = 0x02)%s", CFG_PRINTF_NEWLINE);
+        break;
+      default:
+        break;
+    }
+  #endif
+
+  /* Assign the pin state to the supplied variable */
+  *pinState = _pn532_gpio_abtResponse[7];
+
+  return PN532_ERROR_NONE;
+}
+#endif  // #ifdef CFG_PN532
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_gpio.h b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_gpio.h
new file mode 100644
index 0000000000000000000000000000000000000000..893622f2ac56d9a06b968239c533685f3fa66447
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_gpio.h
@@ -0,0 +1,64 @@
+/**************************************************************************/
+/*!
+    @file pn532_gpio.h
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __PN532_GPIO_H__
+#define __PN532_GPIO_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+#define PN532_GPIO_RESPONSELENGTH           (16)
+#define PN532_GPIO_VALIDATIONBIT            (0x80)
+
+typedef enum pn532_gpio_e
+{
+  PN532_GPIO_P30 = 0,
+  PN532_GPIO_P31,
+  PN532_GPIO_P32,
+  PN532_GPIO_P33,
+  PN532_GPIO_P34,
+  PN532_GPIO_P35
+} pn532_gpio_t;
+
+pn532_error_t pn532_gpio_WriteGPIO (uint8_t pinState);
+pn532_error_t pn532_gpio_ReadGPIO (uint8_t * pinState);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_mifare.h b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_mifare.h
new file mode 100644
index 0000000000000000000000000000000000000000..96cf7142b61c0ccaa03f0fbada607a9a712c73a5
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_mifare.h
@@ -0,0 +1,65 @@
+/**************************************************************************/
+/*!
+    @file pn532_mifare.h
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __PN532_MIFARE_H__
+#define __PN532_MIFARE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+// These may need to be enlarged for multi card support
+#define PN532_RESPONSELEN_INLISTPASSIVETARGET (64)
+#define PN532_RESPONSELEN_INDATAEXCHANGE      (64)
+
+typedef enum pn532_mifare_cmd_e
+{
+  PN532_MIFARE_CMD_AUTH_A     = 0x60,
+  PN532_MIFARE_CMD_AUTH_B     = 0x61,
+  PN532_MIFARE_CMD_READ       = 0x30,
+  PN532_MIFARE_CMD_WRITE      = 0xA0,
+  PN532_MIFARE_CMD_TRANSFER   = 0xB0,
+  PN532_MIFARE_CMD_DECREMENT  = 0xC0,
+  PN532_MIFARE_CMD_INCREMENT  = 0xC1,
+  PN532_MIFARE_CMD_RESTORE    = 0xC2
+}
+pn532_mifare_cmd_t;
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_mifare_classic.c b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_mifare_classic.c
new file mode 100644
index 0000000000000000000000000000000000000000..76c8bd1929b56aaf00e643061bcef9484ff2a1dd
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_mifare_classic.c
@@ -0,0 +1,910 @@
+/**************************************************************************/
+/*!
+    @file pn532_mifare_classic.c
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+
+/*  MIFARE CLASSIC DESCRIPTION
+    ==========================
+
+    MIFARE Classic cards come in 1K and 4K varieties.  While several
+    varieties of chips exist, the two main chipsets used are described
+    in the following publicly accessible documents:
+
+        MF1S503x Mifare Classic 1K data sheet:
+        http://www.nxp.com/documents/data_sheet/MF1S503x.pdf
+
+        MF1S70yyX MIFARE Classic 4K data sheet:
+        http://www.nxp.com/documents/data_sheet/MF1S70YYX.pdf
+
+    Mifare Classic cards typically have a a 4-byte NUID, though you may
+    find cards with 7 byte IDs as well
+
+    EEPROM MEMORY
+    =============
+    Mifare Classic cards have either 1K or 4K of EEPROM memory. Each
+    memory block can be configured with different access conditions,
+    with two seperate authentication keys present in each block.
+
+    The two main Mifare Classic card types are organised as follows:
+
+        1K Cards: 16 sectors of 4 blocks (0..15)
+        4K Cards: 32 sectors of 4 blocks (0..31) and
+                  8 sectors of 16 blocks (32..39)
+
+    4 block sectors
+    ===============
+    Sector  Block   Bytes                                                           Description
+    ------  -----   -----                                                           -----------
+                    0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
+
+    1       3       [-------KEY A-------]   [Access Bits]   [-------KEY B-------]   Sector Trailer 1
+            2       [                            Data                           ]   Data
+            1       [                            Data                           ]   Data
+            0       [                            Data                           ]   Data
+
+    0       3       [-------KEY A-------]   [Access Bits]   [-------KEY B-------]   Sector Trailer 1
+            2       [                            Data                           ]   Data
+            1       [                            Data                           ]   Data
+            0       [                     Manufacturer Data                     ]   Manufacturer Block
+
+    Sector Trailer (Block 3)
+    ------------------------
+    The sector trailer block contains the two secret keys (Key A and Key B), as well
+    as the access conditions for the four blocks.  It has the following structure:
+
+        Sector Trailer Bytes
+        --------------------------------------------------------------
+        0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
+        [       Key A       ]   [Access Bits]   [       Key B       ]
+
+    For more information in using Keys to access the clock contents, see
+    Accessing Data Blocks further below.
+
+    Data Blocks (Blocks 0..2)
+    -------------------------
+    Data blocks are 16 bytes wide and, depending on the permissions set in the
+    access bits, can be read from and written to. You are free to use the 16 data
+    bytes in any way you wish.  You can easily store text input, store four 32-bit
+    integer values, a 16 character uri, etc.
+
+    Data Blocks as "Value Blocks"
+    -----------------------------
+    An alternative to storing random data in the 16 byte-wide blocks is to
+    configure them as "Value Blocks".  Value blocks allow performing electronic
+    purse functions (valid commands are: read, write, increment, decrement,
+    restore, transfer).
+
+    Each Value block contains a single signed 32-bit value, and this value is
+    stored 3 times for data integrity and security reasons.  It is stored twice
+    non-inverted, and once inverted.  The last 4 bytes are used for a 1-byte
+    address, which is stored 4 times (twice non-inverted, and twice inverted).
+
+    Data blocks configured as "Value Blocks" have the following structure:
+
+        Value Block Bytes
+        --------------------------------------------------------------
+        0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
+        [   Value   ]   [   ~Value  ]   [   Value   ]   [A  ~A  A   ~A]
+
+    For more information on value blocks see 8.6.2 and chapter 10 in:
+    http://www.nxp.com/documents/data_sheet/MF1S503x.pdf
+
+    Manufacturer Block (Sector 0, Block 0)
+    --------------------------------------
+    Sector 0 is special since it contains the Manufacturer Block. This block
+    contains the manufacturer data, and is read-only.  It should be avoided
+    unless you know what you are doing.
+
+    16 block sectors
+    ================
+    16 block sectors are identical to 4 block sectors, but with more data blocks.  The same
+    structure described in the 4 block sectors above applies.
+
+    Sector  Block   Bytes                                                           Description
+    ------  -----   -----                                                           ----------
+                    0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
+
+    32      15      [-------KEY A-------]   [Access Bits]   [-------KEY B-------]   Sector Trailer 32
+            14      [                            Data                           ]   Data
+            13      [                            Data                           ]   Data
+            ...
+            2       [                            Data                           ]   Data
+            1       [                            Data                           ]   Data
+            0       [                            Data                           ]   Data
+
+    ACCESSING DATA BLOCKS
+    =====================
+
+    In order to access the Mifare Classic card, you must follow these steps:
+
+    1.) You must retrieve the 7 byte UID or the 4-byte NUID of the card.
+        This can be done using pn532_mifareclassic_WaitForPassiveTarget()
+        below, which will return the appropriate ID.
+
+    2.) You must authenticate the sector you wish to access according to the
+        access rules defined in the Sector Trailer block for that sector.
+        This can be done using pn532_mifareclassic_AuthenticateBlock(),
+        passing in the appropriate key value.
+
+        Most new cards have a default Key A of 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF,
+        but some common values worth trying are:
+
+            0XFF 0XFF 0XFF 0XFF 0XFF 0XFF
+            0XD3 0XF7 0XD3 0XF7 0XD3 0XF7
+            0XA0 0XA1 0XA2 0XA3 0XA4 0XA5
+            0XB0 0XB1 0XB2 0XB3 0XB4 0XB5
+            0X4D 0X3A 0X99 0XC3 0X51 0XDD
+            0X1A 0X98 0X2C 0X7E 0X45 0X9A
+            0XAA 0XBB 0XCC 0XDD 0XEE 0XFF
+            0X00 0X00 0X00 0X00 0X00 0X00
+            0XAB 0XCD 0XEF 0X12 0X34 0X56
+
+    3.) Once authentication has succeeded, and depending on the sector
+        permissions, you can then read/write/increment/decrement the
+        contents of the specific block, using one of the helper functions
+        included in this module.
+
+*/
+
+#include "projectconfig.h"
+
+#ifdef CFG_PN532
+
+#include <string.h>
+
+#include "../pn532.h"
+#include "../pn532_bus.h"
+#include "pn532_mifare.h"
+#include "pn532_mifare_classic.h"
+
+#include "core/delay/delay.h"
+
+/**************************************************************************/
+/*!
+    Resets the magnetic field and waits for a new Type A tag
+*/
+/**************************************************************************/
+static pn532_error_t pn532_mifareclassic_reset()
+{
+  uint8_t sak;
+  uint16_t atqa;
+  uint8_t uid[8];
+  size_t leng;
+  pn532_error_t error;
+
+  pn532_mifareclassic_RFfield(FALSE);
+  delay(50);
+  pn532_mifareclassic_RFfield(TRUE);
+  error = pn532_mifareclassic_WaitForTypeATags(&sak, &atqa, &uid[0], &leng);
+
+  return error;
+}
+
+/**************************************************************************/
+/*!
+    Indicates whether the specified block number is the first block
+    in the sector (block 0 relative to the current sector)
+*/
+/**************************************************************************/
+bool pn532_mifareclassic_isFirstBlock (uint32_t uiBlock)
+{
+  // Test if we are in the small or big sectors
+  if (uiBlock < 128)
+    return ((uiBlock) % 4 == 0);
+  else
+    return ((uiBlock) % 16 == 0);
+}
+
+/**************************************************************************/
+/*!
+    Indicates whether the specified block number is the sector trailer
+*/
+/**************************************************************************/
+bool pn532_mifareclassic_isTrailerBlock (uint32_t uiBlock)
+{
+  // Test if we are in the small or big sectors
+  if (uiBlock < 128)
+    return ((uiBlock + 1) % 4 == 0);
+  else
+    return ((uiBlock + 1) % 16 == 0);
+}
+
+/**************************************************************************/
+/*!
+    Tries to detect MIFARE targets in passive mode.  This needs to be done
+    before anything useful can be accomplished with a tag since you need
+    the tag's unique UID to communicate with it.
+
+    @param  pbtCUID     Pointer to the byte array where the card's UID
+                        will be stored once a card is detected
+    @param  pszCUIDLen  Pointer to the size of the card UID in bytes
+
+    Response for a valid ISO14443A 106KBPS (Mifare Classic, etc.)
+    should be in the following format.  See UM0701-02 section
+    7.3.5 for more information
+
+    byte            Description
+    -------------   ------------------------------------------
+    b0..6           Frame header and preamble
+    b7              Tags Found
+    b8              Tag Number (only one used in this example)
+    b9..10          SENS_RES
+    b11             SEL_RES
+    b12             NFCID Length
+    b13..NFCIDLen   NFCID
+
+    SENS_RES   SEL_RES     Manufacturer/Card Type    NFCID Len
+    --------   -------     -----------------------   ---------
+    00 04      08          NXP Mifare Classic 1K     4 bytes
+    00 02      18          NXP Mifare Classic 4K     4 bytes
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_WRONGCARDTYPE
+*/
+/**************************************************************************/
+pn532_error_t pn532_mifareclassic_WaitForPassiveTarget (byte_t * pbtCUID, size_t * pszCUIDLen)
+{
+  byte_t abtResponse[PN532_RESPONSELEN_INLISTPASSIVETARGET];
+  pn532_error_t error;
+  size_t szLen;
+    uint8_t i;
+
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Waiting for an ISO14443A Card%s", CFG_PRINTF_NEWLINE);
+  #endif
+
+  /* Try to initialise a single ISO14443A tag at 106KBPS                  */
+  /* Note:  To wait for a card with a known UID, append the four byte     */
+  /*        UID to the end of the command.                                */
+  byte_t abtCommand[] = { PN532_COMMAND_INLISTPASSIVETARGET, 0x01, PN532_MODULATION_ISO14443A_106KBPS};
+  error = pn532Write(abtCommand, sizeof(abtCommand));
+  if (error)
+    return error;
+
+  /* Wait until we get a valid response or a timeout                      */
+  do
+  {
+    delay(25);
+    error = pn532Read(abtResponse, &szLen);
+  } while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
+  if (error)
+    return error;
+
+  /* Check szLen ... if it's 10 we've probably timed out via MaxRetries */
+  /* ToDo: Properly parse and handle this error case! */
+  if (szLen == 10)
+  {
+    return PN532_ERROR_TIMEOUTWAITINGFORCARD;
+  }
+
+  /* Check SENSE_RES to make sure this is a Mifare Classic card           */
+  /*          Classic 1K       = 00 04                                    */
+  /*          Classic 4K       = 00 02                                    */
+  /*          Classic Emulated = 00 08                                    */
+  if ((abtResponse[10] == 0x02) ||
+      (abtResponse[10] == 0x04) ||
+      (abtResponse[10] == 0x08))
+  {
+    /* Card appears to be Mifare Classic */
+    *pszCUIDLen = abtResponse[12];
+    for (i=0; i < *pszCUIDLen; i++)
+    {
+      pbtCUID[i] = abtResponse[13+i];
+    }
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Card Found: %s", CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("      ATQA: ");
+      pn532PrintHex(abtResponse+9, 2);
+      PN532_DEBUG("      SAK: %02x%s", abtResponse[11], CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("      UID: ");
+      pn532PrintHex(pbtCUID, *pszCUIDLen);
+    #endif
+  }
+  else
+  {
+    /* Card is ISO14443A but doesn't appear to be Mifare Classic          */
+    /*    Mifare Ultralight    = 0x0044                                   */
+    /*    Mifare DESFire       = 0x0344                                   */
+    /*    Innovision Jewel     = 0x0C00                                   */
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Wrong Card Type (Expected ATQA 00 02, 00 04 or 00 08) %s%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("  ATQA       : ");
+      pn532PrintHex(abtResponse+9, 2);
+      PN532_DEBUG("  SAK        : %02x%s", abtResponse[11], CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("  UID Length : %d%s", abtResponse[12], CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("  UID        : ");
+      size_t pos;
+      for (pos=0; pos < abtResponse[12]; pos++)
+      {
+        printf("%02x ", abtResponse[13 + pos]);
+      }
+      printf("%s%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+    #endif
+    return PN532_ERROR_WRONGCARDTYPE;
+  }
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    Tries to detect MIFARE targets in passive mode.
+
+    @param  pSak [out]  Pointer SAK byte
+    @param  Atqa        Pointer to ATQA data
+
+    Response for a valid ISO14443A 106KBPS (Mifare Classic, etc.)
+    should be in the following format.  See UM0701-02 section
+    7.3.5 for more information
+
+    byte            Description
+    -------------   ------------------------------------------
+    b0..6           Frame header and preamble
+    b7              Tags Found
+    b8              Tag Number (only one used in this example)
+    b9..10          SENS_RES
+    b11             SEL_RES
+    b12             NFCID Length
+    b13..NFCIDLen   NFCID
+
+    SENS_RES   SEL_RES     Manufacturer/Card Type    NFCID Len
+    --------   -------     -----------------------   ---------
+    00 04      08          NXP Mifare Classic 1K     4 bytes
+    00 02      18          NXP Mifare Classic 4K     4 bytes
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_WRONGCARDTYPE
+            - PN532_ERROR_TIMEOUTWAITINGFORCARD
+*/
+/**************************************************************************/
+pn532_error_t pn532_mifareclassic_WaitForTypeATags (byte_t * pSak, uint16_t * pAtqa, byte_t * pbtCUID, size_t * szCUIDLen)
+{
+  byte_t abtResponse[PN532_RESPONSELEN_INLISTPASSIVETARGET];
+  pn532_error_t error;
+  size_t szLen;
+  uint8_t i;
+
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Waiting for an ISO14443A Card%s", CFG_PRINTF_NEWLINE);
+  #endif
+
+  /* Try to initialise a single ISO14443A tag at 106KBPS                  */
+  /* Note:  To wait for a card with a known UID, append the four byte     */
+  /*        UID to the end of the command.                                */
+  byte_t abtCommand[] = { PN532_COMMAND_INLISTPASSIVETARGET, 0x01, PN532_MODULATION_ISO14443A_106KBPS};
+  error = pn532Write(abtCommand, sizeof(abtCommand));
+  if (error)
+    return error;
+
+  /* Wait until we get a valid response or a timeout                      */
+  do
+  {
+    delay(25);
+    error = pn532Read(abtResponse, &szLen);
+  } while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
+  if (error)
+    return error;
+
+  /* Check szLen ... if it's 10 we've probably timed out via MaxRetries */
+  /* ToDo: Properly parse and handle this error case! */
+  if (szLen == 10)
+  {
+    return PN532_ERROR_TIMEOUTWAITINGFORCARD;
+  }
+
+  *pAtqa = ((uint16_t)abtResponse[9]<<8) | (uint16_t)abtResponse[10];
+  *pSak = abtResponse[11];
+  *szCUIDLen = abtResponse[12];
+  for (i=0; i < *szCUIDLen; i++)
+  {
+    pbtCUID[i] = abtResponse[13+i];
+  }
+#ifdef PN532_DEBUGMODE
+  printf("SAK: %02x ",  *pSak);
+  printf("ATQA: %04x ", *pAtqa);
+#endif
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    Tries to authenticate a block of memory on a MIFARE card using the
+    INDATAEXCHANGE command.  See section 7.3.8 of the PN532 User Manual
+    for more information on sending MIFARE and other commands.
+
+    @param  pbtCUID       Pointer to a byte array containing the card UID
+    @param  szCUIDLen     The length (in bytes) of the card's UID (Should
+                          be 4 for MIFARE Classic)
+    @param  uiBlockNumber The block number to authenticate.  (0..63 for
+                          1KB cards, and 0..255 for 4KB cards).
+    @param  uiKeyType     Which key type to use during authentication
+                          (PN532_MIFARE_CMD_AUTH_A or PN532_MIFARE_CMD_AUTH_B)
+    @param  pbtKeys       Pointer to a byte array containing the 6 byte
+                          key value
+*/
+/**************************************************************************/
+pn532_error_t pn532_mifareclassic_AuthenticateBlock (byte_t * pbtCUID, size_t szCUIDLen, uint32_t uiBlockNumber, uint8_t uiKeyType, byte_t * pbtKeys)
+{
+  pn532_error_t error;
+  byte_t abtCommand[17];
+  byte_t abtResponse[PN532_RESPONSELEN_INDATAEXCHANGE];
+  size_t szLen;
+  uint8_t i;
+
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Trying to authenticate card ");
+  pn532PrintHex(pbtCUID, szCUIDLen);
+  #endif
+
+  /* Prepare the authentication command */
+  abtCommand[0] = PN532_COMMAND_INDATAEXCHANGE;   /* Data Exchange Header */
+  abtCommand[1] = 1;                              /* Max card numbers */
+  abtCommand[2] = (uiKeyType == PN532_MIFARE_CMD_AUTH_B) ? PN532_MIFARE_CMD_AUTH_B : PN532_MIFARE_CMD_AUTH_A;
+  abtCommand[3] = uiBlockNumber;                  /* Block Number (1K = 0..63, 4K = 0..255 */
+  memcpy (abtCommand+4, pbtKeys, 6);
+  for (i = 0; i < szCUIDLen; i++)
+  {
+    abtCommand[10+i] = pbtCUID[i];                /* 4 byte card ID */
+  }
+
+  /* Send the command */
+  error = pn532Write(abtCommand, 10+szCUIDLen);
+  if (error)
+  {
+    /* Problem with the serial bus, etc. */
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Authentification failed%s", CFG_PRINTF_NEWLINE);
+    #endif
+    pn532_mifareclassic_reset();
+    return error;
+  }
+
+  /* Read the authentication response */
+  memset(abtResponse, 0, PN532_RESPONSELEN_INDATAEXCHANGE);
+  do
+  {
+    delay(25);
+    error = pn532Read(abtResponse, &szLen);
+  }
+  while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
+  if (error)
+  {
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Authentification failed%s", CFG_PRINTF_NEWLINE);
+    #endif
+    pn532_mifareclassic_reset();
+
+    return error;
+  }
+
+  /* For authentication success, bytes 5-7 should be: 0xD5 0x41 0x00 */
+  /* Mifare auth error is technically byte 7: 0x14 but anything other and 0x00 */
+  /* is not good */
+  {
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Authentification failed%s", CFG_PRINTF_NEWLINE);
+    #endif
+    pn532_mifareclassic_reset();
+    return PN532_ERROR_AUTHENTICATE_FAIL;
+  }
+
+  /* Output the authentication data */
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Authenticated block %d %s", uiBlockNumber, CFG_PRINTF_NEWLINE);
+  #endif
+
+  // Return OK signal
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    Tries to read an entire 16-byte data block at the specified block
+    address.
+
+    @param  uiBlockNumber The block number to authenticate.  (0..63 for
+                          1KB cards, and 0..255 for 4KB cards).
+    @param  pbtData       Pointer to the byte array that will hold the
+                          retrieved data (if any)
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_BLOCKREADFAILED
+*/
+/**************************************************************************/
+pn532_error_t pn532_mifareclassic_ReadDataBlock (uint8_t uiBlockNumber, byte_t * pbtData)
+{
+  pn532_error_t error;
+  byte_t abtCommand[4];
+  byte_t abtResponse[PN532_RESPONSELEN_INDATAEXCHANGE];
+  size_t szLen;
+
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Reading 16 bytes at block %03d%s", uiBlockNumber, CFG_PRINTF_NEWLINE);
+  #endif
+
+  /* Prepare the command */
+  abtCommand[0] = PN532_COMMAND_INDATAEXCHANGE;
+  abtCommand[1] = 1;                            /* Card number */
+  abtCommand[2] = PN532_MIFARE_CMD_READ;        /* Mifare Read command = 0x30 */
+  abtCommand[3] = uiBlockNumber;                /* Block Number (0..63 for 1K, 0..255 for 4K) */
+
+  /* Send the commands */
+  error = pn532Write(abtCommand, sizeof(abtCommand));
+  if (error)
+  {
+    /* Bus error, etc. */
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Read failed%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return error;
+  }
+
+  /* Read the response */
+  memset(abtResponse, 0, PN532_RESPONSELEN_INDATAEXCHANGE);
+  do
+  {
+    delay(50);
+    error = pn532Read(abtResponse, &szLen);
+  }
+  while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
+  if (error)
+  {
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Read failed%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return error;
+  }
+
+  /* Make sure we have a valid response (should be 26 bytes long) */
+  if (szLen == 26)
+  {
+    /* Copy the 16 data bytes to the output buffer        */
+    /* Block content starts at byte 9 of a valid response */
+    memcpy (pbtData, abtResponse+8, 16);
+  }
+  else
+  {
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Unexpected response reading block %d.  Bad key?%s", uiBlockNumber, CFG_PRINTF_NEWLINE);
+    #endif
+    return PN532_ERROR_BLOCKREADFAILED;
+  }
+
+  /* Display data for debug if requested */
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Block %03d: %s", uiBlockNumber, CFG_PRINTF_NEWLINE);
+    pn532PrintHexChar(pbtData, 16);
+  #endif
+
+  // Return OK signal
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    Tries to write an entire 16-byte data block at the specified block
+    address.
+
+    @param  uiBlockNumber The block number to write to (0..63 for
+                          1KB cards, and 0..255 for 4KB cards).
+    @param  pbtData       Pointer to the byte array to write
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_BLOCKWRITEFAILED
+*/
+/**************************************************************************/
+pn532_error_t pn532_mifareclassic_WriteDataBlock (uint8_t uiBlockNumber, byte_t * pbtData)
+{
+  pn532_error_t error;
+  byte_t abtCommand[20]; /* 16 byte payload + 4 command bytes */
+  byte_t abtResponse[PN532_RESPONSELEN_INDATAEXCHANGE];
+  size_t szResponseLen;
+
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Trying to write 16 bytes at block %02d%s", uiBlockNumber, CFG_PRINTF_NEWLINE);
+  #endif
+
+  /* Prepare the command */
+  abtCommand[0] = PN532_COMMAND_INDATAEXCHANGE;
+  abtCommand[1] = 1;                            /* Card number */
+  abtCommand[2] = PN532_MIFARE_CMD_WRITE;       /* Mifare Write command = 0xA0 */
+  abtCommand[3] = uiBlockNumber;                /* Block Number (0..63 for 1K, 0..255 for 4K) */
+  memcpy (abtCommand+4, pbtData, 16);           /* Data Payload */
+
+  /* Send the commands */
+  error = pn532Write(abtCommand, sizeof(abtCommand));
+  if (error)
+  {
+    /* Bus error, etc. */
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Write failed%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return error;
+  }
+
+  /* Read the response */
+  memset(abtResponse, 0, PN532_RESPONSELEN_INDATAEXCHANGE);
+  do
+  {
+    delay(50);
+    error = pn532Read(abtResponse, &szResponseLen);
+  }
+  while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
+  if (error)
+  {
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Write failed%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return error;
+  }
+
+  /* Make sure we have a valid response (should be 26 bytes long) */
+  if (szResponseLen == 26)
+  {
+    /* Copy the 16 data bytes to the output buffer        */
+    /* Block content starts at byte 9 of a valid response */
+    memcpy (pbtData, abtResponse+9, 16);
+  }
+  else
+  {
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Unexpected response writing block %d.  Bad key?%s", uiBlockNumber, CFG_PRINTF_NEWLINE);
+    #endif
+    return PN532_ERROR_BLOCKWRITEFAILED;
+  }
+
+  /* Display data for debug if requested */
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Block %03d: ", uiBlockNumber);
+    pn532PrintHexChar(pbtData, 16);
+  #endif
+
+  // Return OK signal
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    Tries to create a 'value-block' at the specified block.  Value blocks
+    contain a single 32-bit signed integer, and can be incremented,
+    decremented, and manipulated using a set of pre-defined Mifare
+    commands.
+
+    For more information on 'Value Blocks' see section 8.6.2 in:
+    http://www.nxp.com/documents/data_sheet/MF1S503x.pdf
+
+    @param  uiBlockNumber The block number to write to (0..63 for
+                          1KB cards, and 0..255 for 4KB cards).
+    @param  value         The 32-bit integer value to store
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_BLOCKWRITEFAILED
+*/
+/**************************************************************************/
+pn532_error_t pn532_mifareclassic_CreateValueBlock (uint8_t uiBlockNumber, int32_t value)
+{
+  pn532_error_t error;
+  byte_t buffer[16];
+  int32_t inverted;
+
+  /* Display data for debug if requested */
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Writing value block at %d: %d %s", uiBlockNumber, value, CFG_PRINTF_NEWLINE);
+  #endif
+
+  /* First four bytes are the regular value in lsb format */
+  buffer[0] = (value >> 24) & 0xFF;
+  buffer[1] = (value >> 16) & 0xFF;
+  buffer[2] = (value >> 8) & 0xFF;
+  buffer[3] = value & 0xFF;
+
+  /* Next four bytes are the value inverted */
+  inverted = ~value;
+  buffer[4] = (inverted >> 24) & 0xFF;
+  buffer[5] = (inverted >> 16) & 0xFF;
+  buffer[6] = (inverted >> 8) & 0xFF;
+  buffer[7] = inverted & 0xFF;
+
+  /* Next four bytes are the regular value in lsb format again */
+  buffer[8] = (value >> 24) & 0xFF;
+  buffer[9] = (value >> 16) & 0xFF;
+  buffer[10] = (value >> 8) & 0xFF;
+  buffer[11] = value & 0xFF;
+
+  /* Last four bytes are the addr byte (use block number for now) */
+  buffer[12] = uiBlockNumber;    /* Normal value */
+  buffer[13] = ~uiBlockNumber;   /* Inverted */
+  buffer[14] = uiBlockNumber;    /* Normal value */
+  buffer[15] = ~uiBlockNumber;   /* Inverted */
+
+  error = pn532_mifareclassic_WriteDataBlock(uiBlockNumber, buffer);
+  if (error)
+    return error;
+
+  // Return OK signal
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    Returns a 32-bit integer value from a Mifare Value Block
+
+    @param  uiBlockNumber The block number to write to (0..63 for
+                          1KB cards, and 0..255 for 4KB cards).
+    @param  value         Placeholder for the 32-bit integer
+*/
+/**************************************************************************/
+pn532_error_t pn532_mifareclassic_ReadValueBlock (uint8_t uiBlockNumber, int32_t * value)
+{
+  pn532_error_t error;
+  /* ToDo: This should only require 16 bytes ... but test for overflow to be sure */
+  /* Was 'PN532_RESPONSELEN_INDATAEXCHANGE' for len */
+  byte_t abtBlockData[16];
+
+  // Make sure the block address is valid, and we're not in the sector trailer
+  if (uiBlockNumber > 255 || uiBlockNumber < 1 || pn532_mifareclassic_isTrailerBlock(uiBlockNumber))
+  {
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Invalid block number%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return PN532_ERROR_ADDRESSOUTOFRANGE;
+  }
+
+  /* Try to read the appropriate data block */
+  error = pn532_mifareclassic_ReadDataBlock (uiBlockNumber, abtBlockData);
+  if (!error)
+  {
+    int32_t vpos, vneg;
+    /* Positive value */
+    vpos =  abtBlockData[0] << 24;
+    vpos |= abtBlockData[1] << 16;
+    vpos |= abtBlockData[2] << 8;
+    vpos |= abtBlockData[3] & 0xFF;
+    /* Inverted value */
+    vneg =  abtBlockData[4] << 24;
+    vneg |= abtBlockData[5] << 16;
+    vneg |= abtBlockData[6] << 8;
+    vneg |= abtBlockData[7] & 0xFF;
+    if (~vpos != vneg)
+    {
+      /* This isn't a properly formatted Mifare Value Block */
+      return PN532_ERROR_INCORRECTBLOCKFORMAT;
+    }
+    else
+    {
+      *value = vpos;
+      return PN532_ERROR_NONE;
+    }
+  }
+  else
+  {
+    return error;
+  }
+}
+
+/**************************************************************************/
+/*!
+    Increments a Value Block by the specified number, and then sends the
+    transfer command to persist the changes.
+
+    @param  uiBlockNumber The block number to write to (0..63 for
+                          1KB cards, and 0..255 for 4KB cards).
+    @param  value         The 32-bit integer value to store
+*/
+/**************************************************************************/
+pn532_error_t pn532_mifareclassic_IncrementValueBlock (uint8_t uiBlockNumber, int32_t value)
+{
+  pn532_error_t error;
+  int32_t oldValue, newValue;
+
+  // It's less code just to recreate the block rather than using
+  // the Mifare increment command
+
+  // First read the value
+  error = pn532_mifareclassic_ReadValueBlock(uiBlockNumber, &oldValue);
+  if (error)
+    return error;
+
+  // Increment the old value
+  newValue = oldValue + value;
+
+  // Write it back
+  error = pn532_mifareclassic_CreateValueBlock(uiBlockNumber, newValue);
+  if (error)
+    return error;
+
+  // Return OK signal
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    Decrements a Value Block by the specified number, and then sends the
+    transfer command to persist the changes.
+
+    @param  uiBlockNumber The block number to write to (0..63 for
+                          1KB cards, and 0..255 for 4KB cards).
+    @param  value         The 32-bit integer value to store
+*/
+/**************************************************************************/
+pn532_error_t pn532_mifareclassic_DecrementValueBlock (uint8_t uiBlockNumber, int32_t value)
+{
+  pn532_error_t error;
+  int32_t oldValue, newValue;
+
+  // It's less code just to recreate the block rather than using
+  // the Mifare decrement command
+
+  // First read the value
+  error = pn532_mifareclassic_ReadValueBlock(uiBlockNumber, &oldValue);
+  if (error)
+    return error;
+
+  // Increment the old value
+  newValue = oldValue - value;
+
+  // Write it back
+  error = pn532_mifareclassic_CreateValueBlock(uiBlockNumber, newValue);
+  if (error)
+    return error;
+
+  // Return OK signal
+  return PN532_ERROR_NONE;
+}
+
+pn532_error_t pn532_mifareclassic_RFfield(BOOL fieldOn)
+{
+  pn532_error_t error;
+
+  byte_t RFcmdOff[] = {0xD4, 0x32, 0x01, 0x00};
+  byte_t RFcmdOn[]  = {0xD4, 0x32, 0x01, 0x03};
+
+  if(fieldOn == FALSE)
+  {
+    error = pn532Write(RFcmdOff, sizeof(RFcmdOff));
+  }
+  else
+  {
+    error = pn532Write(RFcmdOn, sizeof(RFcmdOn));
+  }
+
+  return error;
+}
+
+#endif  // #ifdef CFG_PN532
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_mifare_classic.h b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_mifare_classic.h
new file mode 100644
index 0000000000000000000000000000000000000000..32eaf23b791b4b36966b01ca20b69fc777b582ad
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_mifare_classic.h
@@ -0,0 +1,64 @@
+/**************************************************************************/
+/*!
+    @file pn532_mifare_classic.h
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __PN532_MIFARE_CLASSIC_H__
+#define __PN532_MIFARE_CLASSIC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "pn532_mifare.h"
+
+/* Generic helper funtions for any Mifare Classic activity */
+bool          pn532_mifareclassic_isFirstBlock (uint32_t uiBlock);
+bool          pn532_mifareclassic_isTrailerBlock (uint32_t uiBlock);
+pn532_error_t pn532_mifareclassic_WaitForPassiveTarget (byte_t * pbtCUID, size_t * szCUIDLen);
+pn532_error_t pn532_mifareclassic_WaitForTypeATags (byte_t * pSak, uint16_t * pAtqa, byte_t * pbtCUID, size_t * szCUIDLen);
+pn532_error_t pn532_mifareclassic_AuthenticateBlock (byte_t * pbtCUID, size_t szCUIDLen, uint32_t uiBlockNumber, uint8_t uiKeyType, byte_t * pbtKeys);
+pn532_error_t pn532_mifareclassic_ReadDataBlock (uint8_t uiBlockNumber, byte_t * pbtData);
+pn532_error_t pn532_mifareclassic_WriteDataBlock (uint8_t uiBlockNumber, byte_t * pbtData);
+pn532_error_t pn532_mifareclassic_RFfield(bool fieldOn);
+/* Help functions for Mifare Value Blocks */
+pn532_error_t pn532_mifareclassic_CreateValueBlock (uint8_t uiBlockNumber, int32_t value);
+pn532_error_t pn532_mifareclassic_ReadValueBlock (uint8_t uiBlockNumber, int32_t * value);
+pn532_error_t pn532_mifareclassic_IncrementValueBlock (uint8_t uiBlockNumber, int32_t value);
+pn532_error_t pn532_mifareclassic_DecrementValueBlock (uint8_t uiBlockNumber, int32_t value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_mifare_ultralight.c b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_mifare_ultralight.c
new file mode 100644
index 0000000000000000000000000000000000000000..5fb541461c380788b97ea051931be1c41c38723e
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_mifare_ultralight.c
@@ -0,0 +1,326 @@
+/**************************************************************************/
+/*!
+    @file pn532_mifare_ultralight.c
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+
+/*  MIFARE ULTRALIGHT DESCRIPTION
+    =============================
+
+    MIFARE Ultralight cards typically contain 512 bits (64 bytes) of
+    memory, including 4 bytes (32-bits) of OTP (One Time Programmable)
+    memory where the individual bits can be written but not erased.
+
+        MF0ICU1 Mifare Ultralight Functional Specification:
+        http://www.nxp.com/documents/data_sheet/MF0ICU1.pdf
+
+
+    Mifare Ultralight cards have a 7-byte UID
+
+    EEPROM MEMORY
+    =============
+    Mifare Ultralight cards have 512 bits (64 bytes) of EEPROM memory,
+    including 4 byte (32 bits) of OTP memory.  Unlike Mifare Classic cards,
+    there is no authentication on a per block level, although the blocks
+    can be set to "read-only" mode using Lock Bytes (described below).
+
+    EEPROM memory is organised into 16 pages of four bytes eachs, in
+    the following order
+
+    Page   Description
+    ----   ------------
+    0      Serial Number (4 bytes)
+    1      Serial Number (4 bytes)
+    2      Byte 0:    Serial Number
+           Byte 1:    Internal Memory
+           Byte 2..3: lock bytes
+    3      One-time programmable memory (4 bytes)
+    4..15  User memory (4 bytes)
+
+    Lock Bytes (Page 2)
+    -------------------
+    Bytes 2 and 3 of page 2 are referred to as "Lock Bytes".  Each
+    page from 0x03 and higher can individually locked by setting the
+    corresponding locking bit to "1" to prevent further write access,
+    effectively making the memory read only.
+
+    For information on the lock byte mechanism, refer to section 8.5.2 of
+    the datasheet (referenced above).
+
+    OTP Bytes (Page 3)
+    ------------------
+    Page 3 is the OTP memory, and by default all bits on this page are
+    set to 0.  These bits can be bitwise modified using the Mifare WRITE
+    command, and individual bits can be set to 1, but can not be changed
+    back to 0.
+
+    Data Pages (Pages 4..15)
+    ------------------------
+    Pages 4 to 15 are can be freely read from and written to,
+    provided there is no conflict with the Lock Bytes described above.
+
+    After production, the bytes have the following default values:
+
+    Page    Byte Values
+    ----    ----------------------
+            0     1     2     3
+    4       0xFF  0xFF  0xFF  0xFF
+    5..15   0x00  0x00  0x00  0x00
+
+    ACCESSING DATA BLOCKS
+    =====================
+
+    Before you can access the cards, you must following two steps:
+
+    1.) 'Connect' to a Mifare Ultralight card and retrieve the 7 byte
+        UID of the card.
+
+    2.) Memory can be read and written directly once a passive mode
+        connection has been made.  No authentication is required for
+        Mifare Ultralight cards.
+
+*/
+#include "projectconfig.h"
+
+#ifdef CFG_PN532
+
+#include <string.h>
+
+#include "../pn532.h"
+#include "../pn532_bus.h"
+#include "pn532_mifare_ultralight.h"
+
+#include "core/delay/delay.h"
+
+/**************************************************************************/
+/*!
+    Tries to detect MIFARE targets in passive mode.
+
+    @param  pbtCUID     Pointer to the byte array where the card's 7 byte
+                        UID will be stored once a card is detected
+    @param  pszCUIDLen  Pointer to the size of the card UID in bytes
+
+    Response for a valid ISO14443A 106KBPS (Mifare Ultralight, etc.)
+    should be in the following format.  See UM0701-02 section
+    7.3.5 for more information
+
+    byte            Description
+    -------------   ------------------------------------------
+    b0..6           Frame header and preamble
+    b7              Tags Found
+    b8              Tag Number (only one used in this example)
+    b9..10          SENS_RES
+    b11             SEL_RES
+    b12             NFCID Length
+    b13..NFCIDLen   NFCID
+
+    SENS_RES   SEL_RES     Manufacturer/Card Type    NFCID Len
+    --------   -------     -----------------------   ---------
+    00 44      00          NXP Mifare Ultralight     7 bytes
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_WRONGCARDTYPE
+*/
+/**************************************************************************/
+pn532_error_t pn532_mifareultralight_WaitForPassiveTarget (byte_t * pbtCUID, size_t * pszCUIDLen)
+{
+  byte_t abtResponse[PN532_RESPONSELEN_INLISTPASSIVETARGET];
+  pn532_error_t error;
+  size_t szLen;
+  uint8_t i;
+
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Waiting for an ISO14443A Card%s", CFG_PRINTF_NEWLINE);
+  #endif
+
+  /* Try to initialise a single ISO14443A tag at 106KBPS                  */
+  /* Note:  To wait for a card with a known UID, append the four byte     */
+  /*        UID to the end of the command.                                */
+  byte_t abtCommand[] = { PN532_COMMAND_INLISTPASSIVETARGET, 0x01, PN532_MODULATION_ISO14443A_106KBPS};
+  error = pn532Write(abtCommand, sizeof(abtCommand));
+  if (error)
+    return error;
+
+  /* Wait until we get a valid response or a timeout                      */
+  do
+  {
+    delay(25);
+    error = pn532Read(abtResponse, &szLen);
+  } while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
+  if (error)
+    return error;
+
+  /* Check szLen ... if it's 10 we've probably timed out via MaxRetries */
+  /* ToDo: Properly parse and handle this error case! */
+  if (szLen == 10)
+  {
+    return PN532_ERROR_TIMEOUTWAITINGFORCARD;
+  }
+
+  /* Check SENS_RES to make sure this is a Mifare Ultralight card         */
+  /*          Mifare Ultralight = 00 44                                   */
+  if (abtResponse[10] == 0x44)
+  {
+    /* Card appears to be Mifare Ultralight */
+    *pszCUIDLen = abtResponse[12];
+    for (i=0; i < *pszCUIDLen; i++)
+    {
+      pbtCUID[i] = abtResponse[13+i];
+    }
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Card Found: %s", CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("      ATQA: ");
+      pn532PrintHex(abtResponse+9, 2);
+      PN532_DEBUG("      SAK: %02x%s", abtResponse[11], CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("      UID: ");
+      pn532PrintHex(pbtCUID, *pszCUIDLen);
+    #endif
+  }
+  else
+  {
+    /* Card is ISO14443A but doesn't appear to be Mifare Ultralight       */
+    /*    Mifare Classic       = 0x0002, 0x0004, 0x0008                   */
+    /*    Mifare DESFire       = 0x0344                                   */
+    /*    Innovision Jewel     = 0x0C00                                   */
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Wrong Card Type (Expected ATQA 00 44) %s%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("  ATQA       : ");
+      pn532PrintHex(abtResponse+9, 2);
+      PN532_DEBUG("  SAK        : %02x%s", abtResponse[11], CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("  UID Length : %d%s", abtResponse[12], CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("  UID        : ");
+      size_t pos;
+      for (pos=0; pos < abtResponse[12]; pos++)
+      {
+        printf("%02x ", abtResponse[13 + pos]);
+      }
+      printf("%s%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+    #endif
+    return PN532_ERROR_WRONGCARDTYPE;
+  }
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    Tries to read an entire 4-byte page at the specified address.
+
+    @param  page        The page number (0..63 in most cases)
+    @param  pbtBuffer   Pointer to the byte array that will hold the
+                        retrieved data (if any)
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_ADDRESSOUTOFRANGE
+            - PN532_ERROR_BLOCKREADFAILED
+*/
+/**************************************************************************/
+pn532_error_t pn532_mifareultralight_ReadPage (uint8_t page, byte_t * pbtBuffer)
+{
+  pn532_error_t error;
+  byte_t abtCommand[4];
+  byte_t abtResponse[PN532_RESPONSELEN_INDATAEXCHANGE];
+  size_t szLen;
+
+  if (page >= 64)
+  {
+    return PN532_ERROR_ADDRESSOUTOFRANGE;
+  }
+
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Reading page %03d%s", page, CFG_PRINTF_NEWLINE);
+  #endif
+
+  /* Prepare the command */
+  abtCommand[0] = PN532_COMMAND_INDATAEXCHANGE;
+  abtCommand[1] = 1;                            /* Card number */
+  abtCommand[2] = PN532_MIFARE_CMD_READ;        /* Mifare Read command = 0x30 */
+  abtCommand[3] = page;                         /* Page Number (0..63 in most cases) */
+
+  /* Send the commands */
+  error = pn532Write(abtCommand, sizeof(abtCommand));
+  if (error)
+  {
+    /* Bus error, etc. */
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Read failed%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return error;
+  }
+
+  /* Read the response */
+  memset(abtResponse, 0, PN532_RESPONSELEN_INDATAEXCHANGE);
+  do
+  {
+    delay(50);
+    error = pn532Read(abtResponse, &szLen);
+  }
+  while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
+  if (error)
+  {
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Read failed%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return error;
+  }
+
+  /* Make sure we have a valid response (should be 26 bytes long) */
+  if (szLen == 26)
+  {
+    /* Copy the 4 data bytes to the output buffer         */
+    /* Block content starts at byte 9 of a valid response */
+    /* Note that the command actually reads 16 byte or 4  */
+    /* pages at a time ... we simply discard the last 12  */
+    /* bytes                                              */
+    memcpy (pbtBuffer, abtResponse+8, 4);
+  }
+  else
+  {
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Unexpected response reading block %d.  Bad key?%s", page, CFG_PRINTF_NEWLINE);
+    #endif
+    return PN532_ERROR_BLOCKREADFAILED;
+  }
+
+  /* Display data for debug if requested */
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Page %02d: %s", page, CFG_PRINTF_NEWLINE);
+    pn532PrintHexChar(pbtBuffer, 4);
+  #endif
+
+  // Return OK signal
+  return PN532_ERROR_NONE;
+}
+
+#endif  // #ifdef CFG_PN532
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_mifare_ultralight.h b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_mifare_ultralight.h
new file mode 100644
index 0000000000000000000000000000000000000000..383d634eb84bca889ecb8155d5f2ba3de881b141
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_mifare_ultralight.h
@@ -0,0 +1,52 @@
+/**************************************************************************/
+/*!
+    @file pn532_mifare_ultralight.h
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __PN532_MIFARE_ULTRALIGHT_H__
+#define __PN532_MIFARE_ULTRALIGHT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "pn532_mifare.h"
+
+pn532_error_t pn532_mifareultralight_WaitForPassiveTarget (byte_t * pbtCUID, size_t * szCUIDLen);
+pn532_error_t pn532_mifareultralight_ReadPage (uint8_t page, byte_t * pbtBuffer);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_ndef.c b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_ndef.c
new file mode 100644
index 0000000000000000000000000000000000000000..a4e446d205eb8aef0518e5cac5f96a0763cc797d
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_ndef.c
@@ -0,0 +1,1187 @@
+/**************************************************************************/
+/*!
+    @file pn532_ndef.c
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013 Adafruit Industries (www.adafruit.com)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+
+/**************************************************************************
+ NDEF
+ ====
+ The NFC Data Exchange Format (NDEF) is a standardised data format that
+ can be used to exchange information between any compatible NFC device
+ and another NFC device or tag. The data format consists of NDEF
+ Messages and NDEF Records. The standard is maintained by the NFC Forum.
+
+ The NDEF format is used to store and exchange information like URIs,
+ plain text, etc., using a commonly understood format. NFC tags like
+ Mifare Classic cards can be configured as NDEF tags, and data written
+ to them by one NFC device (NDEF Records) can be understood and
+ accessed by any other NDEF compatible device. NDEF messages can also
+ be used to exchange data between two active NFC devices in
+ "peer-to-peer" mode. By adhering to the NDEF data exchange format
+ during communication, devices that would otherwise have no meaningful
+ knowledge of each other or common language are able to share data in
+ an organised, mutually understandable manner.
+
+ Some helpful white papers relating to NDEF are listed below:
+
+ - NFC Data Exchange Format (NDEF) Technical Specification
+ Available at: http://www.nfc-forum.org/specs/spec_list/
+
+ - NFC Record Type Definition (RTD) Specification
+ Available at: http://www.nfc-forum.org/specs/spec_list/
+
+ - NXP White Paper - NFC Forum Type Tags
+ http://www.nxp.com/acrobat_download2/other/identification/173110_NFC_Forum_Type_Tags_WhitePaper.pdf
+
+ NDEF MESSAGES
+ =============
+ NDEF Messages are the basic "transportation" mechanism for NDEF
+ records, with each message containing one or more NDEF Records.
+
+ NDEF Records
+ ============
+ NDEF Records contain a specific payload, and have the
+ following structure that identifies the contents and size of
+ the record:
+
+ Bit 7     6       5       4       3       2       1       0
+ ------  ------  ------  ------  ------  ------  ------  ------
+ [ MB ]  [ ME ]  [ CF ]  [ SR ]  [ IL ]  [        TNF         ]
+
+ [                         TYPE LENGTH                        ]
+
+ [                       PAYLOAD LENGTH                       ]
+
+ [                          ID LENGTH                         ]
+
+ [                         RECORD TYPE                        ]
+
+ [                              ID                            ]
+
+ [                           PAYLOAD                          ]
+
+
+***************************************************************************/
+#include "projectconfig.h"
+
+//#ifdef CFG_PN532
+
+#include "pn532_ndef.h"
+#include "../mem_allocator/pn532_mem.h"
+
+/**************************************************************************/
+/*!
+    Message Begin bit, used to mark the first record within the message
+*/
+/**************************************************************************/
+#define NDEF_HEADER_MB_MASK             ((uint8_t)(0x01U<<7))
+
+/**************************************************************************/
+/*!
+    Message End bit, used to mark the last record in the message
+*/
+/**************************************************************************/
+#define NDEF_HEADER_ME_MASK             ((uint8_t)(0x01U<<6))
+
+/**************************************************************************/
+/*!
+    Message Chunk flag, used to indicate if the record is an initial or
+    middle chunked record
+*/
+/**************************************************************************/
+#define NDEF_HEADER_CF_MASK             ((uint8_t)(0x01U<<5))
+
+/**************************************************************************/
+/*!
+    Short Record flag, used to indicate if the record is a short record,
+    hence it's length contain 1 octet
+*/
+/**************************************************************************/
+#define NDEF_HEADER_SR_MASK             ((uint8_t)(0x01U<<4))
+
+/**************************************************************************/
+/*!
+    ID Length Flag, indicates that the record contains an ID field if set
+*/
+/**************************************************************************/
+#define NDEF_HEADER_IL_MASK             ((uint8_t)(0x01U<<3))
+
+/**************************************************************************/
+/*!
+    Type name format, indicates the structure of the value of the TYPE
+    field
+*/
+/**************************************************************************/
+#define NDEF_HEADER_TNF_MASK            ((uint8_t)(0x07U<<0))
+
+#define NDEF_FLAG_MASK                  (0xF8)
+#define NDEF_TNF_MASK                   (0x07)
+#define NDEF_HEADER_INDEX               (0)
+#define NDEF_TYPE_LENGTH_INDEX          (1)
+#define NDEF_PAYLOAD_LENGTH_INDEX       (2)
+#define NDEF_EXTRACT_FLAGS(header)      ((header) & NDEF_FLAG_MASK)
+#define NDEF_EXTRACT_TNF(header)        ((header) & NDEF_TNF_MASK)
+#define NDEF_RECORD_HEADER(header, tnf) (((header) & NDEF_FLAG_MASK) | ((tnf) & NDEF_TNF_MASK))
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+typedef struct NDefRecord_st
+{
+  uint8_t *pData;                   /** Raw data of entire NDEF record */
+  uint32_t length;                  /** Length of entire NDEF record */
+  uint32_t idLenIndex;
+  uint32_t typeIndex;
+  uint32_t idIndex;
+  uint32_t payloadIndex;
+  uint32_t payloadLen;
+  uint8_t bufferAllocated;          /** Indicates whether the buffer *pData
+                                        is allocated (and managed) by NDEF
+                                        or managed by upper layer */
+  struct NDefRecord_st *pNext;
+} NdefRecord_t;
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_create_empty(pn532_ndef_record_t *pNdefRecord)
+{
+  NdefRecord_t *pRec;
+
+  if (pNdefRecord == NULL)
+  {
+    return PN532_ERROR_INVALID_PARAM;
+  }
+
+  pRec = (NdefRecord_t*) pn532_mem_alloc(sizeof(NdefRecord_t));
+  if (pRec == NULL)
+  {
+    return PN532_ERROR_MEM_INSUFFICIENT;
+  }
+  memset(pRec, 0, sizeof(NdefRecord_t));
+  *pNdefRecord = pRec;
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_createFromValue(pn532_ndef_record_t *pNdefRecord,
+  uint8_t tnf, uint8_t *pType, uint8_t typeLength, uint8_t *pId,
+  uint8_t idLength, uint8_t *pPayload, uint32_t payloadLength)
+{
+  pn532_error_t errCode;
+  NdefRecord_t *pRec;
+
+  if ((pNdefRecord == NULL) || (pType == NULL) || (typeLength == 0))
+  {
+    return PN532_ERROR_INVALID_PARAM;
+  }
+  pRec = (NdefRecord_t*) pn532_mem_alloc(sizeof(NdefRecord_t));
+  if (pRec == NULL)
+  {
+    return PN532_ERROR_MEM_INSUFFICIENT;
+  }
+  memset(pRec, 0, sizeof(NdefRecord_t));
+  errCode = pn532_ndef_update(pRec, tnf, pType, typeLength, pId, idLength,
+    pPayload, payloadLength);
+  if (errCode != PN532_ERROR_NONE)
+  {
+    pn532_mem_free(pRec);
+    return errCode;
+  }
+  pn532_ndef_setMB(pRec);
+  pn532_ndef_setME(pRec);
+  *pNdefRecord = pRec;
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_createFromRawEx(pn532_ndef_record_t *pNdefRecord,
+  uint8_t *pBuffer, uint32_t length,
+  pn532_ndef_create_buffer_mode_t bufferMode)
+{
+  pn532_error_t errCode;
+  NdefRecord_t *pRec;
+
+  if ((pNdefRecord == NULL) || (pBuffer == 0) || (bufferMode
+    < NDEF_CREATE_BUFFER_MODE_DUPLICATE) || (bufferMode
+    > NDEF_CREATE_BUFFER_MODE_DELEGATE))
+  {
+    return PN532_ERROR_INVALID_PARAM;
+  }
+
+  pRec = (NdefRecord_t*) pn532_mem_alloc(sizeof(NdefRecord_t));
+  if (pRec == NULL)
+  {
+    return PN532_ERROR_MEM_INSUFFICIENT;
+  }
+  memset(pRec, 0, sizeof(NdefRecord_t));
+  errCode = pn532_ndef_updateFromRawEx(pRec, pBuffer, length, bufferMode);
+  if (errCode != PN532_ERROR_NONE)
+  {
+    pn532_mem_free(pRec);
+    return errCode;
+  }
+  *pNdefRecord = pRec;
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_createFromRaw(pn532_ndef_record_t *pNdefRecord,
+  uint8_t *pBuffer, uint32_t length)
+{
+  return pn532_ndef_createFromRawEx(pNdefRecord, pBuffer, length,
+    NDEF_CREATE_BUFFER_MODE_DUPLICATE);
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_createFromStream(pn532_ndef_record_t *pNdefRecord,
+  pn532_ndef_fetch_data_fn fnFetch, void* pUserData)
+{
+  pn532_error_t errCode;
+  NdefRecord_t *pRec;
+
+  if ((pNdefRecord == NULL) || (fnFetch == NULL))
+  {
+    return PN532_ERROR_INVALID_PARAM;
+  }
+  pRec = (NdefRecord_t*) pn532_mem_alloc(sizeof(NdefRecord_t));
+  if (pRec == NULL)
+  {
+    return PN532_ERROR_MEM_INSUFFICIENT;
+  }
+  memset(pRec, 0, sizeof(NdefRecord_t));
+  errCode = pn532_ndef_updateFromStream(pRec, fnFetch, pUserData);
+  if (errCode != PN532_ERROR_NONE)
+  {
+    pn532_mem_free(pRec);
+    return errCode;
+  }
+  *pNdefRecord = pRec;
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void pn532_ndef_destroy(pn532_ndef_record_t ndefRecord)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  if (pRec == NULL)
+  {
+    return;
+  }
+  if ((pRec->pData != NULL) && (pRec->bufferAllocated))
+  {
+    pn532_mem_free(pRec->pData);
+  }
+  pn532_mem_free(pRec);
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_update(pn532_ndef_record_t ndefRecord, uint8_t tnf,
+  uint8_t *pType, uint8_t typeLength, uint8_t *pId, uint8_t idLength,
+  uint8_t *pPayload, uint32_t payloadLength)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  uint8_t flags = 0;
+
+  if ((pRec == NULL) || (pType == NULL) || (typeLength == 0))
+  {
+    return PN532_ERROR_INVALID_PARAM;
+  }
+  if (pRec->pData != NULL)
+  {
+    /* Keep the current MB and ME flag */
+    flags = pRec->pData[NDEF_HEADER_INDEX] & (NDEF_HEADER_MB_MASK
+      | NDEF_HEADER_ME_MASK);
+  }
+  /* To keep memory peek low, we pn532_mem_free current data before allocating new data */
+  if ((pRec->pData != NULL) && (pRec->bufferAllocated))
+  {
+    pn532_mem_free(pRec->pData);
+    pRec->pData = NULL;
+    pRec->bufferAllocated = 0;
+  }
+
+  if (pId == NULL)
+  {
+    idLength = 0;
+  }
+  if (pPayload == NULL)
+  {
+    payloadLength = 0;
+  }
+
+  pRec->length = 1                      /* FLAG + TNF */
+  + 1                                   /* TYPE LENGTH */
+  + (payloadLength > 0xFF ? 4 : 1)      /* PAYLOAD LENGTH */
+  + (idLength > 0 ? 1 + idLength : 0)   /* ID LENGTH + ID */
+  + typeLength                          /* TYPE */
+  + payloadLength;                      /* PAYLOAD */
+  pRec->pData = (uint8_t*) pn532_mem_alloc(pRec->length);
+  if (pRec->pData == NULL)
+  {
+    pRec->bufferAllocated = 0;
+    return PN532_ERROR_MEM_INSUFFICIENT;
+  }
+  pRec->bufferAllocated = 1;
+
+  if (payloadLength < 0xFF)
+  {
+    flags |= NDEF_HEADER_SR_MASK;
+  }
+  if (idLength > 0)
+  {
+    flags |= NDEF_HEADER_IL_MASK;
+  }
+  pRec->pData[NDEF_HEADER_INDEX] = NDEF_RECORD_HEADER(flags, tnf);
+  pRec->pData[NDEF_TYPE_LENGTH_INDEX] = typeLength;
+
+  if (payloadLength < 0xFF)
+  {
+    pRec->pData[NDEF_PAYLOAD_LENGTH_INDEX] = (uint8_t) payloadLength;
+    pRec->idLenIndex = NDEF_PAYLOAD_LENGTH_INDEX + 1;
+  }
+  else
+  {
+    pRec->pData[NDEF_PAYLOAD_LENGTH_INDEX] = (uint8_t)(
+      (payloadLength >> 24) & 0xFF);
+    pRec->pData[NDEF_PAYLOAD_LENGTH_INDEX + 1] = (uint8_t)(
+      (payloadLength >> 16) & 0xFF);
+    pRec->pData[NDEF_PAYLOAD_LENGTH_INDEX + 2] = (uint8_t)(
+      (payloadLength >> 8) & 0xFF);
+    pRec->pData[NDEF_PAYLOAD_LENGTH_INDEX + 3] = (uint8_t)(
+      payloadLength & 0xFF);
+    pRec->idLenIndex = NDEF_PAYLOAD_LENGTH_INDEX + 4;
+  }
+
+  if (idLength > 0)
+  {
+    pRec->pData[pRec->idLenIndex] = idLength;
+    pRec->typeIndex = pRec->idLenIndex + 1;
+  }
+  else
+  {
+    pRec->typeIndex = pRec->idLenIndex;
+  }
+
+  memcpy(pRec->pData + pRec->typeIndex, pType, typeLength);
+  pRec->idIndex = pRec->typeIndex + typeLength;
+
+  if (idLength > 0)
+  {
+    memcpy(pRec->pData + pRec->idIndex, pId, idLength);
+    pRec->payloadIndex = pRec->idIndex + idLength;
+  }
+  else
+  {
+    pRec->payloadIndex = pRec->idIndex;
+  }
+  memcpy(pRec->pData + pRec->payloadIndex, pPayload, payloadLength);
+  pRec->payloadLen = payloadLength;
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_updateFromRawEx(pn532_ndef_record_t ndefRecord,
+  uint8_t *pBuffer, uint32_t length,
+  pn532_ndef_create_buffer_mode_t bufferMode)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  uint32_t totalLen = 2;
+  uint32_t idLenIndex;
+  uint32_t typeIndex;
+  uint32_t idIndex;
+  uint32_t payloadIndex;
+  uint32_t payloadLen;
+
+  if ((pRec == NULL) || (pBuffer == NULL) || (bufferMode
+    < NDEF_CREATE_BUFFER_MODE_DUPLICATE) || (bufferMode
+    > NDEF_CREATE_BUFFER_MODE_DELEGATE))
+  {
+    return PN532_ERROR_INVALID_PARAM;
+  }
+  /************Parse input data ********************/
+  /* Header + Type */
+  totalLen = 2;
+  if (length < totalLen)
+  {
+    return PN532_ERROR_INVALID_PARAM;
+  }
+
+  /* Payload Len */
+  if (pBuffer[NDEF_HEADER_INDEX] & NDEF_HEADER_SR_MASK)
+  {
+    if (totalLen + 1 > length)
+    {
+      return PN532_ERROR_INVALID_PARAM;
+    }
+    payloadLen = pBuffer[NDEF_PAYLOAD_LENGTH_INDEX];
+    totalLen += 1;
+  }
+  else
+  {
+    if (totalLen + 4 > length)
+    {
+      return PN532_ERROR_INVALID_PARAM;
+    }
+    payloadLen = ((pBuffer[NDEF_PAYLOAD_LENGTH_INDEX] << 24) & 0xFF000000)
+      | ((pBuffer[NDEF_PAYLOAD_LENGTH_INDEX + 1] << 16) & 0x00FF0000)
+      | ((pBuffer[NDEF_PAYLOAD_LENGTH_INDEX + 2] << 8) & 0x0000FF00)
+      | (pBuffer[NDEF_PAYLOAD_LENGTH_INDEX + 3] & 0x000000FF);
+    totalLen += 4;
+  }
+  idLenIndex = totalLen;
+
+  /* ID Len */
+  if (pBuffer[NDEF_HEADER_INDEX] & NDEF_HEADER_IL_MASK)
+  {
+    if (totalLen + 1 > length)
+    {
+      return PN532_ERROR_INVALID_PARAM;
+    }
+    totalLen++;
+  }
+  typeIndex = totalLen;
+
+  /* Type */
+  if (totalLen + pBuffer[NDEF_TYPE_LENGTH_INDEX] > length)
+  {
+    return PN532_ERROR_INVALID_PARAM;
+  }
+  totalLen += pBuffer[NDEF_TYPE_LENGTH_INDEX];
+  idIndex = totalLen;
+
+  /* ID */
+  if (pBuffer[NDEF_HEADER_INDEX] & NDEF_HEADER_IL_MASK)
+  {
+    if (totalLen + pBuffer[idLenIndex] > length)
+    {
+      return PN532_ERROR_INVALID_PARAM;
+    }
+    totalLen += pBuffer[idLenIndex];
+  }
+  payloadIndex = totalLen;
+
+  /* Payload */
+  if (totalLen + payloadLen > length)
+  {
+    return PN532_ERROR_INVALID_PARAM;
+  }
+  totalLen += payloadLen;
+
+  /************Assign to target record ********************/
+  /* To keep memory peek low, we pn532_mem_free current data before allocating new */
+  if ((pRec->pData != NULL) && (pRec->bufferAllocated))
+  {
+    pn532_mem_free(pRec->pData);
+    pRec->pData = NULL;
+    pRec->bufferAllocated = 0;
+  }
+  switch (bufferMode)
+  {
+    case NDEF_CREATE_BUFFER_MODE_DUPLICATE:
+      pRec->pData = (uint8_t*) pn532_mem_alloc(length);
+      if (pRec->pData == NULL)
+      {
+        pRec->bufferAllocated = 0;
+        pRec->length = 0;
+        pRec->idLenIndex = 0;
+        pRec->typeIndex = 0;
+        pRec->idIndex = 0;
+        pRec->payloadIndex = 0;
+        pRec->payloadLen = 0;
+        return PN532_ERROR_MEM_INSUFFICIENT;
+      }
+      pRec->bufferAllocated = 1;
+      memcpy(pRec->pData, pBuffer, length);
+
+      pRec->length = totalLen;
+      pRec->idLenIndex = idLenIndex;
+      pRec->typeIndex = typeIndex;
+      pRec->idIndex = idIndex;
+      pRec->payloadIndex = payloadIndex;
+      pRec->payloadLen = payloadLen;
+
+      break;
+
+    case NDEF_CREATE_BUFFER_MODE_REFERENCE:
+      pRec->pData = pBuffer;
+      pRec->bufferAllocated = 0;
+
+      pRec->length = totalLen;
+      pRec->idLenIndex = idLenIndex;
+      pRec->typeIndex = typeIndex;
+      pRec->idIndex = idIndex;
+      pRec->payloadIndex = payloadIndex;
+      pRec->payloadLen = payloadLen;
+      break;
+
+    case NDEF_CREATE_BUFFER_MODE_DELEGATE:
+      pRec->pData = pBuffer;
+      pRec->bufferAllocated = 1;
+
+      pRec->length = totalLen;
+      pRec->idLenIndex = idLenIndex;
+      pRec->typeIndex = typeIndex;
+      pRec->idIndex = idIndex;
+      pRec->payloadIndex = payloadIndex;
+      pRec->payloadLen = payloadLen;
+      break;
+
+    default:
+      return PN532_ERROR_INVALID_PARAM;
+  }
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_updateFromRaw(pn532_ndef_record_t ndefRecord,
+  uint8_t *pBuffer, uint32_t length)
+{
+  return pn532_ndef_updateFromRawEx(ndefRecord, pBuffer, length,
+    NDEF_CREATE_BUFFER_MODE_DUPLICATE);
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_updateFromStream(pn532_ndef_record_t ndefRecord,
+  pn532_ndef_fetch_data_fn fnFetch, void* pUserData)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  uint8_t header;
+  uint8_t typeLen = 0;
+  uint8_t payloadLen = 0;
+  uint8_t idLen = 0;
+
+  uint32_t totalLen;
+  uint32_t typeIndex;
+  uint32_t idIndex;
+  uint32_t payloadIndex;
+
+  pn532_error_t err;
+
+  if ((pRec == NULL) || (fnFetch == NULL))
+  {
+    return PN532_ERROR_INVALID_PARAM;
+  }
+  if ((pRec->pData != NULL) && (pRec->bufferAllocated))
+  {
+    pn532_mem_free(pRec->pData);
+    pRec->pData = NULL;
+    pRec->bufferAllocated = 0;
+  }
+
+  err = fnFetch(pUserData, &header, sizeof(header));
+  if (err != PN532_ERROR_NONE)
+  {
+    return err;
+  }
+  err = fnFetch(pUserData, &typeLen, sizeof(typeLen));
+  if (err != PN532_ERROR_NONE)
+  {
+    return err;
+  }
+  if (header & NDEF_HEADER_SR_MASK)
+  {
+    //	typedef pn532_error_t (*pn532_ndef_fetch_data_fn)(void* pUserData,
+    //	    uint8_t *out_buff, uint32_t length);
+    err = fnFetch(pUserData, &payloadLen, 1);
+    totalLen = 3;
+  }
+  else
+  {
+    err = fnFetch(pUserData, &payloadLen, 4);
+    totalLen = 6;
+  }
+  if (err != PN532_ERROR_NONE)
+  {
+    return err;
+  }
+
+  if (header & NDEF_HEADER_IL_MASK)
+  {
+    err = fnFetch(pUserData, &idLen, sizeof(idLen));
+  }
+  else
+  {
+    idLen = 0;
+  }
+  totalLen++;
+  typeIndex = totalLen;
+  totalLen += typeLen;
+  idIndex = totalLen;
+  totalLen += idLen;
+  payloadIndex = totalLen;
+  totalLen += payloadLen;
+
+  /* To keep memory peek low, we pn532_mem_free current data before allocating new data */
+  if ((pRec->pData != NULL) && (pRec->bufferAllocated))
+  {
+    pn532_mem_free(pRec->pData);
+    pRec->pData = NULL;
+    pRec->bufferAllocated = 0;
+  }
+
+  pRec->pData = (uint8_t*) pn532_mem_alloc(totalLen);
+  if (pRec->pData != NULL)
+  {
+    pRec->bufferAllocated = 1;
+    pRec->length = totalLen;
+
+    pRec->pData[NDEF_HEADER_INDEX] = header;
+    pRec->pData[NDEF_TYPE_LENGTH_INDEX] = typeLen;
+
+    if (header & NDEF_HEADER_SR_MASK)
+    {
+      pRec->pData[NDEF_PAYLOAD_LENGTH_INDEX] = payloadLen;
+      pRec->idLenIndex = NDEF_PAYLOAD_LENGTH_INDEX + 1;
+    }
+    else
+    {
+      pRec->pData[NDEF_PAYLOAD_LENGTH_INDEX] = (uint8_t)(
+        (payloadLen >> 24) & 0xFF);
+      pRec->pData[NDEF_PAYLOAD_LENGTH_INDEX + 1] = (uint8_t)(
+        (payloadLen >> 16) & 0xFF);
+      pRec->pData[NDEF_PAYLOAD_LENGTH_INDEX + 2] = (uint8_t)(
+        (payloadLen >> 8) & 0xFF);
+      pRec->pData[NDEF_PAYLOAD_LENGTH_INDEX + 3] = (uint8_t)(
+        payloadLen & 0xFF);
+      pRec->idLenIndex = NDEF_PAYLOAD_LENGTH_INDEX + 4;
+    }
+    pRec->pData[pRec->idLenIndex] = idLen;
+    pRec->typeIndex = typeIndex;
+    pRec->idIndex = idIndex;
+    pRec->payloadIndex = payloadIndex;
+    pRec->payloadLen = payloadLen;
+
+    err = fnFetch(pUserData, pRec->pData + typeIndex,
+      typeLen + idLen + payloadLen);
+    if (err != PN532_ERROR_NONE)
+    {
+      pn532_mem_free(pRec->pData);
+      pRec->pData = NULL;
+      pRec->bufferAllocated = 0;
+      pRec->length = 0;
+      pRec->idLenIndex = 0;
+      pRec->typeIndex = 0;
+      pRec->idIndex = 0;
+      pRec->payloadIndex = 0;
+      pRec->payloadLen = 0;
+      return err;
+    }
+    return PN532_ERROR_NONE;
+  }
+  else
+  {
+    pRec->bufferAllocated = 0;
+    pRec->length = 0;
+    pRec->idLenIndex = 0;
+    pRec->typeIndex = 0;
+    pRec->idIndex = 0;
+    pRec->payloadIndex = 0;
+    pRec->payloadLen = 0;
+    return PN532_ERROR_MEM_INSUFFICIENT;
+  }
+}
+
+/**************************************************************************/
+/*                 Getter and Setter functions                            */
+/**************************************************************************/
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+uint8_t pn532_ndef_getMB(pn532_ndef_record_t ndefRecord)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  if ((pRec == NULL) || (pRec->pData == NULL))
+  {
+    return 0;
+  }
+  if ((pRec->pData[NDEF_HEADER_INDEX] & NDEF_HEADER_MB_MASK)
+    == NDEF_HEADER_MB_MASK)
+  {
+    return 1;
+  }
+  else
+  {
+    return 0;
+  }
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_setMB(pn532_ndef_record_t ndefRecord)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  if ((pRec == NULL) || (pRec->pData == NULL))
+  {
+    return PN532_ERROR_INVALID_PARAM;
+  }
+  pRec->pData[NDEF_HEADER_INDEX] |= NDEF_HEADER_MB_MASK;
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_clearMB(pn532_ndef_record_t ndefRecord)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  if ((pRec == NULL) || (pRec->pData == NULL))
+  {
+    return PN532_ERROR_INVALID_PARAM;
+  }
+  pRec->pData[NDEF_HEADER_INDEX] &= (~NDEF_HEADER_MB_MASK);
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+uint8_t pn532_ndef_getME(pn532_ndef_record_t ndefRecord)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  if ((pRec == NULL) || (pRec->pData == NULL))
+  {
+    return 0;
+  }
+  if ((pRec->pData[NDEF_HEADER_INDEX] & NDEF_HEADER_ME_MASK)
+    == NDEF_HEADER_ME_MASK)
+  {
+    return 1;
+  }
+  else
+  {
+    return 0;
+  }
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_setME(pn532_ndef_record_t ndefRecord)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  if ((pRec == NULL) || (pRec->pData == NULL))
+  {
+    return PN532_ERROR_INVALID_PARAM;
+  }
+  pRec->pData[NDEF_HEADER_INDEX] |= NDEF_HEADER_ME_MASK;
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_clearME(pn532_ndef_record_t ndefRecord)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  if ((pRec == NULL) || (pRec->pData == NULL))
+  {
+    return PN532_ERROR_INVALID_PARAM;
+  }
+  pRec->pData[NDEF_HEADER_INDEX] &= (~NDEF_HEADER_ME_MASK);
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+uint8_t pn532_ndef_getTNF(pn532_ndef_record_t ndefRecord)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  if ((pRec == NULL) || (pRec->pData == NULL))
+  {
+    return 0;
+  }
+  return NDEF_EXTRACT_TNF(pRec->pData[NDEF_HEADER_INDEX]);
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+const uint8_t* pn532_ndef_getType(pn532_ndef_record_t ndefRecord)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  if ((pRec == NULL) || (pRec->pData == NULL))
+  {
+    return NULL;
+  }
+  return pRec->pData + pRec->typeIndex;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+uint32_t pn532_ndef_getTypeLength(pn532_ndef_record_t ndefRecord)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  if ((pRec == NULL) || (pRec->pData == NULL))
+  {
+    return 0;
+  }
+  return pRec->pData[NDEF_TYPE_LENGTH_INDEX];
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+const uint8_t* pn532_ndef_getId(pn532_ndef_record_t ndefRecord)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  if ((pRec == NULL) || (pRec->pData == NULL))
+  {
+    return NULL;
+  }
+  if (pRec->pData[NDEF_HEADER_INDEX] & NDEF_HEADER_IL_MASK)
+  {
+    return pRec->pData + pRec->idIndex;
+  }
+  else
+  {
+    return NULL;
+  }
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+uint32_t pn532_ndef_getIdLength(pn532_ndef_record_t ndefRecord)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  if ((pRec == NULL) || (pRec->pData == NULL))
+  {
+    return 0;
+  }
+  if (pRec->pData[NDEF_HEADER_INDEX] & NDEF_HEADER_IL_MASK)
+  {
+    return pRec->pData[pRec->idLenIndex];
+  }
+  else
+  {
+    return 0;
+  }
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+const uint8_t* pn532_ndef_getPayload(pn532_ndef_record_t ndefRecord)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  if ((pRec == NULL) || (pRec->pData == NULL))
+  {
+    return NULL;
+  }
+  return pRec->pData + pRec->payloadIndex;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+uint32_t pn532_ndef_getPayloadLength(pn532_ndef_record_t ndefRecord)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  if ((pRec == NULL) || (pRec->pData == NULL))
+  {
+    return 0;
+  }
+  return pRec->payloadLen;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+const uint8_t* pn532_ndef_getAll(pn532_ndef_record_t ndefRecord)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  if ((pRec == NULL) || (pRec->pData == NULL))
+  {
+    return NULL;
+  }
+  return pRec->pData;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+uint32_t pn532_ndef_getLength(pn532_ndef_record_t ndefRecord)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  if ((pRec == NULL) || (pRec->pData == NULL))
+  {
+    return 0;
+  }
+  return pRec->length;
+}
+
+/************************************************************************/
+/*                      NDEF Message functions                          */
+/************************************************************************/
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_ndef_record_t pn532_ndef_getNextRecord(pn532_ndef_record_t ndefRecord)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  if (pRec == NULL)
+  {
+    return NULL;
+  }
+  return (pn532_ndef_record_t) pRec->pNext;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_linkNextRecord(pn532_ndef_record_t ndefRecord,
+  pn532_ndef_record_t nextRecord)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefRecord;
+  if (pRec == NULL)
+  {
+    return PN532_ERROR_INVALID_PARAM;
+  }
+  pRec->pNext = (NdefRecord_t*) nextRecord;
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_appendRecord(pn532_ndef_message_t ndefMesg,
+  pn532_ndef_record_t ndefRecord)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefMesg;
+  if (pRec == NULL)
+  {
+    return PN532_ERROR_INVALID_PARAM;
+  }
+  while (pRec->pNext != NULL)
+  {
+    pRec = pRec->pNext;
+  }
+  pRec->pNext = (NdefRecord_t*) ndefRecord;
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_ndef_record_t pn532_ndef_getFirstRecord(pn532_ndef_message_t ndefMesg)
+{
+  return (pn532_ndef_record_t) ndefMesg;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_ndef_record_t pn532_ndef_getRecord(pn532_ndef_message_t ndefMesg,
+  uint32_t index)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefMesg;
+  uint32_t i;
+  if (pRec == NULL)
+  {
+    return NULL;
+  }
+
+  for (i = 0; i < index; i++)
+  {
+    pRec = pRec->pNext;
+    if (pRec == NULL)
+    {
+      return NULL;
+    }
+  }
+  return pRec;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+uint32_t pn532_ndef_getNumberOfRecords(pn532_ndef_message_t ndefMesg)
+{
+  NdefRecord_t *pRec = (NdefRecord_t*) ndefMesg;
+  uint32_t c = 0;
+  if (pRec == NULL)
+  {
+    return 0;
+  }
+  c = 1;
+  while (pRec->pNext != NULL)
+  {
+    pRec = pRec->pNext;
+    c++;
+  }
+  return c;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_createTextPayload(char *isoCode, char *text,
+    char *payloadBuffer, int32_t *bufferLen)
+{
+  int32_t i = 0;
+  *bufferLen = 0;
+
+  if ((isoCode == NULL) || (text == NULL) || (payloadBuffer == NULL))
+  {
+    return PN532_ERROR_INVALID_PARAM;
+  }
+
+  if (strlen(isoCode) > 5)
+  {
+    /* ISO code is maximum 5 chars, ex. "en-GB" */
+    return PN532_ERROR_INVALID_PARAM;
+  }
+
+  if (strlen(text) > 256)
+  {
+    /* ToDo: Throw a more precise error message? */
+    return PN532_ERROR_INVALID_PARAM;
+  }
+
+  /* Insert the status byte (assumes UTF-8 encoding) */
+  i = strlen(isoCode);
+  payloadBuffer[0] = i;   /* ISO code length, 0..5 */
+  *bufferLen += 1;
+
+  /* Copy isoCode into the payload buffer */
+  memcpy(payloadBuffer+1, isoCode, i);
+  *bufferLen += i;
+
+  /* Copy text in the payload buffer */
+  memcpy(payloadBuffer+i+1, text, strlen(text));
+  *bufferLen += strlen(text);
+
+  return PN532_ERROR_NONE;
+}
+
+//#endif  // #ifdef CFG_PN532
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_ndef.h b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_ndef.h
new file mode 100644
index 0000000000000000000000000000000000000000..2f19b29bcefbfad0fc480713c079106e026f6a29
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_ndef.h
@@ -0,0 +1,806 @@
+/**************************************************************************/
+/*!
+    @file pn532_ndef.h
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013 Adafruit Industries (www.adafruit.com)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __PN532_NDEF_H__
+#define __PN532_NDEF_H__
+
+#include "projectconfig.h"
+#include "../pn532.h"
+
+/**************************************************************************/
+/*!
+    Indicates no type, id, or payload is associated with this NDEF Record.
+
+    Type, id and payload fields must all be empty to be a valid
+    NDEF_TNF_EMPTY record.
+*/
+/**************************************************************************/
+#define NDEF_TNF_EMPTY                (0x00)
+
+/**************************************************************************/
+/*!
+    Indicates the type field uses the RTD type name format.
+
+    Use this TNF with RTD types such as NDEF_RTD_TEXT, NDEF_RTD_URI.
+*/
+/**************************************************************************/
+#define NDEF_TNF_WELL_KNOWN            (0x01)
+
+/**************************************************************************/
+/*!
+    Indicates the type field contains a value that follows the media-type
+    BNF construct defined by RFC 2046.
+*/
+/**************************************************************************/
+#define NDEF_TNF_MIME_MEDIA            (0x02)
+
+/**************************************************************************/
+/*!
+    Indicates the type field contains a value that follows the absolute-URI
+    BNF construct defined by RFC 3986.
+*/
+/**************************************************************************/
+#define NDEF_TNF_ABSOLUTE_URI          (0x03)
+
+/**************************************************************************/
+/*!
+    Indicates the type field contains a value that follows the RTD external
+    name specification.
+
+    Note this TNF should not be used with NDEF_RTD_TEXT or NDEF_RTD_URI
+    constants.  Those are well known RTD constants, not external RTD
+    constants.
+*/
+/**************************************************************************/
+#define NDEF_TNF_EXTERNAL_TYPE         (0x04)
+
+/**************************************************************************/
+/*!
+    Indicates the payload type is unknown.
+
+    This is similar to the "application/octet-stream" MIME type. The
+    payload type is not explicitly encoded within the NDEF Message.
+
+    The type field must be empty to be a valid NDEF_TNF_UNKNOWN record.
+*/
+/**************************************************************************/
+#define NDEF_TNF_UNKNOWN               (0x05)
+
+/**************************************************************************/
+/*!
+    Indicates the payload is an intermediate or final chunk of a chunked
+    NDEF Record.
+
+    The payload type is specified in the first chunk, and subsequent chunks
+    must use NDEF_TNF_UNCHANGED with an empty type field.
+    NDEF_TNF_UNCHANGED must not be used in any other situation.
+*/
+/**************************************************************************/
+#define NDEF_TNF_UNCHANGED             (0x06)
+
+/**************************************************************************/
+/*!
+    Reserved TNF type.
+
+    The NFC Forum NDEF Specification v1.0 suggests for NDEF parsers to
+    treat this value like NDEF_TNF_UNKNOWN.
+
+    @hide
+*/
+/**************************************************************************/
+#define NDEF_TNF_RESERVED              (0x07)
+
+/**************************************************************************/
+/*!
+    RTD Text type. For use with NDEF_TNF_WELL_KNOWN.
+*/
+/**************************************************************************/
+#define NDEF_RTD_TEXT                  ("T")
+
+/**************************************************************************/
+/*!
+    RTD URI type. For use with NDEF_TNF_WELL_KNOWN.
+*/
+/**************************************************************************/
+#define NDEF_RTD_URI                   ("U")
+
+/**************************************************************************/
+/*!
+    RTD Smart Poster type. For use with NDEF_TNF_WELL_KNOWN.
+*/
+/**************************************************************************/
+#define NDEF_RTD_SMART_POSTER          ("Sp")
+
+/**************************************************************************/
+/*!
+    RTD Alternative Carrier type. For use with NDEF_TNF_WELL_KNOWN.
+*/
+/**************************************************************************/
+#define NDEF_RTD_ALTERNATIVE_CARRIER   ("ac")
+
+/**************************************************************************/
+/*!
+    RTD Handover Carrier type. For use with NDEF_TNF_WELL_KNOWN.
+*/
+/**************************************************************************/
+#define NDEF_RTD_HANDOVER_CARRIER      ("Hc")
+
+/**************************************************************************/
+/*!
+    RTD Handover Request type. For use with NDEF_TNF_WELL_KNOWN.
+*/
+/**************************************************************************/
+#define NDEF_RTD_HANDOVER_REQUEST      ("Hr")
+
+/**************************************************************************/
+/*!
+    RTD Handover Select type. For use with NDEF_TNF_WELL_KNOWN.
+*/
+/**************************************************************************/
+#define NDEF_RTD_HANDOVER_SELECT       ("Hs")
+
+/**************************************************************************/
+/*!
+    RTD Android app type. For use with TNF_EXTERNAL.
+
+    The payload of a record with type NDEF_RTD_ANDROID_APP should be the
+    package name identifying an application. Multiple NDEF_RTD_ANDROID_APP
+    records may be included in a single {@link NdefMessage}.
+
+    Use {@link #createApplicationRecord(String)} to create
+    NDEF_RTD_ANDROID_APP records.
+*/
+/**************************************************************************/
+#define NDEF_RTD_ANDROID_APP           ("android.com:pkg")
+
+/**************************************************************************/
+/*!
+    URI Idenfifier Codes used by URI Records with Well-Known Records (TNF
+    Record type 0x01).  These code are inserted before the URI payload to
+    help keep the records as short as possible.
+*/
+/**************************************************************************/
+typedef enum
+{
+  NDEF_WNR_URIPREFIX_NONE           = 0x00,
+  NDEF_WNR_URIPREFIX_HTTP_WWWDOT    = 0x01,
+  NDEF_WNR_URIPREFIX_HTTPS_WWWDOT   = 0x02,
+  NDEF_WNR_URIPREFIX_HTTP           = 0x03,
+  NDEF_WNR_URIPREFIX_HTTPS          = 0x04,
+  NDEF_WNR_URIPREFIX_TEL            = 0x05,
+  NDEF_WNR_URIPREFIX_MAILTO         = 0x06,
+  NDEF_WNR_URIPREFIX_FTP_ANONAT     = 0x07,
+  NDEF_WNR_URIPREFIX_FTP_FTPDOT     = 0x08,
+  NDEF_WNR_URIPREFIX_FTPS           = 0x09,
+  NDEF_WNR_URIPREFIX_SFTP           = 0x0A,
+  NDEF_WNR_URIPREFIX_SMB            = 0x0B,
+  NDEF_WNR_URIPREFIX_NFS            = 0x0C,
+  NDEF_WNR_URIPREFIX_FTP            = 0x0D,
+  NDEF_WNR_URIPREFIX_DAV            = 0x0E,
+  NDEF_WNR_URIPREFIX_NEWS           = 0x0F,
+  NDEF_WNR_URIPREFIX_TELNET         = 0x10,
+  NDEF_WNR_URIPREFIX_IMAP           = 0x11,
+  NDEF_WNR_URIPREFIX_RTSP           = 0x12,
+  NDEF_WNR_URIPREFIX_URN            = 0x13,
+  NDEF_WNR_URIPREFIX_POP            = 0x14,
+  NDEF_WNR_URIPREFIX_SIP            = 0x15,
+  NDEF_WNR_URIPREFIX_SIPS           = 0x16,
+  NDEF_WNR_URIPREFIX_TFTP           = 0x17,
+  NDEF_WNR_URIPREFIX_BTSPP          = 0x18,
+  NDEF_WNR_URIPREFIX_BTL2CAP        = 0x19,
+  NDEF_WNR_URIPREFIX_BTGOEP         = 0x1A,
+  NDEF_WNR_URIPREFIX_TCPOBEX        = 0x1B,
+  NDEF_WNR_URIPREFIX_IRDAOBEX       = 0x1C,
+  NDEF_WNR_URIPREFIX_FILE           = 0x1D,
+  NDEF_WNR_URIPREFIX_URN_EPC_ID     = 0x1E,
+  NDEF_WNR_URIPREFIX_URN_EPC_TAG    = 0x1F,
+  NDEF_WNR_URIPREFIX_URN_EPC_PAT    = 0x20,
+  NDEF_WNR_URIPREFIX_URN_EPC_RAW    = 0x21,
+  NDEF_WNR_URIPREFIX_URN_EPC        = 0x22,
+  NDEF_WNR_URIPREFIX_URN_NFC        = 0x23
+} pn532_ndef_wnr_urirec_ident_t;
+
+/**************************************************************************/
+/*!
+    PN532 buffer modes (controls the way dynamic memory is managed)
+*/
+/**************************************************************************/
+typedef enum pn532_ndef_create_buffer_mode_en
+{
+  /** pn532_ndef_create allocate new buffer to store NDEF record and manage
+   * it, after calling pn532_ndef_create function, upper layer can change
+   * buffer content and free it after using.
+   * This is the safest mode, but require more memory*/
+  NDEF_CREATE_BUFFER_MODE_DUPLICATE = 0,
+
+  /** pn532_ndef_create refer to input buffer, upper layer should not modify
+   * buffer content and has to free it after using buffer */
+  NDEF_CREATE_BUFFER_MODE_REFERENCE,
+
+  /** pn532_ndef_create refer and manage input buffer */
+  NDEF_CREATE_BUFFER_MODE_DELEGATE
+} pn532_ndef_create_buffer_mode_t;
+
+/**************************************************************************/
+/*!
+    NDEF Structures use to parse NDEF message reading from media
+ */
+/**************************************************************************/
+typedef void* pn532_ndef_record_t;
+
+typedef pn532_ndef_record_t pn532_ndef_message_t;
+
+/**************************************************************************/
+/*!
+    @brief Call back to fetch data for NDEF parsing
+
+    @see pn532_ndef_parser_stream
+ */
+/**************************************************************************/
+typedef pn532_error_t (*pn532_ndef_fetch_data_fn)(void* pUserData,
+  uint8_t *out_buff, uint32_t length);
+
+/**************************************************************************/
+/*!
+    @brief          Creates an empty NDEF record
+
+    @param[out]     pNdefRecord     pointer to the new record
+
+    @return         pn532_error_t, possible error messages are:
+
+                    PN532_ERROR_INVALID_PARAM
+                    PN532_ERROR_MEM_INSUFFICIENT
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_create_empty(pn532_ndef_record_t *pNdefRecord);
+
+/**************************************************************************/
+/*!
+    @brief Create an NDEF record from supplied details
+
+    @param[out]     pNdefRecord     pointer to the new record
+    @param[in]      tnf             TNF ID
+    @param[in]      pType           record type
+    @param[in]      typeLength      length of pType
+    @param[in,opt]  pId             record ID
+    @param[in]      idLength        length of pId
+    @param[in]      pPayload        record payload
+    @param[in]      payloadLength   length of pPayload
+
+    @return         pn532_error_t, possible error messages are:
+
+                    PN532_ERROR_INVALID_PARAM
+                    PN532_ERROR_MEM_INSUFFICIENT
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_createFromValue(pn532_ndef_record_t *pNdefRecord,
+  uint8_t tnf, uint8_t *pType, uint8_t typeLength, uint8_t *pId,
+  uint8_t idLength, uint8_t *pPayload, uint32_t payloadLength);
+
+/**************************************************************************/
+/*!
+    @brief  Creates an NDEF record from raw buffer data
+
+    @param[out]     pNdefRecord     pointer to the new record
+    @param[in]      pBuffer         buffer containing the raw record data
+    @param[in]      length          length of the raw NDEF record data
+    @param[in]      bufferMode      buffer management mode
+
+    @return         pn532_error_t, possible error messages are:
+
+                    PN532_ERROR_INVALID_PARAM
+                    PN532_ERROR_MEM_INSUFFICIENT
+
+    @see pn532_ndef_create_buffer_mode_t
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_createFromRawEx(pn532_ndef_record_t *pNdefRecord,
+  uint8_t *pBuffer, uint32_t length,
+  pn532_ndef_create_buffer_mode_t bufferMode);
+
+/**************************************************************************/
+/*!
+    @brief Creates an NDEF record from raw buffer data using the default
+           buffer management mode (NDEF_CREATE_BUFFER_MODE_DUPLICATE)
+
+    @param[out]     pNdefRecord     pointer to the new record
+    @param[in]      pBuffer         buffer containing the raw record data
+    @param[in]      length          length of raw NDEF record data
+
+    @return         pn532_error_t, possible error messages are:
+
+                    PN532_ERROR_INVALID_PARAM
+                    PN532_ERROR_MEM_INSUFFICIENT
+
+    @see pn532_ndef_create_buffer_mode_t
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_createFromRaw(pn532_ndef_record_t *pNdefRecord,
+  uint8_t *pBuffer, uint32_t length);
+
+/**************************************************************************/
+/*!
+    @brief Creates an NDEF record from a stream (NDEF_CREATE_BUFFER_MODE_REFERENCE)
+
+    @param[out]     pNdefRecord     pointer to the new record
+    @param[in]      fnFetch         function to fetch data
+    @param[in]      pUserData       User data which will be passed to
+                                    the fnFetch callback
+
+    @return         pn532_error_t, possible error messages are:
+
+                    PN532_ERROR_INVALID_PARAM
+                    PN532_ERROR_MEM_INSUFFICIENT
+
+    @see pn532_ndef_create_buffer_mode_t
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_createFromStream(pn532_ndef_record_t *pNdefRecord,
+  pn532_ndef_fetch_data_fn fnFetch, void *pUserData);
+
+/**************************************************************************/
+/*!
+    @brief Destroys the record, freeing the memory
+
+    @param          ndefRec         NDEF record to destroy
+*/
+/**************************************************************************/
+void pn532_ndef_destroy(pn532_ndef_record_t ndefRecord);
+
+/**************************************************************************/
+/*!
+    @brief    Updates an NDEF record with new data/values
+
+    @note     Please note that this function frees allocated resources
+              before updating any values. If the function fails to allocate
+              memory for new record, previous values are discarded
+              and the record becomes empty.
+
+    @param[in,out]  ndefRecord      Ndef record to update
+    @param[in]      tnf             TNF ID
+    @param[in]      pType           record type
+    @param[in]      typeLength      length of pType
+    @param[in,opt]  pId             record Id
+    @param[in]      idLength        length of pId
+    @param[in]      pPayload        record payload
+    @param[in]      payloadLength   length of pPayload
+
+    @return         pn532_error_t, possible error messages are:
+
+                    PN532_ERROR_INVALID_PARAM
+                    PN532_ERROR_MEM_INSUFFICIENT
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_update(pn532_ndef_record_t ndefRecord, uint8_t tnf,
+  uint8_t *pType, uint8_t typeLength, uint8_t *pId, uint8_t idLength,
+  uint8_t *pPayload, uint32_t payloadLength);
+
+/**************************************************************************/
+/*!
+    @brief    Updates an NDEF record from a raw buffer
+
+    @note     Please note that this function frees allocated resources
+              before updating any values. If the function fails to allocate
+              memory for new record, previous values are discarded
+              and the record becomes empty.
+
+    @param[in,out]  ndefRecord      Ndef record to update
+    @param[in]      pBuffer         Buffer containing raw record data
+    @param[in]      length          length of data in buffer
+    @param[in]      bufferMode      buffer management mode
+
+    @return         pn532_error_t, possible error messages are:
+
+                    PN532_ERROR_INVALID_PARAM
+                    PN532_ERROR_MEM_INSUFFICIENT
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_updateFromRawEx(pn532_ndef_record_t ndefRecord,
+  uint8_t *pBuffer, uint32_t length,
+  pn532_ndef_create_buffer_mode_t bufferMode);
+
+/**************************************************************************/
+/*!
+    @brief    Parse an NDEF record from a buffer using the default buffer
+              management mode (NDEF_CREATE_BUFFER_MODE_DUPLICATE)
+
+    @note     Please note that this function frees allocated resources
+              before updating any values. If the function fails to allocate
+              memory for new record, previous values are discarded
+              and the record becomes empty.
+
+    @param[in,out]  ndefRecord      Ndef record to update
+    @param[in]      pBuffer         Buffer containing raw record data
+    @param[in]      length          length of data in buffer
+
+    @return         pn532_error_t, possible error messages are:
+
+                    PN532_ERROR_INVALID_PARAM
+                    PN532_ERROR_MEM_INSUFFICIENT
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_updateFromRaw(pn532_ndef_record_t ndefRecord,
+  uint8_t *pBuffer, uint32_t length);
+
+/**************************************************************************/
+/*!
+    @brief Updates an Ndef record from a runtime stream
+
+    @note     Please note that this function frees allocated resources
+              before updating any values. If the function fails to allocate
+              memory for new record, previous values are discarded
+              and the record becomes empty.
+
+    @param[in,out]  ndefRecord      Ndef record to store data
+    @param[in]      fnFetch         Function to get data on demand during the
+                                    parsing process
+    @param[in]      pUserData       User data which will passed to fnFetch
+                                    callback
+
+    @return         pn532_error_t, possible error messages are:
+
+                    PN532_ERROR_INVALID_PARAM
+                    PN532_ERROR_MEM_INSUFFICIENT
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_updateFromStream(pn532_ndef_record_t ndefRecord,
+  pn532_ndef_fetch_data_fn fnFetch, void* pUserData);
+
+/**************************************************************************/
+/*                 Getter and Setter functions                            */
+/**************************************************************************/
+
+/**************************************************************************/
+/*!
+    @brief Get MB (Message Begin) flag
+
+    @param[in]      ndefRecord      NDEF record to get MB from
+
+    @return         MB state (1 or 0)
+
+    @see pn532_ndef_setMB, pn532_ndef_clearMB
+*/
+/**************************************************************************/
+uint8_t pn532_ndef_getMB(pn532_ndef_record_t ndefRecord);
+
+/**************************************************************************/
+/*!
+    @brief  Set MB (Message Begin) flag
+
+    @param[in]      ndefRecord      Ndef record to set MB flag in
+
+    @return         pn532_error_t, possible error messages are:
+
+                    PN532_ERROR_INVALID_PARAM
+
+    @see pn532_ndef_getMB, pn532_ndef_clearMB
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_setMB(pn532_ndef_record_t ndefRecord);
+
+/**************************************************************************/
+/*!
+    @brief  Clear MB (Message Begin) flag
+
+    @param[in]      ndefRecord      Ndef record to clear MB flag in
+
+    @return         pn532_error_t, possible error messages are:
+
+                    PN532_ERROR_INVALID_PARAM
+
+    @see pn532_ndef_getMB, pn532_ndef_setMB
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_clearMB(pn532_ndef_record_t ndefRecord);
+
+/**************************************************************************/
+/*!
+    @brief  Gets the ME (Message End) flag
+
+    @param[in]      ndefRecord      NDEF record to get MB from
+
+    @return         ME flag
+
+    @see pn532_ndef_setME, pn532_ndef_clearME
+*/
+/**************************************************************************/
+uint8_t pn532_ndef_getME(pn532_ndef_record_t ndefRecord);
+
+/**************************************************************************/
+/*!
+    @brief Sets the ME (Message End) flag
+
+    @param[in]      ndefRecord      Ndef record to set ME flag in
+
+    @return         pn532_error_t, possible error messages are:
+
+                    PN532_ERROR_INVALID_PARAM
+
+    @see pn532_ndef_getME, pn532_ndef_clearME
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_setME(pn532_ndef_record_t ndefRecord);
+
+/**************************************************************************/
+/*!
+    @brief Clears the ME (Message End) flag
+
+    @param[in]      ndefRecord      Ndef record to clear ME flag in
+
+    @return         pn532_error_t, possible error messages are:
+
+                    PN532_ERROR_INVALID_PARAM
+
+    @see pn532_ndef_getME, pn532_ndef_setME
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_clearME(pn532_ndef_record_t ndefRecord);
+
+/**************************************************************************/
+/*!
+    @brief  Gets the TNF (Type Name Format)
+
+    @param[in]      ndefRecord      NDEF record to get TNF from
+
+    @return         The TNF value
+*/
+/**************************************************************************/
+uint8_t pn532_ndef_getTNF(pn532_ndef_record_t ndefRecord);
+
+/**************************************************************************/
+/*!
+    @brief Gets the record type
+
+    @param[in]      ndefRecord      NDEF record to get Type from
+
+    @return         A constant pointer to Type or NULL if no valid Type
+                    value was found
+
+    @see pn532_ndef_getTypeLength
+*/
+/**************************************************************************/
+const uint8_t* pn532_ndef_getType(pn532_ndef_record_t ndefRecord);
+
+/**************************************************************************/
+/*!
+    @brief  Gets the type length
+
+    @param[in]      ndefRecord      NDEF record to get Type length from
+
+    @return         type length or 0 if no valid type value
+
+    @see pn532_ndef_getType
+*/
+/**************************************************************************/
+uint32_t pn532_ndef_getTypeLength(pn532_ndef_record_t ndefRecord);
+
+/**************************************************************************/
+/*!
+    @brief  Gets the record's ID
+
+    @param[in]      ndefRecord      NDEF record to get ID from
+
+    @return         A constant pointer to ID or NULL if the input record
+                    has no ID
+
+    @see pn532_ndef_getIdLength
+*/
+/**************************************************************************/
+const uint8_t* pn532_ndef_getId(pn532_ndef_record_t ndefRecord);
+
+/**
+ */
+/**************************************************************************/
+/*!
+    @brief Get the ID length
+
+    @param[in]        ndefRecord    NDEF record to get Id length from
+
+    @return           ID length or 0 if the input record has no ID
+
+    @see pn532_ndef_getId
+*/
+/**************************************************************************/
+uint32_t pn532_ndef_getIdLength(pn532_ndef_record_t ndefRecord);
+
+/**************************************************************************/
+/*!
+    @brief Get the record payload
+
+    @param[in]        ndefRecord    NDEF record to get payload from
+
+    @return           A constant pointer to payload or NULL if the input
+                      record has no valid payload.
+
+    @see pn532_ndef_getPayloadLength
+*/
+/**************************************************************************/
+const uint8_t* pn532_ndef_getPayload(pn532_ndef_record_t ndefRecord);
+
+/**************************************************************************/
+/*!
+    @brief Get the payload length
+
+    @param[in]        ndefRecord    NDEF record to get Payload length
+
+    @return           Payload length or 0 if the input record has no
+                      valid payload
+
+    @see pn532_ndef_getPayload
+*/
+/**************************************************************************/
+uint32_t pn532_ndef_getPayloadLength(pn532_ndef_record_t ndefRecord);
+
+/**************************************************************************/
+/*!
+    @brief Get the entire NDEF record
+
+    @param[in]      ndefRecord      NDEF record
+
+    @return         constant pointer to the record data
+*/
+/**************************************************************************/
+const uint8_t* pn532_ndef_getAll(pn532_ndef_record_t ndefRecord);
+
+/**************************************************************************/
+/*!
+    @brief  Get length of entire NDEF record
+
+    @param[in]      ndefRecord      NDEF record to get length
+
+    @return         length of entire NDEF record
+*/
+/**************************************************************************/
+uint32_t pn532_ndef_getLength(pn532_ndef_record_t ndefRecord);
+
+/************************************************************************/
+/*                      NDEF Message functions                          */
+/************************************************************************/
+
+/**************************************************************************/
+/*!
+    @brief Gets the next NDEF record in the NDEF message
+
+    @param[in]      ndefRecord      Current NDEF record
+
+    @return         The next NDEF record, or NULL if no record is present
+
+    @see pn532_ndef_linkNextRecord
+*/
+/**************************************************************************/
+pn532_ndef_record_t pn532_ndef_getNextRecord(pn532_ndef_record_t ndefRecord);
+
+/**************************************************************************/
+/*!
+    @brief  Appends an NDEF record after current NDEF record.<br/>
+            The current record should be the last record of the NDEF
+            message.
+
+    @param[in]      ndefRecord      Current NDEF record
+    @param[in]      nextRecord      Next NDEF record
+
+    @return         pn532_error_t, possible error messages are:
+
+                    PN532_ERROR_INVALID_PARAM
+
+    @see pn532_ndef_linkNextRecord
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_linkNextRecord(pn532_ndef_record_t ndefRecord,
+  pn532_ndef_record_t nextRecord);
+
+/**************************************************************************/
+/*!
+    @brief  Appends a new NDEF record to NDEF message.
+
+    @param[in]      ndefMesg        NDEF message
+    @param[in]      ndefRecord      new NDEF record, which will be appended
+                                    to ndefMesg
+
+    @return         pn532_error_t, possible error messages are:
+
+                    PN532_ERROR_INVALID_PARAM
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_appendRecord(pn532_ndef_message_t ndefMesg,
+  pn532_ndef_record_t ndefRecord);
+
+/**************************************************************************/
+/*!
+    @brief  Gest the first record of the NDEF message
+
+    @param[in]      ndefMesg        NDEF message
+
+    @return The first NDEF record or NULL if NDEF message is empty
+*/
+/**************************************************************************/
+pn532_ndef_record_t pn532_ndef_getFirstRecord(pn532_ndef_message_t ndefMesg);
+
+/**************************************************************************/
+/*!
+    @brief  Gets the record identified by index
+
+    @param[in]      ndefMesg        NDEF message
+    @param[in]      index           index of requested record (start by 0)
+
+    @return         NDEF record at index or NULL if NDEF message has less
+                    than (index+1) record
+
+    @see pn532_ndef_getNumberOfRecord
+*/
+/**************************************************************************/
+pn532_ndef_record_t pn532_ndef_getRecord(pn532_ndef_message_t ndefMesg,
+  uint32_t index);
+
+/**************************************************************************/
+/*!
+    @brief  Gets the number of records in the NDEF message
+
+    @param[in]      ndefMesg        NDEF message
+
+    @return         Number of NDEF record
+*/
+/**************************************************************************/
+uint32_t pn532_ndef_getNumberOfRecords(pn532_ndef_message_t ndefMesg);
+
+/**************************************************************************/
+/*!
+    @brief  Creates a payload for a Text 'Well-Known Record Type'
+
+            BYTE    Description
+            ----    -------------------------------------------------
+            0       Status byte
+                    Bit 7     - 0 - UTF-8 encoding
+                                1 - UTF-16 encoding
+                    Bit 6     - RFU (must be 0)
+                    BIT 5..0  - ISO/IANA code length
+            1       ISO/IANA language code (ex. 'en' or 'en-GB').
+                    Encoding is always in US-ASCII.
+            n+1     Actual text encoded in either UTF-8 or UTF-16
+
+    @param[in]      isoCode        char array containing the ISO/IANA code
+    @param[in]      text           char array containg the text payload
+    @param[in]      payloadBuffer  buffer to hold the text payload
+    @param[out]     bufferLen      length of the payloadBuffer
+
+    @return         pn532_error_t, possible error messages are:
+
+                    PN532_ERROR_INVALID_PARAM
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_createTextPayload(char *isoCode, char *text,
+    char *payloadBuffer, int32_t *bufferLen);
+
+#endif
+
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_ndef_cards.c b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_ndef_cards.c
new file mode 100644
index 0000000000000000000000000000000000000000..1bf2329bd0e63bfc2ffb622b9ebc5c176e4de6bf
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_ndef_cards.c
@@ -0,0 +1,1058 @@
+/**************************************************************************/
+/*!
+    @file pn532_ndef_cards.c
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013 Adafruit Industries (www.adafruit.com)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_PN532
+
+#include "pn532_ndef_cards.h"
+#include "pn532_mifare_classic.h"
+#include "pn532_ndef.h"
+#include "../mem_allocator/pn532_mem.h"
+
+/** used for padding purpose */
+#define TLV_TAG_NULL            (uint8_t)0x00
+
+/** the block contain a ndef message*/
+#define TLV_TAG_NDEF            (uint8_t)0x03
+
+/* proprieatary information*/
+#define TLV_TAG_PROPRIETARY     (uint8_t)0xFD
+
+/** last TLV block in the data area*/
+#define TLV_TAG_TERMINATOR      (uint8_t)0xFE
+
+/**Number of Short Sector of Mifare 1k/4k*/
+#define NR_SHORTSECTOR          (32)
+
+/**Number of Long Sector of Mifare 4K*/
+#define NR_LONGSECTOR           (8)
+
+/**Number of block of Short Sector, is first 16 sector of Mifare 1k/4k*/
+#define NR_BLOCK_OF_SHORTSECTOR (4)
+
+/** Number of block of Long Sector, is last 8 sector of Mifare 4K*/
+#define NR_BLOCK_OF_LONGSECTOR  (16)
+
+/** Total block of Mifare 1k/4k*/
+#define TOTAL_BLOCK_MF1K        (16*4)
+#define TOTAL_BLOCK_MF4K        (32*4+8*16)
+
+/** Get Sector trailer block based on Sector                          */
+#define BLOCK_NUMBER_OF_SECTOR_TRAILER(sector) (((sector)<NR_SHORTSECTOR)? \
+  ((sector)*NR_BLOCK_OF_SHORTSECTOR + NR_BLOCK_OF_SHORTSECTOR-1):\
+  (NR_SHORTSECTOR*NR_BLOCK_OF_SHORTSECTOR + (sector-NR_SHORTSECTOR)*NR_BLOCK_OF_LONGSECTOR + NR_BLOCK_OF_LONGSECTOR-1))
+
+/** Get Sector 1st block based on Sector number                         */
+#define BLOCK_NUMBER_OF_SECTOR_1ST_BLOCK(sector) (((sector)<NR_SHORTSECTOR)? \
+  ((sector)*NR_BLOCK_OF_SHORTSECTOR):\
+  (NR_SHORTSECTOR*NR_BLOCK_OF_SHORTSECTOR + (sector-NR_SHORTSECTOR)*NR_BLOCK_OF_LONGSECTOR))
+
+/**Sector number where MAD1 is located*/
+#define SECTOR_NUMBER_MAD1      (0)
+
+/**Sector number where MAD2 is located*/
+#define SECTOR_NUMBER_MAD2      (16)
+
+/*** Block number of Sector-trailer block of Mad1*/
+#define BLOCK_NUMBER_MAD1 BLOCK_NUMBER_OF_SECTOR_TRAILER(SECTOR_NUMBER_MAD1)
+
+/*** Block number of Sector-trailer block of Mad2*/
+#define BLOCK_NUMBER_MAD2 BLOCK_NUMBER_OF_SECTOR_TRAILER(SECTOR_NUMBER_MAD2)
+
+/**GPB byte of a sector trailer block buffer*/
+#define GPB(buff)               (uint8_t)(buff[9])
+
+/**Access Condition 1st byte*/
+#define ACB(buff)               (buff[6])
+
+#define NFC_AID_CLUSTER_CODE    (uint8_t)0xE1
+#define NFC_AID_APP_CODE        (uint8_t)0x03
+#define NFC_AID                 ((uint16_t)NFC_AID_CLUSTER_CODE<<8 | (uint16_t)NFC_AID_APP_CODE)
+
+/** MIFARE Classic and MIFARE Plus NFC Read/ Write Access Condition */
+#define NFC_GPB_RW_ACCESS_RIGHT_GRANTED                    (0x00)
+#define NFC_GPB_RW_ACCESS_RIGHT_PROHIBIT        (0x03)
+#define NFC_GPB_MINOR_VERSION                   (0x00)  // mapping version 1.0
+#define NFC_GPB_MAJOR_VERSION                   (0x01)
+
+#define CAPACITY_MF1K            (1*2*16 + 15*3*16)
+#define CAPACITY_MF1K_NDEF       (15*3*16)
+#define CAPACITY_MF4K            ((1*2*16 + 31*3*16)+(8*16*16))
+#define CAPACITY_MF4K_NDEF       ((31*3*16)+(8*15*16))
+
+#define REMAIN_SIZE_MF1K(sector) ((TOTAL_BLOCK_MF1K  - BLOCK_NUMBER_OF_SECTOR_1ST_BLOCK(sector))/4*3)*16
+#define REMAIN_SIZE_MF4K(sector) ((TOTAL_BLOCK_MF4K  - BLOCK_NUMBER_OF_SECTOR_1ST_BLOCK(sector))/4*3)*16
+
+#define CHECK_INVALID_POINTER(p) {if (!p) return PN532_ERROR_INVALID_PARAM;}
+#define CHECK_SUCCESS(status)    {if ((status) != PN532_ERROR_NONE) {return (status);}}
+#define CHECK_N_BREAK(status)    {if ((status) != PN532_ERROR_NONE) {break;}}
+
+#define CHECK_SUCCESS_FUNCTION(status,func)   {(status) = (func); CHECK_SUCCESS(status);}
+#define CHECK_N_BREAK_FUNCTION(status, func)  {(status) = (func); CHECK_N_BREAK(status);}
+
+#define MY_MIN(a,b) (a>b?b:a)
+
+/* Keys used with Mifare Classic Ndef tags */
+static const uint8_t KEY_DEFAULT_KEYAB[6]          = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+static const uint8_t KEY_MAD_PUBLIC_KEYA[6]        = {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5};
+static const uint8_t KEY_NFC_PUBLIC_KEYA[6]        = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7};
+
+uint8_t gGPB;
+uint16_t lengOfNdef = 0;
+
+/**************************************************************************/
+/*!
+    @note   Possible error messages are:
+
+            - PN532_ERROR_INVALID_PARAM
+            - PN532_ERROR_WRONGCARDTYPE     (Not Mifare Classic 1K/4K)
+            - PN532_ERROR_INVALID_TAG       (Not an NDEF formatted tag)
+            - PN532_ERROR_MEM_INSUFFICIENT
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_mfc_ndef_write(pTag_t pTag, pn532_ndef_record_t rec,
+  uint8_t sector)
+{
+  pn532_error_t errCode = PN532_ERROR_NONE;
+  uint8_t   blockBuffer[16];
+  uint16_t  ndefLength;
+  uint8_t   *recordBuffer;
+  uint8_t   blockBufferIdx;     /* Index while data is being processed in blockBuffer */
+  uint16_t  recordBufferIdx;    /* Index while data is being processed in recordBuffer */
+  uint8_t   processLength;      /* Number of byte to handle in recordBuffer */
+  uint8_t   processSector;
+  uint8_t   processBlockNr;
+  uint8_t   miscDataLen;
+  uint16_t  ndefTlvAdress;
+
+  CHECK_INVALID_POINTER(pTag);
+  CHECK_INVALID_POINTER(rec);
+
+  /* Make sure this is a supported tag (Mifare Classic 1K or 4K) */
+  if ((pTag->type != TAG_TYPE_MFC_1K) && (pTag->type != TAG_TYPE_MFC_4K))
+  {
+    return PN532_ERROR_WRONGCARDTYPE;
+  }
+
+  if (((pTag->type == TAG_TYPE_MFC_1K) && (sector > 15)) ||
+    ((pTag->type == TAG_TYPE_MFC_4K) && (sector > 39)))
+  {
+    return PN532_ERROR_INVALID_PARAM;
+  }
+
+  if ((sector == SECTOR_NUMBER_MAD1) || (sector == SECTOR_NUMBER_MAD2))
+  {
+    return PN532_ERROR_INVALID_PARAM;
+  }
+
+  /* Check if the tag is in NFC format, if not return an error */
+  errCode = pn532_ndef_mfc_get_tagType(pTag);
+
+  if (pTag->ndefType != NDEF_TAG_TYPE_NDEF_WRITE_ENABLE)
+  {
+    return PN532_ERROR_INVALID_TAG;
+  }
+
+  /* Scan Ndef Message TLV block */
+  errCode = pn532_ndef_mfc_scan_ndef_tlv(pTag, &ndefTlvAdress);
+  if(errCode != PN532_ERROR_NONE)
+  {
+    return errCode;
+  }
+
+  /* Get ndefLength */
+  ndefLength = pn532_ndef_getLength(rec);
+
+  miscDataLen = ndefTlvAdress % 16;
+  blockBufferIdx = (ndefTlvAdress % 16);
+
+  if (ndefLength >= 255)
+  {
+    miscDataLen += 4; //03 XX XX XX DATA FE
+  }
+  else
+  {
+    miscDataLen += 2; //03 XX DATA FE
+  }
+
+  switch (pTag->type)
+  {
+    case TAG_TYPE_MFC_1K:
+      if (REMAIN_SIZE_MF1K(sector) < miscDataLen + ndefLength)
+      {
+        return PN532_ERROR_MEM_INSUFFICIENT;
+      }
+
+      break;
+    case TAG_TYPE_MFC_4K:
+      if (REMAIN_SIZE_MF4K(sector) < miscDataLen + ndefLength)
+      {
+        return PN532_ERROR_MEM_INSUFFICIENT;
+      }
+      break;
+    default:
+      break;
+  }
+
+  processBlockNr = ndefTlvAdress / 16;
+  errCode = pn532_mifareclassic_AuthenticateBlock(pTag->uid,
+          pTag->lenUid,processBlockNr , PN532_MIFARE_CMD_AUTH_A,(byte_t *)KEY_NFC_PUBLIC_KEYA);
+  if(errCode != PN532_ERROR_NONE)
+  {
+    return errCode;
+  }
+
+  errCode = pn532_mifareclassic_ReadDataBlock(processBlockNr, blockBuffer);
+
+  if (ndefLength < 255) /* 1 byte length */
+  {
+    blockBuffer[blockBufferIdx + 1] = (uint8_t)ndefLength;
+    blockBufferIdx++;
+  }
+  else
+  {
+    blockBuffer[blockBufferIdx + 1] = 0xff;
+    blockBuffer[blockBufferIdx + 2] = (uint8_t)((ndefLength >> 8) & 0x00ff);
+    blockBuffer[blockBufferIdx + 3] = (uint8_t)(ndefLength & 0x00ff);
+    blockBufferIdx += 3;
+  }
+  blockBufferIdx = miscDataLen;
+
+  recordBuffer = (uint8_t*) pn532_ndef_getAll(rec);
+  recordBufferIdx = 0;
+
+  processSector = (processBlockNr/4);  /* For 1st run */
+
+  do
+  {
+    /* Fill the remaining bytes of the nfc block */
+    processLength = MY_MIN(16-blockBufferIdx,ndefLength-recordBufferIdx);
+    memcpy(blockBuffer + blockBufferIdx, recordBuffer + recordBufferIdx,
+      processLength);
+
+    recordBufferIdx += processLength;
+    blockBufferIdx += processLength;
+
+    /* Handle LAST BLOCK of Record */
+    if (blockBufferIdx < 16)
+    {
+      blockBuffer[blockBufferIdx] = TLV_TAG_TERMINATOR;
+      /* Fill the rest of block data as zero; */
+      memset(blockBuffer + blockBufferIdx + 1, 0x00,
+        16 - blockBufferIdx - 1);
+    }
+
+    if (processBlockNr == (uint8_t)(BLOCK_NUMBER_OF_SECTOR_1ST_BLOCK(processSector+1)))
+    {
+      processSector++;
+
+      CHECK_N_BREAK_FUNCTION(errCode,pn532_mifareclassic_AuthenticateBlock(pTag->uid,
+          pTag->lenUid,processBlockNr , PN532_MIFARE_CMD_AUTH_A,(byte_t *)KEY_NFC_PUBLIC_KEYA));
+    }
+
+    CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_WriteDataBlock(processBlockNr, blockBuffer));
+
+    blockBufferIdx = 0;
+    processBlockNr++;
+
+    //skip sector-trailer block
+    if (processBlockNr == (uint8_t)BLOCK_NUMBER_OF_SECTOR_TRAILER(processSector))
+    {
+      processBlockNr++;
+    }
+
+  } while (recordBufferIdx < ndefLength);
+
+  if (errCode != PN532_ERROR_NONE)
+  {
+    return errCode;
+  }
+
+  /* Exception: note that when the last byte of a record fits nicely in the last byte
+   * of a block, we need to fill TERMINATE TAG in the next block */
+  if (((ndefLength + miscDataLen) % 16) == 0)
+  {
+    blockBuffer[0] = TLV_TAG_TERMINATOR;
+    memset(&blockBuffer[1], 0, 15);
+    do
+    {
+      if (processBlockNr == BLOCK_NUMBER_OF_SECTOR_1ST_BLOCK(processSector+1))
+      {
+        processSector++;
+
+        CHECK_N_BREAK_FUNCTION(errCode,pn532_mifareclassic_AuthenticateBlock(pTag->uid,
+            pTag->lenUid,processBlockNr , PN532_MIFARE_CMD_AUTH_A,(byte_t *)KEY_NFC_PUBLIC_KEYA));
+      }
+
+      CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_WriteDataBlock(processBlockNr, blockBuffer));
+    } while (0);
+  }
+
+  return errCode;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Formats a blank Mifare Classic card and an NFC/NDEF tag
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_INVALID_TAG       (Tag is not blank)
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_mfc_nfc_format(pTag_t pTag, Bool isMad2Needed)
+{
+  pn532_error_t errCode = PN532_ERROR_NONE;
+  uint8_t blockBuffer[16];
+  uint8_t nfcCrcInfo[2] = { 0x14, 0x01 };
+  uint8_t nfcAids[16] = { 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1,
+                          0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1 };
+  uint8_t madAccessBits[3] = { 0x78, 0x77, 0x88 };
+  uint8_t nfcAccessBits[3] = { 0x7F, 0x07, 0x88 };
+  uint8_t numOfSector = 16;
+  uint8_t idx;
+
+  CHECK_INVALID_POINTER(pTag);
+
+  /* Assumes that the tag is now blank. If tag is not blank, return error */
+  if (pTag->ndefType != NDEF_TAG_TYPE_BLANK)
+  {
+    return PN532_ERROR_INVALID_TAG;
+  }
+
+  if ((pTag->type == TAG_TYPE_MFC_4K) && (isMad2Needed == True))
+  {
+    numOfSector = 40;
+  }
+
+  for (idx = 0; idx < numOfSector; idx++)
+  {
+    /* Change KEY A, accessBits, GPB of each sector */
+    CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_AuthenticateBlock(pTag->uid,
+        pTag->lenUid,BLOCK_NUMBER_OF_SECTOR_TRAILER(idx), PN532_MIFARE_CMD_AUTH_B,( byte_t *)KEY_DEFAULT_KEYAB));
+    if ((idx == 0) || (idx == 16)) //format Mad sector(s)
+    {
+      /* Write 0x03E1 into MAD1, (MAD2) */
+      memcpy(blockBuffer, nfcAids, sizeof(nfcAids));
+      CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 1, blockBuffer)); // 2
+      if (idx == 0)
+      {
+        memcpy(blockBuffer, nfcCrcInfo, sizeof(nfcCrcInfo));
+        memcpy(blockBuffer + 2, nfcAids, sizeof(nfcAids) - 2);
+        CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 2, blockBuffer)); // 1
+      }
+      else // idx = 16
+      {
+        memcpy(blockBuffer, nfcAids, sizeof(nfcAids));
+        CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 2, blockBuffer)); // 1
+
+        memcpy(blockBuffer, nfcCrcInfo, sizeof(nfcCrcInfo));
+        memcpy(blockBuffer + 2, nfcAids, sizeof(nfcAids) - 2);
+        CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 3, blockBuffer)); // 0
+      }
+
+      memcpy(blockBuffer, KEY_MAD_PUBLIC_KEYA, sizeof(KEY_MAD_PUBLIC_KEYA));
+      memcpy(blockBuffer + 6, madAccessBits, sizeof(madAccessBits));
+      if (idx == 0)
+      {
+        blockBuffer[9] = 0xC1;
+      }
+      else // idx = 16
+      {
+        blockBuffer[9] = 0xC2;
+      }
+      memcpy(blockBuffer + 10, KEY_DEFAULT_KEYAB, sizeof(KEY_DEFAULT_KEYAB));
+      CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_WriteDataBlock(BLOCK_NUMBER_OF_SECTOR_TRAILER(idx), blockBuffer)); // 3
+    }
+    else /* Format nfc sector(s) */
+    {
+      if (idx == 1)
+      {
+        memset(blockBuffer, 0, sizeof(blockBuffer));
+        blockBuffer[0] = 0x00;
+        blockBuffer[1] = 0x00;
+        blockBuffer[2] = 0x03; // TLV Ndef Message
+        blockBuffer[3] = 0x00; // length = 0
+        blockBuffer[4] = 0xfe; // end TLV
+        CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 3, blockBuffer));
+      }
+      /* other nfc sector(s) */
+      memcpy(blockBuffer, KEY_NFC_PUBLIC_KEYA, sizeof(KEY_NFC_PUBLIC_KEYA));
+      memcpy(blockBuffer + 6, nfcAccessBits, sizeof(nfcAccessBits));
+      blockBuffer[9] = 0x40;
+      memcpy(blockBuffer + 10, KEY_DEFAULT_KEYAB, sizeof(KEY_DEFAULT_KEYAB));
+      CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_WriteDataBlock(BLOCK_NUMBER_OF_SECTOR_TRAILER(idx), blockBuffer));
+    }
+  }
+  if (errCode != PN532_ERROR_NONE)
+  {
+    return errCode;
+  }
+
+  pTag->ndefType = NDEF_TAG_TYPE_NDEF_WRITE_ENABLE;
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reformats an NFC/NDEF tag as a blank Mifare Classic card
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_TAG_UNWRITABLE
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_mfc_blank_format(pTag_t pTag)
+{
+  pn532_error_t errCode = PN532_ERROR_NONE;
+  uint8_t blockBuffer[16];
+  uint8_t blankAccessBits[3] = { 0xff, 0x07, 0x80 };
+  uint8_t idx;
+  uint8_t numOfSector = 0;
+
+  CHECK_INVALID_POINTER(pTag);
+
+  /* Make sure that this is an NDEF tag and writeable */
+  if ((pTag->ndefType != NDEF_TAG_TYPE_NDEF_WRITE_ENABLE) && (pTag->ndefType
+    != NDEF_TAG_TYPE_BLANK))
+  {
+    return PN532_ERROR_TAG_UNWRITABLE;
+  }
+
+  /* Just exit if the card is already blank */
+  if (pTag->ndefType == NDEF_TAG_TYPE_BLANK)
+  {
+    return PN532_ERROR_NONE;
+  }
+
+  /* Figure out how many sectors we have */
+  if (pTag->type == TAG_TYPE_MFC_1K)
+  {
+    numOfSector = 16;
+  }
+  else if (pTag->type == TAG_TYPE_MFC_4K)
+  {
+    errCode = pn532_mifareclassic_AuthenticateBlock(pTag->uid,
+      pTag->lenUid, BLOCK_NUMBER_MAD2, PN532_MIFARE_CMD_AUTH_A,
+      (byte_t *) KEY_MAD_PUBLIC_KEYA);
+    if (errCode == PN532_ERROR_NONE)
+    {
+      numOfSector = 40;
+    }
+  }
+
+  for (idx = 0; idx < numOfSector; idx++)
+  {
+    /* 1.1 Authenticate MAD sector */
+    CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_AuthenticateBlock(pTag->uid,
+        pTag->lenUid,BLOCK_NUMBER_OF_SECTOR_TRAILER(idx), PN532_MIFARE_CMD_AUTH_B,( byte_t *)KEY_DEFAULT_KEYAB));
+
+    /* 1.2 Write to other blocks */
+    if (idx == 16)
+    {
+      memset(blockBuffer, 0, sizeof(blockBuffer));
+      CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 3, blockBuffer));
+    }
+    if ((idx == 0) || (idx == 16))
+    {
+      memset(blockBuffer, 0, sizeof(blockBuffer));
+      CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 2, blockBuffer));
+    }
+    else
+    {
+      memset(blockBuffer, 0, sizeof(blockBuffer));
+      CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 3, blockBuffer));
+      CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 2, blockBuffer));
+    }
+    memset(blockBuffer, 0, sizeof(blockBuffer));
+    CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 1, blockBuffer));
+
+    /* 1.3 Change the key */
+    memcpy(blockBuffer, KEY_DEFAULT_KEYAB, sizeof(KEY_DEFAULT_KEYAB));
+    memcpy(blockBuffer + 6, blankAccessBits, sizeof(blankAccessBits));
+    blockBuffer[9] = 0x69;
+    memcpy(blockBuffer + 10, KEY_DEFAULT_KEYAB, sizeof(KEY_DEFAULT_KEYAB));
+
+    /* 1.4 Write the trailer block */
+    CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_WriteDataBlock(BLOCK_NUMBER_OF_SECTOR_TRAILER(idx), blockBuffer));
+  }
+
+  if (errCode != PN532_ERROR_NONE)
+  {
+    return errCode;
+  }
+
+  pTag->ndefType = NDEF_TAG_TYPE_BLANK;
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_mfc_get_tagType(pTag_t pTag)
+{
+  pn532_error_t errCode = PN532_ERROR_NONE;
+  uint8_t nfcAidsTable[40] =  { 0 };
+  uint8_t blockBuffer[16];
+  uint8_t blockBufferIdx;
+  uint16_t idx, blockIdx;
+
+  CHECK_INVALID_POINTER(pTag)
+
+  /* Using do {}while(0) to take the advantage of 'break' and avoid 'goto' */
+  pTag->ndefType = NDEF_TAG_UNKNOWN;
+
+  do
+  {
+    /* 1 Authenticate MAD1 sector with Mad public key A */
+    CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_AuthenticateBlock(pTag->uid,
+        pTag->lenUid,BLOCK_NUMBER_MAD1, PN532_MIFARE_CMD_AUTH_A,( byte_t *)KEY_MAD_PUBLIC_KEYA))
+
+    CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_ReadDataBlock(BLOCK_NUMBER_MAD1, blockBuffer));
+
+    /* 1.1 check DA bit in GPB, must be 1 indicate that MAD is available */
+    if ((GPB(blockBuffer) & 0x01) == 0)
+    {
+      break;
+    }
+    /* 1.2 Check the access condition bits */
+    if (memcmp(&ACB(blockBuffer), "\x78\x77\x88", 3) == 0)
+    {
+      pTag->ndefType = NDEF_TAG_TYPE_NDEF_WRITE_ENABLE;
+    }
+    else if (memcmp(&ACB(blockBuffer), "\x07\x8f\x0f", 3) == 0)
+    {
+      pTag->ndefType = NDEF_TAG_TYPE_NDEF_READ_ONLY;
+    }
+
+    /* 1.3. Fill NFC AIDs into NFC_AIDs table */
+    CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_ReadDataBlock(1, blockBuffer));
+
+    for (idx = 2; idx < 16; idx += 2)
+    {
+      if ((blockBuffer[idx] == NFC_AID_APP_CODE) && (blockBuffer[idx + 1]
+        == NFC_AID_CLUSTER_CODE))
+      {
+        nfcAidsTable[idx / 2] = 1;
+      }
+    }
+
+    CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_ReadDataBlock(2, blockBuffer));
+
+    for (idx = 0; idx < 16; idx += 2)
+    {
+      if ((blockBuffer[idx] == NFC_AID_APP_CODE) && (blockBuffer[idx + 1]
+        == NFC_AID_CLUSTER_CODE))
+      {
+        nfcAidsTable[(idx / 2) + 8] = 1;
+      }
+    }
+
+    /* 2. Authenticate MAD2 sector with Mad public key A */
+    if (pTag->type == TAG_TYPE_MFC_4K)
+    {
+      errCode = pn532_mifareclassic_AuthenticateBlock(pTag->uid, pTag->lenUid,
+        BLOCK_NUMBER_MAD2, PN532_MIFARE_CMD_AUTH_A,
+        (byte_t *) KEY_MAD_PUBLIC_KEYA);
+
+      if (errCode == PN532_ERROR_NONE)
+      {
+        errCode = pn532_mifareclassic_ReadDataBlock(BLOCK_NUMBER_MAD2,
+          blockBuffer);
+
+        if (errCode == PN532_ERROR_NONE)
+        {
+          /* 2.1 Check the DA bit in GPB ... must be 1 to indicate that MAD is available */
+          if ((GPB(blockBuffer) & 0x01) == 0)
+          {
+            break;
+          }
+          /* 2.2 Check the access condition bits */
+          if (memcmp(&ACB(blockBuffer), "\x78\x77\x88", 3) == 0)
+          {
+            pTag->ndefType = NDEF_TAG_TYPE_NDEF_WRITE_ENABLE;
+          }
+          else if (memcmp(&ACB(blockBuffer), "\x07\x8f\x0f", 3) == 0)
+          {
+            pTag->ndefType = NDEF_TAG_TYPE_NDEF_READ_ONLY;
+          }
+
+          /* Fill NFC AIDs into NFC_AIDs table */
+          CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_ReadDataBlock(1, blockBuffer));
+
+          for (idx = 2; idx < 16; idx += 2)
+          {
+            if ((blockBuffer[idx] == NFC_AID_APP_CODE)
+              && (blockBuffer[idx + 1] == NFC_AID_CLUSTER_CODE))
+            {
+              nfcAidsTable[(idx / 2) + 16] = 1;
+            }
+          }
+
+          CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_ReadDataBlock(2, blockBuffer));
+
+          for (idx = 0; idx < 16; idx += 2)
+          {
+            if ((blockBuffer[idx] == NFC_AID_APP_CODE)
+              && (blockBuffer[idx + 1] == NFC_AID_CLUSTER_CODE))
+            {
+              nfcAidsTable[(idx / 2) + 23] = 1;
+            }
+          }
+
+          CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_ReadDataBlock(2, blockBuffer));
+
+          for (idx = 0; idx < 16; idx += 2)
+          {
+            if ((blockBuffer[idx] == NFC_AID_APP_CODE)
+              && (blockBuffer[idx + 1] == NFC_AID_CLUSTER_CODE))
+            {
+              nfcAidsTable[(idx / 2) + 32] = 1;
+            }
+          }
+        }
+      }
+    }
+
+    /* 3. Check NFC sector */
+    for (idx = 1; idx < sizeof(nfcAidsTable) / sizeof(nfcAidsTable[0]); idx++)
+    {
+      if (nfcAidsTable[idx] == 1)
+      {
+        // to do A
+        errCode = pn532_mifareclassic_AuthenticateBlock(pTag->uid,
+          pTag->lenUid, BLOCK_NUMBER_OF_SECTOR_TRAILER(idx),
+          PN532_MIFARE_CMD_AUTH_A, (byte_t *) KEY_NFC_PUBLIC_KEYA);
+
+        if (errCode != PN532_ERROR_NONE)
+        {
+          continue;
+        }
+
+        /* Check DA bit in GPB, must be 1 indicate that MAD is available */
+        errCode = pn532_mifareclassic_ReadDataBlock(
+          BLOCK_NUMBER_OF_SECTOR_TRAILER(idx), blockBuffer);
+
+        if (errCode != PN532_ERROR_NONE)
+        {
+          continue;
+        }
+
+        gGPB = GPB(blockBuffer);
+
+        /* Check version bits 4-7 */
+        if ((((gGPB >> 4) & 0x03) != NFC_GPB_MINOR_VERSION) || (((gGPB
+          >> 6) & 0x03) != NFC_GPB_MAJOR_VERSION))
+        {
+          break;
+        }
+
+        /* Check read access condition */
+        if (((gGPB >> 2) & 0x03) != NFC_GPB_RW_ACCESS_RIGHT_GRANTED) /* read access condition support */
+        {
+          continue;
+        }
+
+        /* Check write access condition; R/W condition must be valid: either 00b or 11b */
+        if ((((gGPB >> 0) & 0x03) != NFC_GPB_RW_ACCESS_RIGHT_GRANTED) &&
+                        (((gGPB >> 0) & 0x03) != NFC_GPB_RW_ACCESS_RIGHT_PROHIBIT))
+        {
+          continue;
+        }
+
+
+
+        /* Check Access condition Bits */
+        if ((memcmp(&ACB(blockBuffer), "\x7f\x07\x88", 3) == 0)
+          && (pTag->ndefType = NDEF_TAG_TYPE_NDEF_WRITE_ENABLE))
+        {
+          pTag->ndefType = NDEF_TAG_TYPE_NDEF_WRITE_ENABLE;
+        }
+        else if ((memcmp(&ACB(blockBuffer), "\x07\x8f\x0f", 3) == 0)
+          && (pTag->ndefType = NDEF_TAG_TYPE_NDEF_READ_ONLY))
+        {
+          pTag->ndefType = NDEF_TAG_TYPE_NDEF_READ_ONLY;
+        }
+        else
+        {
+          pTag->ndefType = NDEF_TAG_UNKNOWN;
+        }
+
+        for(blockIdx = 0; blockIdx < ((idx > 32)?15:3); blockIdx++)
+        {
+          errCode = pn532_mifareclassic_ReadDataBlock(
+          (BLOCK_NUMBER_OF_SECTOR_1ST_BLOCK(idx)) + blockIdx, blockBuffer);
+
+          if (errCode != PN532_ERROR_NONE)
+          {
+            continue;
+          }
+
+          for(blockBufferIdx = 0; blockBufferIdx < 16; blockBufferIdx++)
+          {
+            /* Check NDEF Message TLV */
+            if (blockBuffer[blockBufferIdx] != TLV_TAG_NDEF)
+            {
+              continue;
+            }
+
+            pTag->ndefStartSector = idx;
+            /* Check NDEF TLV Length 1 byte or 3 bytes format */
+            // if (blockBuffer[3] == 0xff) /* 3 bytes format */
+            // {
+            //   tlvLength = (((uint16_t) blockBuffer[4] << 8) & 0xff00)
+            //     | ((uint16_t) blockBuffer[5] & 0x00ff);
+            // }
+            // else /* 1 byte format */
+            // {
+            //   tlvLength = blockBuffer[4];
+            // }
+
+            return PN532_ERROR_NONE;
+          }
+        }
+      }
+    }
+  } while (0);
+
+  /* Detect blank tag */
+  /* Authenticate MAD1 sector with the default Mad public key to check blank card */
+  if ((pn532_mifareclassic_AuthenticateBlock(pTag->uid, pTag->lenUid, BLOCK_NUMBER_MAD1,
+    PN532_MIFARE_CMD_AUTH_B, (byte_t *) KEY_DEFAULT_KEYAB))
+    == PN532_ERROR_NONE)
+  {
+    errCode = pn532_mifareclassic_ReadDataBlock(BLOCK_NUMBER_MAD1,
+      blockBuffer);
+    if ((GPB(blockBuffer) & 0x01) == 0)
+    {
+      pTag->ndefType = NDEF_TAG_UNKNOWN;
+      return PN532_ERROR_NONE;
+    }
+    /* Check access condition Bits */
+    if (memcmp(&ACB(blockBuffer), "\xff\x07\x80", 3) == 0)
+    {
+      pTag->ndefType = NDEF_TAG_TYPE_BLANK;
+    }
+    else
+    {
+      pTag->ndefType = NDEF_TAG_UNKNOWN;
+      return PN532_ERROR_NONE;
+    }
+    for (idx = 1; idx < 16; idx++)
+    {
+      if ((pn532_mifareclassic_AuthenticateBlock(pTag->uid, pTag->lenUid,
+        BLOCK_NUMBER_OF_SECTOR_TRAILER(idx), PN532_MIFARE_CMD_AUTH_A,
+        (byte_t *) KEY_DEFAULT_KEYAB)) != PN532_ERROR_NONE)
+      {
+        pTag->ndefType = NDEF_TAG_UNKNOWN;
+        break;
+      }
+    }
+
+    /* Check if the tag has MAD2 */
+    if (((pn532_mifareclassic_AuthenticateBlock(pTag->uid, pTag->lenUid,
+      BLOCK_NUMBER_MAD2, PN532_MIFARE_CMD_AUTH_A,
+      (byte_t *) KEY_DEFAULT_KEYAB)) == PN532_ERROR_NONE) && (pTag->type
+      = TAG_TYPE_MFC_4K))
+    {
+      if ( (GPB(blockBuffer) & 0x01) == 0)
+      {
+        pTag->ndefType = NDEF_TAG_UNKNOWN;
+        return PN532_ERROR_NONE;
+      }
+      /* Check access condition bits */
+      if (memcmp(&ACB(blockBuffer), "\xff\x07\x80", 3) == 0)
+      {
+        pTag->ndefType = NDEF_TAG_TYPE_BLANK;
+      }
+      else
+      {
+        pTag->ndefType = NDEF_TAG_UNKNOWN;
+        return PN532_ERROR_NONE;
+      }
+      for (idx = 16; idx < 40; idx++)
+      {
+        if ((pn532_mifareclassic_AuthenticateBlock(pTag->uid, pTag->lenUid,
+          BLOCK_NUMBER_OF_SECTOR_TRAILER(idx),
+          PN532_MIFARE_CMD_AUTH_A, (byte_t *) KEY_DEFAULT_KEYAB))
+          != PN532_ERROR_NONE)
+        {
+          pTag->ndefType = NDEF_TAG_UNKNOWN;
+          return PN532_ERROR_NONE;
+        }
+      }
+    }
+    pTag->ndefType = NDEF_TAG_TYPE_BLANK;
+  }
+
+  return errCode;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_mfc_parseNtag(pTag_t pTag, pn532_ndef_record_t *rec)
+{
+  pn532_error_t errCode = PN532_ERROR_NONE;
+  uint8_t *pBuff = NULL;
+  uint8_t processSector;
+  uint8_t processBlockNr;
+  uint8_t processDataLength;
+  uint16_t bufferIdx = 0, blockBufferIdx;
+  uint16_t bufferLength = 0;
+  uint16_t nfcTlvAddress;
+  uint8_t blockBuffer[16];
+
+  CHECK_INVALID_POINTER(pTag)
+
+  if ((pTag->type != TAG_TYPE_MFC_1K) && (pTag->type != TAG_TYPE_MFC_4K))
+  {
+    return PN532_ERROR_INVALID_TAG;
+  }
+
+  errCode = pn532_ndef_mfc_scan_ndef_tlv(pTag, &nfcTlvAddress);
+  if(errCode != PN532_ERROR_NONE)
+  {
+    return errCode;
+  }
+
+  processSector = nfcTlvAddress/64;
+  processBlockNr = nfcTlvAddress/16;
+  blockBufferIdx = nfcTlvAddress%16;
+  pTag->ndefStartSector = processSector;
+
+  do
+  {
+    /* if (processBlockNr == BLOCK_NUMBER_OF_SECTOR_1ST_BLOCK(processSector)) */
+    CHECK_N_BREAK_FUNCTION(errCode,pn532_mifareclassic_AuthenticateBlock(pTag->uid,
+      pTag->lenUid,processBlockNr , PN532_MIFARE_CMD_AUTH_A,(byte_t *)KEY_NFC_PUBLIC_KEYA));
+
+    CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_ReadDataBlock(processBlockNr, blockBuffer));
+    if (processBlockNr == (nfcTlvAddress/16))  /* Only do this for the first block */
+    {
+      uint8_t miscDataLength;
+
+      /* First block ... get Length and data */
+      if (blockBuffer[blockBufferIdx + 1] == 0xff)
+      {
+        bufferLength = ((uint16_t) blockBuffer[blockBufferIdx + 2]) << 8 |
+                ((uint16_t) blockBuffer[blockBufferIdx + 3]);
+        miscDataLength = blockBufferIdx + 4;
+      }
+      else
+      {
+        bufferLength = blockBuffer[blockBufferIdx + 1];
+        miscDataLength = blockBufferIdx + 2;
+      }
+
+      if(bufferLength)
+      {
+          pBuff = (uint8_t*) pn532_mem_alloc(bufferLength);
+      }
+      else
+      {
+          return PN532_ERROR_NOT_NDEF_CARD;
+      }
+      if (pBuff == NULL)
+      {
+        return PN532_ERROR_MEM_INSUFFICIENT;
+      }
+
+      processDataLength = MY_MIN(bufferLength-blockBufferIdx,16-miscDataLength);
+      memcpy(pBuff, blockBuffer + miscDataLength, processDataLength);
+      bufferIdx += processDataLength;
+    }
+    else
+    {
+      processDataLength = MY_MIN(bufferLength-bufferIdx,16);
+      memcpy(pBuff + bufferIdx, blockBuffer, processDataLength);
+      bufferIdx += processDataLength;
+    }
+
+    processBlockNr++;
+
+    /* skip sector-trailer block */
+    if (processBlockNr == (uint8_t)BLOCK_NUMBER_OF_SECTOR_TRAILER(processSector))
+    {
+      processSector++;
+      processBlockNr++;
+    }
+
+  } while (bufferIdx < bufferLength);
+
+  if (errCode == PN532_ERROR_NONE)
+  {
+    pn532_ndef_createFromRaw(rec, pBuff, bufferLength);
+  }
+
+  if (pBuff)
+  {
+    pn532_mem_free(pBuff);
+  }
+
+  return errCode;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_mfc_tagType_identify(uint8_t sak, uint16_t atqa,
+  pTag_t pTag)
+{
+  TagType_t tagType = TAG_TYPE_UNKNOWN;
+
+  CHECK_INVALID_POINTER(pTag)
+
+  /* Check if this is a type 4 tag */
+  if (sak & 0x20)
+  {
+    tagType = TAG_TYPE_UNKNOWN;
+    /* ToDo: We can identify more specific type 4 tags here, like desfire, jcop ...*/
+  }
+  else
+  {
+    switch (sak)
+    {
+      /* Infineon Mfc 1k */
+      case 0x88:
+        tagType = TAG_TYPE_MFC_1K;
+        break;
+      /* Classic 1K, Mifare Plus 2K cl2, ...*/
+      case 0x08:
+        if (atqa == (uint16_t)0x0004)
+        {
+          tagType = TAG_TYPE_MFC_1K;
+        }
+        break;
+      /* Classic 4K,... */
+      case 0x18:
+        if (atqa == (uint16_t)0x0002)
+        {
+          tagType = TAG_TYPE_MFC_4K;
+        }
+        break;
+      /* Mini group */
+      case 0x09:
+        tagType = TAG_TYPE_MF_MINI;       /* REQA==0X0400 */
+        break;
+      /* Ultralight/c group */
+      case 0x00:
+        tagType = TAG_TYPE_MF_ULTRALIGHT; /* ATQA = 0X4400 */
+        break;
+      default:
+        break;
+    }
+  }
+
+  pTag->type = tagType;
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_INVALID_TAG
+            - PN532_ERROR_NOT_FOUND_NDEF_TLV
+*/
+/**************************************************************************/
+pn532_error_t pn532_ndef_mfc_scan_ndef_tlv(pTag_t pTag, uint16_t *ndefTlvAddrress)
+{
+  pn532_error_t errCode = PN532_ERROR_NONE;
+  uint8_t sectorSearchRange = 0;
+  uint8_t blockSearchRange = 4;
+  uint8_t blockBuffer[16];
+  uint16_t sectorIdx, blockIdx, blockBufferIdx;
+  /* Make sure pTag is an NDEF tag: NDEF tag and read/rw */
+  if((pTag->ndefType != NDEF_TAG_TYPE_NDEF_WRITE_ENABLE) && (pTag->ndefType != NDEF_TAG_TYPE_NDEF_READ_ONLY))
+  {
+    return PN532_ERROR_INVALID_TAG;
+  }
+  if(pTag->type == TAG_TYPE_MFC_1K)
+  {
+    sectorSearchRange = 16;
+  }
+  else if(pTag->type == TAG_TYPE_MFC_4K)
+  {
+    sectorSearchRange = 40;
+  }
+  /* Scan all nfc sectors to find Ndef Message TLV */
+  for(sectorIdx = 0; sectorIdx < sectorSearchRange; sectorIdx++)
+  {
+    if((sectorIdx == 0) || (sectorIdx == 16))  /* if idx is mad sector -> continue */
+    {
+      continue;
+    }
+    else
+    {
+      /* Authenticate all nfc sectors using keyA */
+      CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_AuthenticateBlock(pTag->uid,
+        pTag->lenUid,BLOCK_NUMBER_OF_SECTOR_TRAILER(sectorIdx), PN532_MIFARE_CMD_AUTH_A,(byte_t *)KEY_NFC_PUBLIC_KEYA));
+
+      /* If authentication is OK -> read nfc authenticated sector block to find NDEF Message TLV */
+      /* Read all blocks of a sector */
+      if(sectorIdx > 31)
+      {
+        blockSearchRange = 16;
+      }
+      for(blockIdx = 0; blockIdx < blockSearchRange; blockIdx++)
+      {
+        CHECK_N_BREAK_FUNCTION(errCode, pn532_mifareclassic_ReadDataBlock
+          ((BLOCK_NUMBER_OF_SECTOR_1ST_BLOCK(sectorIdx)) + blockIdx, blockBuffer));
+        for(blockBufferIdx = 0; blockBufferIdx < sizeof(blockBuffer); blockBufferIdx++)
+        {
+          if(blockBuffer[blockBufferIdx] == TLV_TAG_NDEF)
+          {
+            *ndefTlvAddrress = ((BLOCK_NUMBER_OF_SECTOR_1ST_BLOCK(sectorIdx)) + blockIdx)*16 + blockBufferIdx;
+            return PN532_ERROR_NONE;
+          }
+        } /* Loop to find Ndef messages TLV for blockBuffer */
+      } /* loop to find Ndef messages TLV for all blocks of a sector */
+    }
+  } /* loop to find Ndef message TLV for all sectors */
+  return PN532_ERROR_NOT_FOUND_NDEF_TLV;
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_ndef_cards.h b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_ndef_cards.h
new file mode 100644
index 0000000000000000000000000000000000000000..103cb383392749474cce8e0eae7b0806704207da
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/helpers/pn532_ndef_cards.h
@@ -0,0 +1,214 @@
+/**************************************************************************/
+/*!
+    @file pn532_ndef_cards.h
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013 Adafruit Industries (www.adafruit.com)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef PN532_NDEF_CARDS_H_
+#define PN532_NDEF_CARDS_H_
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "../pn532.h"
+//#include "../pn532_bus.h"
+#include "pn532_mifare.h"
+#include "pn532_ndef.h"
+
+typedef unsigned char Bool, *pBool; /* Boolean (True/False) */
+#define True            1
+#define False      0
+/** type to identify a Ndef Tag type*/
+typedef enum ndefTagType_en
+{
+  /*a blank Card/Tag*/
+  NDEF_TAG_TYPE_BLANK = 0,
+  /*a blank card with default setting from manufacturer*/
+  NDEF_TAG_TYPE_AFTER_PRODUCTION = 1,
+  /*Ndef formated as a read-only tag*/
+  NDEF_TAG_TYPE_NDEF_READ_ONLY = 2,
+  /*Ndef formated as a Read-write Tag*/
+  NDEF_TAG_TYPE_NDEF_WRITE_ENABLE = 3,
+  /*Tag is propietary formated*/
+  NDEF_TAG_PROPRIETARY = 4,
+  /*Tag in unknown */
+  NDEF_TAG_UNKNOWN = 5
+} NdefTagType_t;
+
+typedef enum tagType_en
+{
+  /*MF1 S50 tag*/
+  TAG_TYPE_MFC_1K = 0,
+  /*MF1 S70 tag*/
+  TAG_TYPE_MFC_4K,
+  /*MF1 PLUS 60*/
+  TAG_TYPE_MFPLUS_X_2K,
+  /*MF1 SPLUS 60*/
+  TAG_TYPE_MFPLUS_S_2K,
+  /*MF1 PLUS 80*/
+  TAG_TYPE_MFPLUS_X_4K,
+  /*MF1 SPLUS 80*/
+  TAG_TYPE_MFPLUS_S_4K,
+  /*MIFARE MINI*/
+  TAG_TYPE_MF_MINI,
+  /*Mifare UL*/
+  TAG_TYPE_MF_ULTRALIGHT,
+  /*todo: expand to other card type: UL, ULC, Topaz, Desfire, Felica, ...*/
+  /*Unknown tag type*/
+  TAG_TYPE_UNKNOWN
+} TagType_t;
+
+typedef struct MfcTag_str
+{
+  uint8_t nfcBlockStart;
+  uint8_t nrNfcBlock;
+} MfcTag_t;
+
+/** tag data structure, hold info for the module to operate*/
+typedef struct tag_str
+{
+  TagType_t type;
+  NdefTagType_t ndefType;
+  MfcTag_t mfcTagInfo;
+  uint8_t uid[8];
+  uint8_t lenUid;
+  /*First Sector Of Ndef data, include TLV wrapper*/
+  uint16_t ndefStartSector;
+} Tag_t, *pTag_t;
+
+/**************************************************************************/
+/**
+ * @brief Tries to write a Ndef record to a NFC formated tag
+ * @param[in] pTag   pointer to the tag need to format
+ * @param[in] rec    record to write to the tag;
+ * @return    Possible error messages are:
+ *     PN532_ERROR_BLOCKWRITEFAILED
+ *     PN532_ERROR_NONE
+ *     PN532_ERROR_INVALID_PARAM
+ *    PN532_ERROR_INVALID_TAG
+ */
+/**************************************************************************/
+pn532_error_t pn532_ndef_mfc_ndef_write(pTag_t pTag, pn532_ndef_record_t rec,
+  uint8_t sector);
+
+/**************************************************************************/
+/**
+ * @brief scan NDEF Message TLV
+ * @param[in]  pTag   pointer to the tag need to format
+ * @param[out] sector   return the sector containing Ndef Message TLV
+ * @param[out] blockNumber    record to block sector containing Ndef Message TLV
+ * @param[out] blockBufferIdx  record to block sector containing Ndef Message TLV
+ * @return    Possible error messages are:
+ *     PN532_ERROR_NOT_FOUND_NDEF_TLV
+ *     PN532_ERROR_NONE
+ *     PN532_ERROR_INVALID_PARAM
+ *    PN532_ERROR_INVALID_TAG
+ */
+/**************************************************************************/
+pn532_error_t pn532_ndef_mfc_scan_ndef_tlv(pTag_t pTag, uint16_t *ndefTlvAddrress);
+
+/**************************************************************************/
+/**
+ *  @brief   Tries to format a Mifare Classic tag to become a NFC card
+ *   @param[in] pTag   pointer to the tag need to format
+ *   @param[in] isMad2Needed   mad2 input
+ *   @return         pn532_error_t, Possible error messages are:
+ *     PN532_ERROR_BLOCKWRITEFAILED
+ *     PN532_ERROR_INVALID_PARAM
+ */
+/**************************************************************************/
+pn532_error_t pn532_ndef_mfc_nfc_format(pTag_t pTag, Bool isMad2Needed);
+
+/**************************************************************************/
+/**
+ *  @brief   Tries to format a Mifare Classic tag to become a Blank card
+ *   @param[in] pTag   pointer to the tag need to format
+ *   @return         pn532_error_t, Possible error messages are:
+ *     PN532_ERROR_BLOCKWRITEFAILED
+ *     PN532_ERROR_INVALID_PARAM
+ */
+/**************************************************************************/
+pn532_error_t pn532_ndef_mfc_blank_format(pTag_t pTag);
+
+/**************************************************************************/
+/**
+ * @brief check if a tag is ndef formated or Blank
+ * @param[in] pTag   pointer to the tag need to get tag type.
+ * @return pn532_error_t
+ *    PN532_ERROR_NONE
+ */
+/**************************************************************************/
+pn532_error_t pn532_ndef_mfc_get_tagType(pTag_t pTag);
+
+/**************************************************************************/
+/**
+ * @brief  Tries to parse a Ndef record in a card an return the record out to
+ * user if sucess
+ * @param[in] pTag   the tag from what the parser will go thru
+ * @param[out] rec  record to return to user.
+ * @note: user need to destroy return records in case it is not null
+ * @return pn532_error_t
+ *     PN532_ERROR_INVALID_PARAM
+ *     PN532_ERROR_INVALID_TAG
+ *     PN532_ERROR_NONE
+ *     PN532_ERROR_BLOCKWRITEFAILED
+ */
+/**************************************************************************/
+pn532_error_t pn532_ndef_mfc_parseNtag(pTag_t pTag, pn532_ndef_record_t *rec);
+
+/**************************************************************************/
+/**
+ * @brief  Identify a type A card based on its SAK and atqa infor
+ * @param[in] sak   Select Acknowledge byte return by the cards
+ * @param[in] atqa  answer to REQA data.
+ * @param[out] pTAg tag information to be filled to
+ * @return pn532_error_t
+ *     PN532_ERROR_NONE
+ */
+/**************************************************************************/
+pn532_error_t pn532_ndef_mfc_tagType_identify(uint8_t sak, uint16_t atqa,
+  pTag_t pTag);
+/**************************************************************************/
+/**
+ * @brief  reset card when authenticate fail
+ * @return none
+ */
+/**************************************************************************/
+void pn532_mifareclassic_reset();
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* PN532_NDEF_CARDS_H_ */
+
+/*@}*/
+
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/mem_allocator/bget.c b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/mem_allocator/bget.c
new file mode 100644
index 0000000000000000000000000000000000000000..047ba1bccfca98875c28f2ecee52acf9b97e4c3d
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/mem_allocator/bget.c
@@ -0,0 +1,1114 @@
+/*
+
+			       B G E T
+
+			   Buffer allocator
+
+    Designed and implemented in April of 1972 by John Walker, based on the
+    Case Algol OPRO$ algorithm implemented in 1966.
+
+    Reimplemented in 1975 by John Walker for the Interdata 70.
+    Reimplemented in 1977 by John Walker for the Marinchip 9900.
+    Reimplemented in 1982 by Duff Kurland for the Intel 8080.
+
+    Portable C version implemented in September of 1990 by an older, wiser
+    instance of the original implementor.
+
+    Souped up and/or weighed down  slightly  shortly  thereafter  by  Greg
+    Lutz.
+
+    AMIX  edition, including the new compaction call-back option, prepared
+    by John Walker in July of 1992.
+
+    Bug in built-in test program fixed, ANSI compiler warnings eradicated,
+    buffer pool validator  implemented,  and  guaranteed  repeatable  test
+    added by John Walker in October of 1995.
+
+    This program is in the public domain.
+
+     1. This is the book of the generations of Adam.   In the day that God
+	created man, in the likeness of God made he him;
+     2. Male and female created he them;  and  blessed	them,  and  called
+	their name Adam, in the day when they were created.
+     3. And  Adam  lived  an hundred and thirty years,	and begat a son in
+	his own likeness, and after his image; and called his name Seth:
+     4. And the days of  Adam  after  he  had  begotten  Seth  were  eight
+	hundred years: and he begat sons and daughters:
+     5. And  all  the  days  that Adam lived were nine	hundred and thirty
+	years: and he died.
+     6. And Seth lived an hundred and five years, and begat Enos:
+     7. And Seth lived after he begat Enos eight hundred and seven  years,
+	and begat sons and daughters:
+     8.  And  all the days of Seth were nine hundred and twelve years: and
+	 he died.
+     9. And Enos lived ninety years, and begat Cainan:
+    10. And Enos lived after he begat  Cainan eight  hundred  and  fifteen
+	years, and begat sons and daughters:
+    11. And  all  the days of Enos were nine hundred  and five years:  and
+	he died.
+    12. And Cainan lived seventy years and begat Mahalaleel:
+    13. And Cainan lived  after he  begat  Mahalaleel  eight  hundred  and
+	forty years, and begat sons and daughters:
+    14. And  all the days of Cainan were nine  hundred and ten years:  and
+	he died.
+    15. And Mahalaleel lived sixty and five years, and begat Jared:
+    16. And Mahalaleel lived  after  he  begat	Jared  eight  hundred  and
+	thirty years, and begat sons and daughters:
+    17. And  all  the  days  of Mahalaleel  were eight hundred	ninety and
+	five years: and he died.
+    18. And Jared lived an hundred sixty and  two  years,   and  he  begat
+	Enoch:
+    19. And  Jared  lived  after he begat Enoch  eight hundred years,  and
+	begat sons and daughters:
+    20. And all the days of Jared  were nine hundred sixty and two  years:
+	and he died.
+    21. And Enoch lived sixty and five years, and begat Methuselah:
+    22. And  Enoch  walked   with  God	after  he  begat Methuselah  three
+	hundred years, and begat sons and daughters:
+    23. And all the days of  Enoch  were  three  hundred  sixty  and  five
+	years:
+    24. And Enoch walked with God: and he was not; for God took him.
+    25. And  Methuselah  lived	an  hundred  eighty and  seven years,  and
+	begat Lamech.
+    26. And Methuselah lived after he  begat Lamech seven  hundred  eighty
+	and two years, and begat sons and daughters:
+    27. And  all the days of Methuselah  were nine hundred  sixty and nine
+	years: and he died.
+    28. And Lamech lived an hundred eighty  and two  years,  and  begat  a
+	son:
+    29. And  he called his name Noah, saying,  This same shall	comfort us
+	concerning  our  work and toil of our hands, because of the ground
+	which the LORD hath cursed.
+    30. And  Lamech  lived  after  he begat Noah  five hundred	ninety and
+	five years, and begat sons and daughters:
+    31. And all the days of Lamech were  seven hundred seventy	and  seven
+	years: and he died.
+    32. And  Noah  was five hundred years old:	and Noah begat Shem,  Ham,
+	and Japheth.
+
+    And buffers begat buffers, and links begat	links,	and  buffer  pools
+    begat  links  to chains of buffer pools containing buffers, and lo the
+    buffers and links and pools of buffers and pools of links to chains of
+    pools  of  buffers were fruitful and they multiplied and the Operating
+    System looked down upon them and said that it was Good.
+
+
+    INTRODUCTION
+    ============
+
+    BGET  is a comprehensive memory allocation package which is easily
+    configured to the needs of an application.	BGET is  efficient  in
+    both  the  time  needed to allocate and release buffers and in the
+    memory  overhead  required	for  buffer   pool   management.    It
+    automatically    consolidates   contiguous	 space	 to   minimise
+    fragmentation.  BGET is configured	by  compile-time  definitions,
+    Major options include:
+
+    *   Allocation  by  either the "first fit" or "best fit"
+	    method.
+
+	*   Wiping buffers at release time to catch  code  which
+	    references previously released storage.
+
+	*   Built-in  routines to dump individual buffers or the
+	    entire buffer pool.
+
+	*   Retrieval of allocation and pool size statistics.
+
+	*   Quantisation of buffer sizes to a power  of  two  to
+	    satisfy hardware alignment constraints.
+
+	*   Automatic  pool compaction, growth, and shrinkage by
+	    means of call-backs to user defined functions.
+
+    Applications  of  BGET  can  range	from  storage  management   in
+    ROM-based  embedded programs to providing the framework upon which
+    a  multitasking  system  incorporating   garbage   collection   is
+    constructed.   BGET  incorporates  extensive  internal consistency
+    checking using the <assert.h> mechanism; all these checks  can  be
+    turned off by compiling with NDEBUG defined, yielding a version of
+    BGET with minimal size and maximum speed.
+
+    The  basic	algorithm  underlying  BGET  has withstood the test of
+    time;  more  than  25  years   have   passed   since   the	 first
+    implementation  of	this  code.  And yet, it is substantially more
+    efficient than the native allocation  schemes  of  many  operating
+    systems: the Macintosh and Microsoft Windows to name two, on which
+    programs have obtained substantial speed-ups by layering  BGET  as
+    an application level memory manager atop the underlying system's.
+
+    BGET has been implemented on the largest mainframes and the lowest
+    of	microprocessors.   It  has served as the core for multitasking
+    operating systems, multi-thread applications, embedded software in
+    data  network switching processors, and a host of C programs.  And
+    while it has accreted flexibility and additional options over  the
+    years,  it	remains  fast, memory efficient, portable, and easy to
+    integrate into your program.
+
+
+    BGET IMPLEMENTATION ASSUMPTIONS
+    ===============================
+
+    BGET is written in as portable a dialect of C  as  possible.   The
+    only   fundamental	 assumption   about  the  underlying  hardware
+    architecture is that memory is allocated is a linear  array  which
+    can  be  addressed  as a vector of C "char" objects.  On segmented
+    address space architectures, this generally means that BGET should
+    be used to allocate storage within a single segment (although some
+    compilers	simulate   linear   address   spaces   on    segmented
+    architectures).   On  segmented  architectures,  then, BGET buffer
+    pools  may not be larger than a segment, but since BGET allows any
+    number of separate buffer pools, there is no limit	on  the  total
+    storage  which  can  be  managed,  only  on the largest individual
+    object which can be allocated.  Machines  with  a  linear  address
+    architecture,  such  as  the VAX, 680x0, Sparc, MIPS, or the Intel
+    80386 and above in native mode, may use BGET without restriction.
+
+
+    GETTING STARTED WITH BGET
+    =========================
+
+    Although BGET can be configured in a multitude of fashions,  there
+    are  three	basic  ways  of  working  with	BGET.	The  functions
+    mentioned below are documented in the following  section.	Please
+    excuse  the  forward  references which are made in the interest of
+    providing a roadmap to guide you  to  the  BGET  functions  you're
+    likely to need.
+
+    Embedded Applications
+    ---------------------
+
+    Embedded applications  typically  have  a  fixed  area  of	memory
+    dedicated  to  buffer  allocation (often in a separate RAM address
+    space distinct from the ROM that contains  the  executable	code).
+    To	use  BGET in such an environment, simply call bpool() with the
+    start address and length of the buffer  pool  area	in  RAM,  then
+    allocate  buffers  with  bget()  and  release  them  with  brel().
+    Embedded applications with very limited RAM but abundant CPU speed
+    may  benefit  by configuring BGET for BestFit allocation (which is
+    usually not worth it in other environments).
+
+    Malloc() Emulation
+    ------------------
+
+    If the C library malloc() function is too  slow,  not  present  in
+    your  development environment (for example, an a native Windows or
+    Macintosh program), or otherwise unsuitable, you  can  replace  it
+    with  BGET.  Initially define a buffer pool of an appropriate size
+    with bpool()--usually obtained by making a call to	the  operating
+    system's  low-level  memory allocator.  Then allocate buffers with
+    bget(), bgetz(), and bgetr() (the last two permit  the  allocation
+    of	buffers initialised to zero and [inefficient] re-allocation of
+    existing buffers for  compatibility  with  C  library  functions).
+    Release buffers by calling brel().	If a buffer allocation request
+    fails, obtain more storage from the underlying  operating  system,
+    add it to the buffer pool by another call to bpool(), and continue
+    execution.
+
+    Automatic Storage Management
+    ----------------------------
+
+    You can use BGET as your application's native memory  manager  and
+    implement  automatic  storage  pool  expansion,  contraction,  and
+    optionally application-specific  memory  compaction  by  compiling
+    BGET  with	the  BECtl  variable defined, then calling bectl() and
+    supplying  functions  for  storage	compaction,  acquisition,  and
+    release,  as  well as a standard pool expansion increment.	All of
+    these functions are optional (although it doesn't make much  sense
+    to	provide  a  release  function without an acquisition function,
+    does it?).	Once the call-back functions have  been  defined  with
+    bectl(),  you simply use bget() and brel() to allocate and release
+    storage as before.	You can supply an  initial  buffer  pool  with
+    bpool()  or  rely  on  automatic  allocation to acquire the entire
+    pool.  When a call on  bget()  cannot  be  satisfied,  BGET  first
+    checks  if	a compaction function has been supplied.  If so, it is
+    called (with the space required to satisfy the allocation  request
+    and a sequence number to allow the compaction routine to be called
+    successively without looping).  If the compaction function is able
+    to  free any storage (it needn't know whether the storage it freed
+    was adequate) it should return a  nonzero  value,  whereupon  BGET
+    will retry the allocation request and, if it fails again, call the
+    compaction function again with the next-higher sequence number.
+
+    If	the  compaction  function  returns zero, indicating failure to
+    free space, or no compaction function is defined, BGET next  tests
+    whether  a	non-NULL  allocation function was supplied to bectl().
+    If so, that function is called with  an  argument  indicating  how
+    many  bytes  of  additional  space are required.  This will be the
+    standard pool expansion increment supplied in the call to  bectl()
+    unless  the  original  bget()  call requested a buffer larger than
+    this; buffers larger than the standard pool block can  be  managed
+    "off  the books" by BGET in this mode.  If the allocation function
+    succeeds in obtaining the storage, it returns a pointer to the new
+    block  and	BGET  expands  the  buffer  pool;  if  it  fails,  the
+    allocation request fails and returns NULL to  the  caller.	 If  a
+    non-NULL  release  function  is  supplied,	expansion blocks which
+    become totally empty are released  to  the	global	free  pool  by
+    passing their addresses to the release function.
+
+    Equipped  with  appropriate  allocation,  release,	and compaction
+    functions, BGET can be used as part of very  sophisticated	memory
+    management	 strategies,  including  garbage  collection.	(Note,
+    however, that BGET is *not* a garbage  collector  by  itself,  and
+    that  developing  such a system requires much additional logic and
+    careful design of the application's memory allocation strategy.)
+
+
+    BGET FUNCTION DESCRIPTIONS
+    ==========================
+
+    Functions implemented in this file (some are enabled by certain of
+    the optional settings below):
+
+	    void bpool(void *buffer, bufsize len);
+
+    Create a buffer pool of <len> bytes, using the storage starting at
+    <buffer>.	You  can  call	bpool()  subsequently  to   contribute
+    additional storage to the overall buffer pool.
+
+	    void *bget(bufsize size);
+
+    Allocate  a  buffer of <size> bytes.  The address of the buffer is
+    returned, or NULL if insufficient memory was available to allocate
+    the buffer.
+
+	    void *bgetz(bufsize size);
+
+    Allocate a buffer of <size> bytes and clear it to all zeroes.  The
+    address of the buffer is returned, or NULL if insufficient	memory
+    was available to allocate the buffer.
+
+	    void *bgetr(void *buffer, bufsize newsize);
+
+    Reallocate a buffer previously allocated by bget(),  changing  its
+    size  to  <newsize>  and  preserving  all  existing data.  NULL is
+    returned if insufficient memory is	available  to  reallocate  the
+    buffer, in which case the original buffer remains intact.
+
+	    void brel(void *buf);
+
+    Return  the  buffer  <buf>, previously allocated by bget(), to the
+    free space pool.
+
+	    void bectl(int (*compact)(bufsize sizereq, int sequence),
+		       void *(*acquire)(bufsize size),
+		       void (*release)(void *buf),
+		       bufsize pool_incr);
+
+    Expansion control: specify functions through which the package may
+    compact  storage  (or  take  other	appropriate  action)  when  an
+    allocation	request  fails,  and  optionally automatically acquire
+    storage for expansion blocks  when	necessary,  and  release  such
+    blocks when they become empty.  If <compact> is non-NULL, whenever
+    a buffer allocation request fails, the <compact> function will  be
+    called with arguments specifying the number of bytes (total buffer
+    size,  including  header  overhead)  required   to	 satisfy   the
+    allocation request, and a sequence number indicating the number of
+    consecutive  calls	on  <compact>  attempting  to	satisfy   this
+    allocation	request.   The sequence number is 1 for the first call
+    on <compact> for a given allocation  request,  and	increments  on
+    subsequent	calls,	permitting  the  <compact>  function  to  take
+    increasingly dire measures in an attempt to free up  storage.   If
+    the  <compact>  function  returns  a nonzero value, the allocation
+    attempt is re-tried.  If <compact> returns 0 (as  it  must	if  it
+    isn't  able  to  release  any  space  or add storage to the buffer
+    pool), the allocation request fails, which can  trigger  automatic
+    pool expansion if the <acquire> argument is non-NULL.  At the time
+    the  <compact>  function  is  called,  the	state  of  the	buffer
+    allocator  is  identical  to  that	at  the  moment the allocation
+    request was made; consequently, the <compact>  function  may  call
+    brel(), bpool(), bstats(), and/or directly manipulate  the	buffer
+    pool  in  any  manner which would be valid were the application in
+    control.  This does not, however, relieve the  <compact>  function
+    of the need to ensure that whatever actions it takes do not change
+    things   underneath  the  application  that  made  the  allocation
+    request.  For example, a <compact> function that released a buffer
+    in	the  process  of  being reallocated with bgetr() would lead to
+    disaster.  Implementing a safe and effective  <compact>  mechanism
+    requires  careful  design of an application's memory architecture,
+    and cannot generally be easily retrofitted into existing code.
+
+    If <acquire> is non-NULL, that function will be called whenever an
+    allocation	request  fails.  If the <acquire> function succeeds in
+    allocating the requested space and returns a pointer  to  the  new
+    area,  allocation will proceed using the expanded buffer pool.  If
+    <acquire> cannot obtain the requested space, it should return NULL
+    and   the	entire	allocation  process  will  fail.   <pool_incr>
+    specifies the normal expansion block size.	Providing an <acquire>
+    function will cause subsequent bget()  requests  for  buffers  too
+    large  to  be  managed in the linked-block scheme (in other words,
+    larger than <pool_incr> minus the buffer overhead) to be satisfied
+    directly by calls to the <acquire> function.  Automatic release of
+    empty pool blocks will occur only if all pool blocks in the system
+    are the size given by <pool_incr>.
+
+	    void bstats(bufsize *curalloc, bufsize *totfree,
+			bufsize *maxfree, long *nget, long *nrel);
+
+    The amount	of  space  currently  allocated  is  stored  into  the
+    variable  pointed  to by <curalloc>.  The total free space (sum of
+    all free blocks in the pool) is stored into the  variable  pointed
+    to	by  <totfree>, and the size of the largest single block in the
+    free space	pool  is  stored  into	the  variable  pointed	to  by
+    <maxfree>.	 The  variables  pointed  to  by <nget> and <nrel> are
+    filled, respectively, with	the  number  of  successful  (non-NULL
+    return) bget() calls and the number of brel() calls.
+
+	    void bstatse(bufsize *pool_incr, long *npool,
+			 long *npget, long *nprel,
+			 long *ndget, long *ndrel);
+
+    Extended  statistics: The expansion block size will be stored into
+    the variable pointed to by <pool_incr>, or the negative thereof if
+    automatic  expansion  block  releases are disabled.  The number of
+    currently active pool blocks will  be  stored  into  the  variable
+    pointed  to  by  <npool>.  The variables pointed to by <npget> and
+    <nprel> will be filled with, respectively, the number of expansion
+    block   acquisitions   and	releases  which  have  occurred.   The
+    variables pointed to by <ndget> and <ndrel> will  be  filled  with
+    the  number  of  bget()  and  brel()  calls, respectively, managed
+    through blocks directly allocated by the acquisition  and  release
+    functions.
+
+	    int bpoolv(void *pool);
+
+    The  named	buffer	pool,  previously  initialised	by  a  call on
+    bpool(), is validated for bad pointers, overwritten data, etc.  If
+    compiled with NDEBUG not defined, any error generates an assertion
+    failure.  Otherwise 1 is returned if the pool is valid,  0	if  an
+    error is found.
+
+
+    BGET CONFIGURATION
+    ==================
+*/
+
+#define SizeQuant   4		      /* Buffer allocation size quantum:
+					 all buffers allocated are a
+					 multiple of this size.  This
+					 MUST be a power of two. */
+
+
+#define BufValid    1		      /* Define this symbol to enable the
+					 bpoolv() function for validating
+					 a buffer pool. */ 
+
+#define BufStats    1		      /* Define this symbol to enable the
+					 bstats() function which calculates
+					 the total free space in the buffer
+					 pool, the largest available
+					 buffer, and the total space
+					 currently allocated. */
+
+#define FreeWipe    1		      /* Wipe free buffers to a guaranteed
+					 pattern of garbage to trip up
+					 miscreants who attempt to use
+					 pointers into released buffers. */
+
+#define BestFit     1		      /* Use a best fit algorithm when
+					 searching for space for an
+					 allocation request.  This uses
+					 memory more efficiently, but
+					 allocation will be much slower. */
+
+#define BECtl	    1		      /* Define this symbol to enable the
+					 bectl() function for automatic
+					 pool space control.  */
+
+
+#ifdef lint
+#define NDEBUG			      /* Exits in asserts confuse lint */
+/* LINTLIBRARY */                     /* Don't complain about def, no ref */
+#endif
+
+
+/*  Declare the interface, including the requested buffer size type,
+    bufsize.  */
+
+#include "bget.h"
+
+
+
+
+static struct bfhead freelist = {     /* List of free buffers */
+    {0, 0},
+    {&freelist, &freelist}
+};
+
+#ifdef BufStats
+static bufsize totalloc = 0;	      /* Total space currently allocated */
+static int32_t numget = 0, numrel = 0;   /* Number of bget() and brel() calls */
+#ifdef BECtl
+static int32_t numpblk = 0;	      /* Number of pool blocks */
+static int32_t numpget = 0, numprel = 0; /* Number of block gets and rels */
+static int32_t numdget = 0, numdrel = 0; /* Number of direct gets and rels */
+#endif /* BECtl */
+#endif /* BufStats */
+
+#ifdef BECtl
+
+/* Automatic expansion block management functions */
+
+static int32_t (*compfcn) (bufsize sizereq, int32_t sequence) = NULL;
+static void *(*acqfcn) (bufsize size) = NULL;
+static void (*relfcn) (void *buf) = NULL;
+
+static bufsize exp_incr = 0;	      /* Expansion block size */
+static bufsize pool_len = 0;	      /* 0: no bpool calls have been made
+										-1: not all pool blocks are
+										the same size
+										>0: (common) block size for all
+										bpool calls made so far
+										*/
+#endif
+
+/*  Minimum allocation quantum: */
+
+#define QLSize	(sizeof(struct qlinks))
+#define SizeQ	((SizeQuant > QLSize) ? SizeQuant : QLSize)
+
+#define V   (void)		      /* To denote unwanted returned values */
+
+/* End sentinel: value placed in bsize field of dummy block delimiting
+   end of pool block.  The most negative number which will  fit  in  a
+   bufsize, defined in a way that the compiler will accept. */
+
+#define ESent	((bufsize) (-(((1L << ((sizeof(bufsize) * 8) - 2)) - 1) * 2) - 2))
+
+/*  BGET  --  Allocate a buffer.  */
+
+void *bget(bufsize requested_size)
+{
+    uint32_t size = (uint32_t)requested_size;
+    struct bfhead *b;
+
+#ifdef BestFit
+    struct bfhead *best;
+#endif
+
+    void *buf = NULL;
+
+#ifdef BECtl
+    int32_t compactseq = 0;
+	int8_t acquireLoop = 1; /* boolean used for first while loop control */
+	int8_t BECtlLoop = 1; /* boolean used for second while loop control */
+#endif
+
+	int32_t compfcnResult = 0; /* used to store compfcn call result */
+	int32_t foundBuffer = 0; /* Boolean indicating if we found a buffer. */
+	                     /* It is used to avoid multiple calls to return, */
+						 /* which is not MISRA compliant */
+
+#ifdef BECtl
+    /* If an acquire function was provided in the call to bectl(), wrap
+       a loop around the allocation process  to  allow	acquire  to
+       intervene in case we don't find a suitable buffer in the chain. */
+
+    while (acquireLoop != 0) {
+	acquireLoop = 0;
+#endif
+
+    assert(size > 0);
+
+    if (size < SizeQ) { 	      /* Need at least room for the */
+		size = SizeQ;		      /*    queue links.  */
+    }
+
+#ifdef SizeQuant
+#if SizeQuant > 1
+    size = (size + ((uint32_t)SizeQuant - 1)) & (~((uint32_t)SizeQuant - 1));
+#endif
+#endif
+
+    size += sizeof(struct bhead);     /* Add overhead in allocated buffer
+					 to size required. */
+
+#ifdef BECtl
+    /* If a compact function was provided in the call to bectl(), wrap
+       a loop around the allocation process  to  allow	compaction  to
+       intervene in case we don't find a suitable buffer in the chain. */
+
+    while (BECtlLoop != 0) {
+#endif
+
+		b = freelist.ql.flink;
+
+#ifdef BestFit
+		best = &freelist;
+#endif
+
+		/* Scan the free list searching for the first buffer big enough
+		   to hold the requested size buffer. */
+
+#ifdef BestFit
+		while (b != &freelist) {
+			if (b->bh.bsize >= (int32_t)size) {
+				if ((best == &freelist) || (b->bh.bsize < best->bh.bsize)) {
+					best = b;
+				}
+			}
+			b = b->ql.flink;		  /* Link to next buffer */
+		}
+		b = best;
+#endif /* BestFit */
+
+		while ((b != &freelist) && (foundBuffer == 0)) {
+			if ((bufsize) b->bh.bsize >= (int32_t)size) {
+
+				/* Buffer  is big enough to satisfy  the request.  Allocate it
+				   to the caller.  We must decide whether the buffer is  large
+				   enough  to  split  into  the part given to the caller and a
+				   free buffer that remains on the free list, or  whether  the
+				   entire  buffer  should  be  removed	from the free list and
+				   given to the caller in its entirety.   We  only  split  the
+				   buffer if enough room remains for a header plus the minimum
+				   quantum of allocation. */
+
+				if ((b->bh.bsize - (int32_t)size) > (int32_t)(SizeQ + (sizeof(struct bhead)))) {
+					struct bhead *ba, *bn;
+
+					ba = BH(getPointerOffset(b, (b->bh.bsize - (bufsize)size)));
+					bn = BH(getPointerOffset(ba, (int32_t)size));
+					assert(bn->prevfree == b->bh.bsize);
+					/* Subtract size from length of free block. */
+					b->bh.bsize -= (bufsize)size;
+					/* Link allocated buffer to the previous free buffer. */
+					ba->prevfree = b->bh.bsize;
+					/* Plug negative size into user buffer. */
+					ba->bsize = -(bufsize) size;
+					/* Mark buffer after this one not preceded by free block. */
+					bn->prevfree = 0;
+
+#ifdef BufStats
+					totalloc += (int32_t)size;
+					numget++;		  /* Increment number of bget() calls */
+#endif
+					buf = (void *) getPointerOffset(ba, sizeof(struct bhead));
+					foundBuffer = 1;
+				} else {
+					struct bhead *ba;
+
+					ba = BH(getPointerOffset(b, b->bh.bsize));
+					assert(ba->prevfree == b->bh.bsize);
+
+							/* The buffer isn't big enough to split.  Give  the  whole
+					   shebang to the caller and remove it from the free list. */
+
+					assert(b->ql.blink->ql.flink == b);
+					assert(b->ql.flink->ql.blink == b);
+					b->ql.blink->ql.flink = b->ql.flink;
+					b->ql.flink->ql.blink = b->ql.blink;
+
+#ifdef BufStats
+					totalloc += b->bh.bsize;
+					numget++;		  /* Increment number of bget() calls */
+#endif
+
+					/* Negate size to mark buffer allocated. */
+					b->bh.bsize = -(b->bh.bsize);
+
+					/* Zero the back pointer in the next buffer in memory
+					   to indicate that this buffer is allocated. */
+					ba->prevfree = 0;
+
+					/* Give user buffer starting at queue links. */
+					buf =  (void *) &(b->ql);
+					foundBuffer = 1;
+				}
+			}
+			if (foundBuffer == 0) {
+				b = b->ql.flink;		  /* Link to next buffer */
+			}
+		}
+
+#ifdef BECtl
+
+		if (foundBuffer == 0 ) {
+			/* We failed to find a buffer.  If there's a compact  function
+		   defined,  notify  it  of the size requested.  If it returns
+		   TRUE, try the allocation again. */
+
+			compactseq++;
+			if (compfcn != NULL) {
+				compfcnResult = (*compfcn)((bufsize)size, compactseq);
+			}
+			if ((compfcn == NULL) || (compfcnResult == 0)) {
+				BECtlLoop = 0;
+			}
+		}
+		else {
+			BECtlLoop = 0;
+		}
+    }
+	
+	if (foundBuffer == 0 ) {
+
+		/* No buffer available with requested size free. */
+
+		/* Don't give up yet -- look in the reserve supply. */
+
+		if (acqfcn != NULL) {
+			if ((int32_t)size > (exp_incr - (int32_t)sizeof(struct bhead))) {
+
+				/* Request	is  too  large	to  fit in a single expansion
+				   block.  Try to satisy it by a direct buffer acquisition. */
+
+				struct bdhead *bdh;
+
+				size += (sizeof(struct bdhead) - sizeof(struct bhead));
+				bdh = BDH((*acqfcn)((bufsize) size));
+				if (bdh != NULL) {
+
+					/*  Mark the buffer special by setting the size field
+						of its header to zero.  */
+					bdh->bh.bsize = 0;
+					bdh->bh.prevfree = 0;
+					bdh->tsize = (bufsize)size;
+
+#ifdef BufStats
+					totalloc += (int32_t)size;
+					numget++;	      /* Increment number of bget() calls */
+					numdget++;	      /* Direct bget() call count */
+#endif /* Bufstats */
+
+					buf =  (void *) getPointerOffset(bdh,1);
+				}
+
+			} else {
+
+				/*	Try to obtain a new expansion block */
+
+				void *newpool;
+				newpool = (*acqfcn)((bufsize) exp_incr);
+				if (newpool != NULL) {
+					bpool(newpool, exp_incr);
+					acquireLoop = 1;
+				}
+			}
+		}
+	}
+    /*	Still no buffer available */
+	}
+
+#endif /* BECtl */
+
+    return buf;
+}
+
+/*  BGETZ  --  Allocate a buffer and clear its contents to zero.  We clear
+	       the  entire  contents  of  the buffer to zero, not just the
+	       region requested by the caller. */
+
+void *bgetz(bufsize size)
+{
+    int8_t *buf = (int8_t *) bget(size);
+
+    if (buf != NULL) {
+	struct bhead *b;
+	bufsize rsize;
+
+	b = BH(getPointerOffset(buf, -(int32_t)sizeof(struct bhead)));
+	rsize = -(b->bsize);
+	if (rsize == 0) {
+	    struct bdhead *bd;
+
+	    bd = BDH(getPointerOffset(buf, -(int32_t)sizeof(struct bdhead)));
+	    rsize = bd->tsize - (int32_t)sizeof(struct bdhead);
+	} else {
+	    rsize -= (int32_t)sizeof(struct bhead);
+	}
+	assert(rsize >= size);
+	V memset(buf, 0, (MemSize) rsize);
+    }
+    return ((void *) buf);
+}
+
+/*  BGETR  --  Reallocate a buffer.  This is a minimal implementation,
+	       simply in terms of brel()  and  bget().	 It  could  be
+	       enhanced to allow the buffer to grow into adjacent free
+	       blocks and to avoid moving data unnecessarily.  */
+
+void *bgetr(void *buf, bufsize size)
+{
+    void *nbuf;
+    bufsize osize;		      /* Old size of buffer */
+    struct bhead *b;
+
+	nbuf = bget(size);
+    if ((nbuf != NULL) && (buf != NULL)) { /* Acquire new buffer */
+	
+		b = BH(getPointerOffset(buf, -(int32_t)sizeof(struct bhead)));
+		osize = -b->bsize;
+#ifdef BECtl
+		if (osize == 0) {
+		/*  Buffer acquired directly through acqfcn. */
+		struct bdhead *bd;
+
+		bd = BDH(getPointerOffset(buf, -(int32_t)sizeof(struct bdhead)));
+		osize = bd->tsize - (int32_t)sizeof(struct bdhead);
+		} else{
+#endif
+		osize -= (int32_t)sizeof(struct bhead);
+#ifdef BECtl
+		}
+#endif
+		assert(osize > 0);
+		V memcpy((int8_t *) nbuf, (int8_t *) buf, /* Copy the data */
+			 (MemSize) ((size < osize) ? size : osize));
+		brel(buf);
+    
+	}
+	
+	return nbuf;
+}
+
+/*  BREL  --  Release a buffer.  */
+
+void brel(void *buf)
+{
+    struct bfhead *b, *bn;
+
+    b = BFH(getPointerOffset(buf, -(int32_t)sizeof(struct bhead)));
+	
+#ifdef BufStats
+    numrel++;			      /* Increment number of brel() calls */
+#endif
+
+    assert(buf != NULL);
+
+#ifdef BECtl
+    if (b->bh.bsize == 0) {	      /* Directly-acquired buffer? */
+	struct bdhead *bdh;
+
+	bdh = BDH(getPointerOffset(buf, -(int32_t)sizeof(struct bdhead)));
+	assert(b->bh.prevfree == 0);
+	
+#ifdef BufStats
+	totalloc -= bdh->tsize;
+	assert(totalloc >= 0);
+	numdrel++;		      /* Number of direct releases */
+#endif /* BufStats */
+
+#ifdef FreeWipe
+	V memset((int8_t *) buf, 0x55,
+		 (MemSize) (bdh->tsize - (int32_t)sizeof(struct bdhead)));
+#endif /* FreeWipe */
+
+	assert(relfcn != NULL);
+	(*relfcn)((void *) bdh);      /* Release it directly. */
+    } else {
+#endif /* BECtl */
+
+    /* Buffer size must be negative, indicating that the buffer is
+       allocated. */
+
+    if (b->bh.bsize >= 0) {
+	bn = NULL;
+    }
+    assert(b->bh.bsize < 0);
+
+    /*	Back pointer in next buffer must be zero, indicating the
+	same thing: */
+
+    assert(BH((int8_t *) b - b->bh.bsize)->prevfree == 0);
+
+#ifdef BufStats
+    totalloc += b->bh.bsize;
+    assert(totalloc >= 0);
+#endif
+
+    /* If the back link is nonzero, the previous buffer is free.  */
+
+    if (b->bh.prevfree != 0) {
+
+	/* The previous buffer is free.  Consolidate this buffer  with	it
+	   by  adding  the  length  of	this  buffer  to the previous free
+	   buffer.  Note that we subtract the size  in	the  buffer  being
+           released,  since  it's  negative to indicate that the buffer is
+	   allocated. */
+
+	register bufsize size = b->bh.bsize;
+
+        /* Make the previous buffer the one we're working on. */
+	assert(BH(b - b->bh.prevfree)->bsize == b->bh.prevfree);
+	b = BFH(getPointerOffset(b, -b->bh.prevfree));
+	b->bh.bsize -= size;
+    } else {
+
+        /* The previous buffer isn't allocated.  Insert this buffer
+	   on the free list as an isolated free block. */
+
+	assert(freelist.ql.blink->ql.flink == &freelist);
+	assert(freelist.ql.flink->ql.blink == &freelist);
+	b->ql.flink = &freelist;
+	b->ql.blink = freelist.ql.blink;
+	freelist.ql.blink = b;
+	b->ql.blink->ql.flink = b;
+	b->bh.bsize = -b->bh.bsize;
+    }
+
+    /* Now we look at the next buffer in memory, located by advancing from
+       the  start  of  this  buffer  by its size, to see if that buffer is
+       free.  If it is, we combine  this  buffer  with	the  next  one	in
+       memory, dechaining the second buffer from the free list. */
+
+    bn =  BFH(getPointerOffset(b, b->bh.bsize));
+    if (bn->bh.bsize > 0) {
+
+	/* The buffer is free.	Remove it from the free list and add
+	   its size to that of our buffer. */
+
+	assert(BH(bn + bn->bh.bsize)->prevfree == bn->bh.bsize);
+	assert(bn->ql.blink->ql.flink == bn);
+	assert(bn->ql.flink->ql.blink == bn);
+	bn->ql.blink->ql.flink = bn->ql.flink;
+	bn->ql.flink->ql.blink = bn->ql.blink;
+	b->bh.bsize += bn->bh.bsize;
+
+	/* Finally,  advance  to   the	buffer	that   follows	the  newly
+	   consolidated free block.  We must set its  backpointer  to  the
+	   head  of  the  consolidated free block.  We know the next block
+	   must be an allocated block because the process of recombination
+	   guarantees  that  two  free	blocks will never be contiguous in
+	   memory.  */
+
+	bn = BFH(getPointerOffset(b, b->bh.bsize));
+    }
+	
+#ifdef FreeWipe
+    V memset(getPointerOffset(b, sizeof(struct bfhead)), 0x55,
+	    (MemSize) (b->bh.bsize - (int32_t)sizeof(struct bfhead)));
+#endif
+
+    assert(bn->bh.bsize < 0);
+
+    /* The next buffer is allocated.  Set the backpointer in it  to  point
+       to this buffer; the previous free buffer in memory. */
+
+    bn->bh.prevfree = b->bh.bsize;
+
+#ifdef BECtl
+
+    /*	If  a  block-release function is defined, and this free buffer
+	constitutes the entire block, release it.  Note that  pool_len
+	is  defined  in  such a way that the test will fail unless all
+	pool blocks are the same size.	*/
+
+    if ((relfcn != NULL) &&
+	(((bufsize) b->bh.bsize) == (pool_len - (int32_t)sizeof(struct bhead)))) {
+
+	assert(b->bh.prevfree == 0);
+	assert(BH(b + b->bh.bsize)->bsize == ESent);
+	assert(BH(b + b->bh.bsize)->prevfree == b->bh.bsize);
+	/*  Unlink the buffer from the free list  */
+	b->ql.blink->ql.flink = b->ql.flink;
+	b->ql.flink->ql.blink = b->ql.blink;
+
+	(*relfcn)(b);
+#ifdef BufStats
+	numprel++;		      /* Nr of expansion block releases */
+	numpblk--;		      /* Total number of blocks */
+	assert(numpblk == numpget - numprel);
+#endif /* BufStats */
+    }
+	}
+#endif /* BECtl */
+}
+
+#ifdef BECtl
+
+/*  BECTL  --  Establish automatic pool expansion control  */
+
+void bectl(int32_t (*compact) (bufsize sizereq, int32_t sequence),
+			void *(*acquire) (bufsize size),
+			void (*release) (void *buf),
+			bufsize pool_incr)
+{
+    compfcn = compact;
+    acqfcn = acquire;
+    relfcn = release;
+    exp_incr = pool_incr;
+}
+#endif
+
+/*  BPOOL  --  Add a region of memory to the buffer pool.  */
+
+void bpool(void *buf, bufsize length)
+{
+    struct bfhead *b = BFH(buf);
+    struct bhead *bn;
+	uint32_t len = (uint32_t)length;
+
+#ifdef SizeQuant
+    len &= ~((uint32_t)SizeQuant - 1);
+#endif
+
+#ifdef BECtl
+    if (pool_len == 0) {
+	pool_len = (int32_t)len;
+    } else if ((int32_t)len != pool_len) {
+	pool_len = -1;
+    }
+	else {
+		/* this else statement is just here for MISRA compliance */
+	}
+
+#ifdef BufStats
+    numpget++;			      /* Number of block acquisitions */
+    numpblk++;			      /* Number of blocks total */
+    assert(numpblk == (numpget - numprel));
+#endif /* BufStats */
+
+#endif /* BECtl */
+
+    /* Since the block is initially occupied by a single free  buffer,
+       it  had	better	not  be  (much) larger than the largest buffer
+       whose size we can store in bhead.bsize. */
+
+    assert((len - sizeof(struct bhead)) <= -((bufsize) ESent + 1));
+
+    /* Clear  the  backpointer at  the start of the block to indicate that
+       there  is  no  free  block  prior  to  this   one.    That   blocks
+       recombination when the first block in memory is released. */
+
+    b->bh.prevfree = 0;
+
+    /* Chain the new block to the free list. */
+
+    assert(freelist.ql.blink->ql.flink == &freelist);
+    assert(freelist.ql.flink->ql.blink == &freelist);
+    b->ql.flink = &freelist;
+    b->ql.blink = freelist.ql.blink;
+    freelist.ql.blink = b;
+    b->ql.blink->ql.flink = b;
+
+    /* Create a dummy allocated buffer at the end of the pool.	This dummy
+       buffer is seen when a buffer at the end of the pool is released and
+       blocks  recombination  of  the last buffer with the dummy buffer at
+       the end.  The length in the dummy buffer  is  set  to  the  largest
+       negative  number  to  denote  the  end  of  the pool for diagnostic
+       routines (this specific value is  not  counted  on  by  the  actual
+       allocation and release functions). */
+
+    len -= (int32_t)sizeof(struct bhead);
+    b->bh.bsize = (bufsize) len;
+#ifdef FreeWipe
+    V memset(getPointerOffset(b,sizeof(struct bfhead)), 0x55,
+	     (MemSize) (len - (int32_t)sizeof(struct bfhead)));
+#endif
+    bn = BH(getPointerOffset(b,(int32_t)len));
+    bn->prevfree = (bufsize) len;
+    /* Definition of ESent assumes two's complement! */
+    assert((~0) == -1);
+    bn->bsize = ESent;
+}
+
+#ifdef BufStats
+
+/*  BSTATS  --	Return buffer allocation free space statistics.
+	NULL shall not be passed to this function.  */
+
+void bstats(bufsize *curalloc, bufsize *totfree, bufsize *maxfree, int32_t *nget, int32_t *nrel)
+{
+    struct bfhead *b = freelist.ql.flink;
+
+    *nget = numget;
+    *nrel = numrel;
+    *curalloc = totalloc;
+    *totfree = 0;
+    *maxfree = -1;
+    while (b != &freelist) {
+	assert(b->bh.bsize > 0);
+	*totfree += b->bh.bsize;
+	if (b->bh.bsize > *maxfree) {
+	    *maxfree = b->bh.bsize;
+	}
+	b = b->ql.flink;	      /* Link to next buffer */
+    }
+}
+
+#ifdef BECtl
+
+/*  BSTATSE  --  Return extended statistics  */
+
+void bstatse(bufsize *pool_incr, int32_t *npool, int32_t *npget, int32_t *nprel, int32_t *ndget, int32_t *ndrel)
+{
+    *pool_incr = (pool_len < 0) ? -exp_incr : exp_incr;
+    *npool = numpblk;
+    *npget = numpget;
+    *nprel = numprel;
+    *ndget = numdget;
+    *ndrel = numdrel;
+}
+#endif /* BECtl */
+#endif /* BufStats */
+
+#ifdef BufValid
+
+/*  BPOOLV  --  Validate a buffer pool.  If NDEBUG isn't defined,
+		any error generates an assertion failure. */
+
+int32_t bpoolv(void* buf)
+{
+#ifdef FreeWipe
+	int32_t memResult;
+	int32_t returnValue = 1;
+#endif
+	int8_t loop = 1;
+    struct bfhead *b = BFH(buf);
+
+    while ((b->bh.bsize != ESent) && (loop != 0)) {
+		bufsize bs = b->bh.bsize;
+
+		if (bs < 0) {
+			bs = -bs;
+		} else {
+				int8_t *lerr = (int8_t *)"";
+
+			assert(bs > 0);
+			if (bs <= 0) {
+				returnValue = 0;
+				loop = 0;
+			} else if ((b->ql.blink->ql.flink != b) || (b->ql.flink->ql.blink != b)) {
+				assert(0);
+				returnValue = 0;
+				loop = 0;
+			} else {
+#ifdef FreeWipe
+				lerr = getPointerOffset(b, sizeof(struct bfhead));
+				memResult = memcmp(lerr, getPointerOffset(lerr,1), (MemSize) (bs - (int32_t)(sizeof(struct bfhead) + 1)));
+				if ((bs > (int32_t)sizeof(struct bfhead)) && ((*lerr != 0x55) || (memResult != 0))) {
+					assert(0);
+					returnValue = 0;
+					loop = 0;
+				}
+#endif
+			}
+		}
+		if (returnValue != 0) {
+			b = BFH(getPointerOffset(b,bs));
+		}
+    }
+    return returnValue;
+}
+#endif /* BufValid */
+
+/* cast functions */
+struct bhead* BH (void *p) {
+	return (struct bhead *)p;
+}
+
+struct bdhead* BDH (void *p) {
+	return (struct bdhead *)p;
+}
+
+struct bfhead* BFH (void *p) {
+	return (struct bfhead *)p;
+}
+
+/*  GETPOINTEROFFSET  --  returns a pointer whose value is p + offset.
+	Avoids pointer arithmetic */
+
+int8_t* getPointerOffset(void *p, int32_t offset) {
+	return &(((int8_t*)p)[offset]);
+}
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/mem_allocator/bget.h b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/mem_allocator/bget.h
new file mode 100644
index 0000000000000000000000000000000000000000..fdfa849615b5bc64d6aefe4a231eafaa276ac375
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/mem_allocator/bget.h
@@ -0,0 +1,71 @@
+#ifndef _BGET_H
+#define _BGET_H
+
+#ifndef NDEBUG
+#define NDEBUG /* disable assertions */
+#endif
+
+#include <assert.h>
+#include <string.h>
+#include "stdint.h"
+
+#define MemSize     uint32_t			/* Type for size arguments to memxxx()
+								functions such as memcmp(). */
+
+typedef int32_t bufsize;
+
+/* Queue links */
+
+struct qlinks {
+    struct bfhead *flink;	      /* Forward link */
+    struct bfhead *blink;	      /* Backward link */
+};
+
+/* Header in allocated and free buffers */
+
+struct bhead {
+    bufsize prevfree;			/* Relative link back to previous
+								free buffer in memory or 0 if
+								previous buffer is allocated.	*/
+    bufsize bsize;	/* Buffer size: positive if free,
+					negative if allocated. */
+};
+
+/*  Header in directly allocated buffers (by acqfcn) */
+
+struct bdhead {
+    bufsize tsize;		      /* Total size, including overhead */
+    struct bhead bh;		      /* Common header */
+};
+
+/* Header in free buffers */
+
+struct bfhead {
+    struct bhead bh;		      /* Common allocated/free header */
+    struct qlinks ql;		      /* Links on free list */
+};
+
+
+void bpool(void *buf, bufsize length);
+void *bget(bufsize requested_size);
+void *bgetz(bufsize size);
+void *bgetr(void *buf, bufsize size);
+void brel(void *buf);
+void bectl(int32_t (*compact)(bufsize sizereq, int32_t sequence),
+				void *(*acquire)(bufsize size),
+				void (*release)(void *buf), bufsize pool_incr);
+void bstats(bufsize *curalloc, bufsize *totfree, bufsize *maxfree,
+				int32_t *nget, int32_t *nrel);
+void bstatse(bufsize *pool_incr, int32_t *npool, int32_t *npget,
+				int32_t *nprel, int32_t *ndget, int32_t *ndrel);
+int32_t	bpoolv(void* buf);
+
+/* cast functions */
+struct bhead* BH (void *p);
+struct bdhead* BDH (void *p);
+struct bfhead* BFH (void *p);
+
+/* this function is used for MISRA compliancy, it avoids pointer arithmetic */
+int8_t* getPointerOffset(void *p, int32_t offset);
+
+#endif /* _BGET_H */
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/mem_allocator/pn532_mem.c b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/mem_allocator/pn532_mem.c
new file mode 100644
index 0000000000000000000000000000000000000000..bfcd536c82198619d5c244aa740b83f4c8190976
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/mem_allocator/pn532_mem.c
@@ -0,0 +1,148 @@
+/**************************************************************************/
+/*!
+    @file pn532_mem.c
+
+    @brief Define the memory allocation interface within the PN532 NFC
+    library.  This module uses bget for memory management by default, but
+    it can be ported to any other memory management by keeping the same
+    interface.
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013 Adafruit Industries (www.adafruit.com)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+// #ifdef CFG_PN532
+
+#include "../pn532.h"
+#include "pn532_mem.h"
+
+/* Memory pool for dynamic memory allocator */
+static uint32_t _pn532_mem_pool[CFG_PN532_MEM_POOL_SIZE_BYTES/4];
+static bool     _pn532_mem_initialised = FALSE;
+
+/**************************************************************************/
+/*!
+    Initialises the memory management block using internal memory pool.
+    This function needs to be called when the system starts up.
+
+    @param  none
+
+    @note   A buffer needs to be statically allocated or a memory mapped
+            area used. If a memory area is used, make sure it is free.
+*/
+/**************************************************************************/
+pn532_error_t pn532_mem_initLocal(void)
+{
+  bpool((void*)_pn532_mem_pool, (bufsize)(sizeof(_pn532_mem_pool)));
+  _pn532_mem_initialised = TRUE;
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    Initialises the memory management block.  This function need to be
+    called when the system starts up.
+
+    @param  mem_pool  Memory pool to pass to the memory management module
+    @param  pool_size Size of the pool
+
+    @note   A buffer needs to be statically allocated or a memory mapped
+            area used. If a memory area is used, make sure it is free.
+
+            PN532_ERROR_MEM_INVALID_PARAM is returned when mem_pool
+            input is null.
+*/
+/**************************************************************************/
+pn532_error_t pn532_mem_init(uint32_t * mem_pool, uint16_t pool_size)
+{
+  if ((!mem_pool)||(pool_size==0))
+  {
+    return PN532_ERROR_MEM_INVALID_PARAM;
+  }
+
+  bpool((void*)mem_pool, (bufsize)pool_size);
+
+  _pn532_mem_initialised = TRUE;
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    Tries to allocate a memory block with the specified input size.
+
+    @param    size  Number of byte to try to allocate
+
+    @return   null: When allocation failed
+              address of the memory: When allocation succeeded
+*/
+/**************************************************************************/
+void * pn532_mem_alloc(uint16_t size)
+{
+  void * alloc_mem = NULL;
+
+  if (!_pn532_mem_initialised)
+  {
+    pn532_mem_initLocal();
+  }
+
+  alloc_mem = bget(size);
+
+  /* Debugging: Enable this to troubleshoot if mem_pool is overrun
+   * during debugging.  This while() loop should be removed in
+   * release builds! */
+
+  // #if defined (DEBUG)
+  //   while (alloc_mem == NULL);
+  // #endif
+
+  return alloc_mem;
+}
+
+/**************************************************************************/
+/*!
+    Tries to free a pre-allocated memory block
+
+    @param  mem   The pre-allocated block to be freed
+*/
+/**************************************************************************/
+void pn532_mem_free(void* mem)
+{
+  if (_pn532_mem_initialised)
+  {
+    brel(mem);
+  }
+
+  return;
+}
+
+// #endif  // #ifdef CFG_PN532
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/mem_allocator/pn532_mem.h b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/mem_allocator/pn532_mem.h
new file mode 100644
index 0000000000000000000000000000000000000000..927b3a2965aa72c84eb07fed4340e34cf7bd37d3
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/mem_allocator/pn532_mem.h
@@ -0,0 +1,46 @@
+/**************************************************************************/
+/*!
+    @file pn532_mem.h
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013 Adafruit Industries (www.adafruit.com)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef PN532_MEM_H_
+#define PN532_MEM_H_
+
+#include "projectconfig.h"
+#include "bget.h"
+
+pn532_error_t pn532_mem_initLocal(void);
+pn532_error_t pn532_mem_init(uint32_t * mem_pool, uint16_t pool_size);
+void *        pn532_mem_alloc(uint16_t size);
+void          pn532_mem_free(void* mem);
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/pn532.c b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/pn532.c
new file mode 100644
index 0000000000000000000000000000000000000000..3a0d52d3b88b969bd137956c7cefe67620dea011
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/pn532.c
@@ -0,0 +1,219 @@
+/**************************************************************************/
+/*!
+    @file pn532.c
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_PN532
+
+#include <string.h>
+
+#include "pn532.h"
+#include "pn532_bus.h"
+#include "core/uart/uart.h"
+
+static pn532_pcb_t _pn532_pcb;
+
+/**************************************************************************/
+/*!
+    @brief  Prints a hexadecimal value in plain characters
+
+    @param  pbtData   Pointer to the byte data
+    @param  szBytes   Data length in bytes
+*/
+/**************************************************************************/
+void pn532PrintHex(const byte_t * pbtData, const size_t szBytes)
+{
+  size_t szPos;
+  for (szPos=0; szPos < szBytes; szPos++)
+  {
+    printf("%02x ", pbtData[szPos]);
+  }
+  printf(CFG_PRINTF_NEWLINE);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Prints a hexadecimal value in plain characters, along with
+            the char equivalents in the following format
+
+            AA BB CC DD EE FF  ......
+
+    @param  pbtData   Pointer to the byte data
+    @param  szBytes   Data length in bytes
+*/
+/**************************************************************************/
+void pn532PrintHexChar(const byte_t * pbtData, const size_t szBytes)
+{
+  size_t szPos;
+  for (szPos=0; szPos < szBytes; szPos++)
+  {
+    printf("%02x", pbtData[szPos]);
+  }
+  printf("  ");
+  for (szPos=0; szPos < szBytes; szPos++)
+  {
+    printf("%c", pbtData[szPos] <= 0x1F ? '.' : pbtData[szPos]);
+  }
+  printf(CFG_PRINTF_NEWLINE);
+}
+
+/**************************************************************************/
+/*!
+    @brief      Gets a reference to the PN532 peripheral control block,
+                which can be used to determine that state of the PN532
+                IC, buffers, etc.
+*/
+/**************************************************************************/
+pn532_pcb_t * pn532GetPCB()
+{
+  return &_pn532_pcb;
+}
+
+/**************************************************************************/
+/*!
+    @brief      Initialises the appropriate serial bus (UART, etc.),and
+                sets up any buffers or peripherals required by the PN532.
+*/
+/**************************************************************************/
+err_t pn532Init(void)
+{
+  err_t error;
+
+  // Clear protocol control blocks
+  memset(&_pn532_pcb, 0, sizeof(pn532_pcb_t));
+
+  // Initialise the underlying HW
+  error = pn532_bus_HWInit();
+  if (error)
+  {
+    // Something failed during init ... report the error
+    return error;
+  }
+  else
+  {
+    // Set the PCB flags to an appropriate state
+    _pn532_pcb.initialised = TRUE;
+    // Let the caller know that initialised succeeded
+    return ERROR_NONE;
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief      Reads the response buffer from the PN532
+
+    @param      pbtResponse
+                The byte array that will hold the response data
+    @param      pszLen
+                Placeholder to return the actual number of bytes read
+*/
+/**************************************************************************/
+pn532_error_t pn532Read(byte_t * pbtResponse, size_t * pszLen)
+{
+  if (!_pn532_pcb.initialised)
+  {
+    /* Warning: pn532Init uses a different error type! */
+    err_t error;
+    error = pn532Init();
+    if (error) return PN532_ERROR_UNABLETOINIT;
+  }
+
+  // Try to wake the device up if it's in sleep mode
+  if (_pn532_pcb.state == PN532_STATE_SLEEP)
+  {
+    pn532_error_t wakeupError = pn532_bus_Wakeup();
+    if (wakeupError)
+      return wakeupError;
+  }
+
+  // Read the response if the device is in an appropriate state
+  if (_pn532_pcb.state == PN532_STATE_READY)
+  {
+    return pn532_bus_ReadResponse(pbtResponse, pszLen);
+  }
+  else
+  {
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Init Failed%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return PN532_ERROR_UNABLETOINIT;
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief      Sends a byte array of command and parameter data to the
+                PN532, starting with the command byte.  The frame's
+                preamble, checksums, postamble and frame identifier (0xD4)
+                will all be automatically added.
+
+    @param      abtCommand
+                The byte array containg the command and any
+                optional parameters
+    @param      szLen
+                The number of bytes in abtCommand
+*/
+/**************************************************************************/
+pn532_error_t pn532Write(byte_t * abtCommand, size_t szLen)
+{
+  if (!_pn532_pcb.initialised)
+  {
+    /* Warning: pn532Init uses a different error type! */
+    err_t error;
+    error = pn532Init();
+    if (error) return PN532_ERROR_UNABLETOINIT;
+  }
+
+  // Try to wake the device up if it's in sleep mode
+  if (_pn532_pcb.state == PN532_STATE_SLEEP)
+  {
+    pn532_error_t error = pn532_bus_Wakeup();
+    if (error) return error;
+  }
+
+  // Send the command if the device is in an appropriate state
+  if (_pn532_pcb.state == PN532_STATE_READY)
+  {
+    return pn532_bus_SendCommand(abtCommand, szLen);
+  }
+  else
+  {
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Init Failed%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return PN532_ERROR_UNABLETOINIT;
+  }
+}
+
+#endif  // #ifdef CFG_PN532
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/pn532.h b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/pn532.h
new file mode 100644
index 0000000000000000000000000000000000000000..06114a21a8d2891e6631c8afe86fcfc0b4407a95
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/pn532.h
@@ -0,0 +1,201 @@
+/**************************************************************************/
+/*!
+    @file pn532.h
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __PN532_H__
+#define __PN532_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+// Comment out this line to disable debug output
+// #define PN532_DEBUGMODE
+#if defined PN532_DEBUGMODE
+  #define PN532_DEBUG(...)      printf(__VA_ARGS__)
+#else
+  #define PN532_DEBUG(...)
+#endif
+
+/* Error messages generated by the stack */
+/* Not to be confused with app level errors from the PN532 */
+/* These are the errors that are returned by the PN532 driver */
+typedef enum pn532_error_e
+{
+  PN532_ERROR_NONE                    = 0x00,
+  PN532_ERROR_UNABLETOINIT            = 0x01,   /**< Unable to initialise or wakeup the device */
+  PN532_ERROR_APPLEVELERROR           = 0x02,   /**< Application level error detected */
+  PN532_ERROR_BUSY                    = 0x03,   /**< Busy executing a previous command */
+  PN532_ERROR_NOACK                   = 0x04,   /**< No ack message received */
+  PN532_ERROR_INVALIDACK              = 0x05,   /**< Ack != 00 00 FF 00 FF 00 */
+  PN532_ERROR_PREAMBLEMISMATCH        = 0x06,   /**< Frame preamble + start code mismatch */
+  PN532_ERROR_EXTENDEDFRAME           = 0x07,   /**< Extended frames currently unsupported */
+  PN532_ERROR_LENCHECKSUMMISMATCH     = 0x08,
+  PN532_ERROR_RESPONSEBUFFEREMPTY     = 0x09,   /**< No response data received */
+  PN532_ERROR_READYSTATUSTIMEOUT      = 0x0A,   /**< Timeout waiting for 'ready' status (SPI/I2C only) */
+  PN532_ERROR_TIMEOUTWAITINGFORCARD   = 0x0B,   /**< No card detected in field with the specified timeout */
+  PN532_ERROR_BLOCKREADFAILED         = 0x0C,   /**< Unexpected response to block read request */
+  PN532_ERROR_WRONGCARDTYPE           = 0x0D,   /**< Card is not the expected format (based on SENS_RES/ATQA value) */
+  PN532_ERROR_ADDRESSOUTOFRANGE       = 0x0E,   /**< Specified block and page is out of range */
+  PN532_ERROR_I2C_NACK                = 0x0F,   /**< I2C Bus - No ACK was received for master to slave data transfer */
+  PN532_ERROR_I2C_TIMEOUT             = 0x10,   /**< I2C Bus - Timeout waiting for I2C response (missing pullups?) */
+  PN532_ERROR_BLOCKWRITEFAILED        = 0x11,   /**< Unexpected response to block write request */
+  PN532_ERROR_INCORRECTBLOCKFORMAT    = 0x12,   /**< Block isn't in the expected format (Mifare Value Block, etc.) */
+  PN532_ERROR_MEM_INVALID_PARAM       = 0x13,   /**< Parameter given to a function is invalid */
+  PN532_ERROR_MEM_INSUFFICIENT        = 0x14,   /**< Not enough memory */
+  PN532_ERROR_INVALID_PARAM           = 0x15,   /**< Invalid Parameter */
+  PN532_ERROR_INVALID_TAG             = 0x16,   /**< Invalid Tag is present */
+  PN532_ERROR_TOOMANYTARGETS          = 0x17,   /**< Unhandled number of targets during INLISTPASSIVETARGET */
+  PN532_ERROR_UNEXPECTEDRESPONSE      = 0x18,   /**< Unexpected response from the PN532 */
+  PN532_ERROR_PAYLOADOVERFLOW         = 0x19,   /**< Supplied payload is too large for the frame */
+  PN532_ERROR_TAG_UNWRITABLE          = 0x1A,   /**< Unable to write to the tag because write permissions have been disabled */
+  PN532_ERROR_TAG_WRITE_ERROR         = 0x1B,   /**< Write failed because this is not an NDEF writable tag */
+  PN532_ERROR_INVALID_LENGTH          = 0x1C,   /**< Invalid length for the supplied data */
+  PN532_ERROR_NOT_FOUND_NDEF_TLV      = 0x1D,   /**< Unable to locate the TLV block in the tag/NDEF message */
+  PN532_ERROR_AUTHENTICATE_FAIL       = 0x1E,   /**< Authentication error */
+  PN532_ERROR_NOT_NDEF_CARD           = 0x1F,   /**< Card does not contain a NDEF Message. */
+  PN532_ERROR_RFCONFIGURATION_FAIL    = 0x20    /**< RF configuration error */
+} pn532_error_t;
+
+typedef enum pn532_modulation_e
+{
+  PN532_MODULATION_ISO14443A_106KBPS  = 0x00,
+  PN532_MODULATION_FELICA_212KBPS     = 0x01,
+  PN532_MODULATION_FELICA_424KBPS     = 0x02,
+  PN532_MODULATION_ISO14443B_106KBPS  = 0x03,
+  PN532_MODULATION_JEWEL_106KBPS      = 0x04
+} pn532_modulation_t;
+
+/* HW Commands for the PN532.  */
+/* See UM0701-02 - PN532 User Manual */
+enum
+{
+  PN532_COMMAND_DIAGNOSE              = 0x00,
+  PN532_COMMAND_GETFIRMWAREVERSION    = 0x02,
+  PN532_COMMAND_GETGENERALSTATUS      = 0x04,
+  PN532_COMMAND_READREGISTER          = 0x06,
+  PN532_COMMAND_WRITEREGISTER         = 0x08,
+  PN532_COMMAND_READGPIO              = 0x0C,
+  PN532_COMMAND_WRITEGPIO             = 0x0E,
+  PN532_COMMAND_SETSERIALBAUDRATE     = 0x10,
+  PN532_COMMAND_SETPARAMETERS         = 0x12,
+  PN532_COMMAND_SAMCONFIGURATION      = 0x14,
+  PN532_COMMAND_POWERDOWN             = 0x16,
+  PN532_COMMAND_RFCONFIGURATION       = 0x32,
+  PN532_COMMAND_RFREGULATIONTEST      = 0x58,
+  PN532_COMMAND_INJUMPFORDEP          = 0x56,
+  PN532_COMMAND_INJUMPFORPSL          = 0x46,
+  PN532_COMMAND_INLISTPASSIVETARGET   = 0x4A,
+  PN532_COMMAND_INATR                 = 0x50,
+  PN532_COMMAND_INPSL                 = 0x4E,
+  PN532_COMMAND_INDATAEXCHANGE        = 0x40,
+  PN532_COMMAND_INCOMMUNICATETHRU     = 0x42,
+  PN532_COMMAND_INDESELECT            = 0x44,
+  PN532_COMMAND_INRELEASE             = 0x52,
+  PN532_COMMAND_INSELECT              = 0x54,
+  PN532_COMMAND_INAUTOPOLL            = 0x60,
+  PN532_COMMAND_TGINITASTARGET        = 0x8C,
+  PN532_COMMAND_TGSETGENERALBYTES     = 0x92,
+  PN532_COMMAND_TGGETDATA             = 0x86,
+  PN532_COMMAND_TGSETDATA             = 0x8E,
+  PN532_COMMAND_TGSETMETADATA         = 0x94,
+  PN532_COMMAND_TGGETINITIATORCOMMAND = 0x88,
+  PN532_COMMAND_TGRESPONSETOINITIATOR = 0x90,
+  PN532_COMMAND_TGGETTARGETSTATUS     = 0x8A
+};
+
+/* Application level errors generated by the PN532 chip */
+/* See UM0701-02 - PN532 User Manual */
+enum
+{
+  PN532_APPERROR_NONE                 = 0x00,
+  PN532_APPERROR_TIMEOUT              = 0x01,
+  PN532_APPERROR_CRCERROR             = 0x02,
+  PN532_APPERROR_PARITYERROR          = 0x04,
+  PN532_APPERROR_FRAMINGERROR         = 0x05,
+  PN532_APPERROR_BITCOLLISION         = 0x06,
+  PN532_APPERROR_INSUFFICIENTBUFFER   = 0x07,
+  PN532_APPERROR_RFBUFFEROVERFLOW     = 0x09,
+  PN532_APPERROR_RFFIELDTIMEOUT       = 0x0A,
+  PN532_APPERROR_RFPROTOCOLERROR      = 0x0B,
+  PN532_APPERROR_TEMPERROR            = 0x0D,
+  PN532_APPERROR_INTERNBUFFEROVERFLOW = 0x0E,
+  PN532_APPERROR_INVALIDPARAMETER     = 0x10,
+  PN532_APPERROR_DEP_UNSUPPORTEDCMD   = 0x12,
+  PN532_APPERROR_DEP_INVALIDOFORMAT   = 0x13,
+  PN532_APPERROR_AUTHENTERR           = 0x14,
+  PN532_APPERROR_UIDCCHECKERROR       = 0x23,
+  PN532_APPERROR_DEP_INVALIDDEVSTATE  = 0x25,
+  PN532_APPERROR_OPERATIONNOTALLOWED  = 0x26,
+  PN532_APPERROR_CMDNOTACCEPTABLE     = 0x27,
+  PN532_APPERROR_TARGETRELEASED       = 0x29,
+  PN532_APPERROR_IDMISMATCH           = 0x2A,
+  PN532_APPERROR_CARDDISAPPEARED      = 0x2B,
+  PN532_APPERROR_NFCID3MISMATCH       = 0x2C,
+  PN532_APPERROR_OVERCURRENTEVENT     = 0x2D,
+  PN532_APPERROR_NADMISSINGINDEP      = 0x2E
+};
+
+/* Possible states for the PN532 SW Stack */
+typedef enum pn532_state_e
+{
+  PN532_STATE_SLEEP,
+  PN532_STATE_READY,
+  PN532_STATE_BUSY
+}
+pn532_state_t;
+
+/* PN532 Protocol control block */
+typedef struct
+{
+  bool                initialised;
+  pn532_state_t       state;
+  pn532_modulation_t  modulation;
+  uint32_t            lastCommand;
+  uint32_t            appError;
+} pn532_pcb_t;
+
+void          pn532PrintHex(const byte_t * pbtData, const size_t szBytes);
+void          pn532PrintHexChar(const byte_t * pbtData, const size_t szBytes);
+pn532_pcb_t * pn532GetPCB(void);
+err_t       pn532Init(void);
+pn532_error_t pn532Read(byte_t *pbtResponse, size_t * pszLen);
+pn532_error_t pn532Write(byte_t *abtCommand, size_t szLen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/pn532_bus.h b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/pn532_bus.h
new file mode 100644
index 0000000000000000000000000000000000000000..486cce0d43ef87b381a45eddf1af6941045e3e65
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/pn532_bus.h
@@ -0,0 +1,79 @@
+/**************************************************************************/
+/*!
+    @file pn532_bus.h
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __PN532_BUS_H__
+#define __PN532_BUS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "pn532.h"
+
+#if defined(CFG_ENABLE_UART)
+  // #define PN532_BUS_UART
+#endif
+
+#if defined(CFG_ENABLE_I2C)
+  #define PN532_BUS_I2C
+#endif
+
+#if defined PN532_BUS_UART && defined PN532_BUS_I2C
+  #error "Only one target can be defined for the PN532 (PN532_BUS_I2C or PN532_BUS_UART)"
+#endif
+
+#define PN532_NORMAL_FRAME__DATA_MAX_LEN      (254)
+#define PN532_NORMAL_FRAME__OVERHEAD          (8)
+#define PN532_EXTENDED_FRAME__DATA_MAX_LEN    (264)
+#define PN532_EXTENDED_FRAME__OVERHEAD        (11)
+#define PN532_BUFFER_LEN                      (PN532_EXTENDED_FRAME__DATA_MAX_LEN + PN532_EXTENDED_FRAME__OVERHEAD)
+
+#define PN532_UART_BAUDRATE                   (115200)
+
+#define PN532_I2C_ADDRESS                     (0x48)
+#define PN532_I2C_READBIT                     (0x01)
+#define PN532_I2C_READYTIMEOUT                (20)    // Max number of attempts to read Ready bit (see UM 5-Nov-2007 Section 6.2.4)
+
+// Generic interface for the different serial buses available on the PN532
+err_t       pn532_bus_HWInit(void);
+pn532_error_t pn532_bus_SendCommand(const byte_t * pbtData, const size_t szData);
+pn532_error_t pn532_bus_ReadResponse(byte_t * pbtResponse, size_t * pszRxLen);
+pn532_error_t pn532_bus_Wakeup(void);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/pn532_bus_i2c.c b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/pn532_bus_i2c.c
new file mode 100644
index 0000000000000000000000000000000000000000..567c004c763984008e324ba1aeadd607d1904fb5
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/pn532_bus_i2c.c
@@ -0,0 +1,539 @@
+/**************************************************************************/
+/*!
+    @file pn532_bus_i2c.c
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <string.h>
+
+#include "projectconfig.h"
+
+#ifdef CFG_PN532
+
+#include "pn532.h"
+#include "pn532_bus.h"
+
+#ifdef PN532_BUS_I2C
+
+#include "core/delay/delay.h"
+#include "core/gpio/gpio.h"
+#include "core/i2c/i2c.h"
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+// Don't use a timeout for now since it complicates things (set to 0)
+#define PN532_I2C_TIMEOUT (0)
+
+/* ======================================================================
+   PRIVATE FUNCTIONS
+   ====================================================================== */
+
+/**************************************************************************/
+/*!
+    @brief  Writes an 8 bit value over I2C
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_I2C_NACK
+*/
+/**************************************************************************/
+pn532_error_t pn532_bus_i2c_WriteData (const byte_t * pbtData, const size_t szData)
+{
+  uint32_t i;
+  uint32_t i2cState;
+
+  // Send the specified bytes
+  I2CWriteLength = szData+1;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = PN532_I2C_ADDRESS;         // I2C device address
+  for ( i = 0; i < szData; i++ )
+  {
+    I2CMasterBuffer[i+1] = pbtData[i];
+  }
+  i2cState = i2cEngine();
+
+  // Check if we got an ACK
+  if ((i2cState == I2CSTATE_NACK) || (i2cState == I2CSTATE_SLA_NACK))
+  {
+    // I2C slave didn't acknowledge the master transfer
+    // The PN532 probably isn't connected properly or the
+    // bus select pins are in the wrong state
+    return PN532_ERROR_I2C_NACK;
+  }
+  if (i2cState == I2CSTATE_TIMEOUT)
+  {
+        // The most likely cause of this is missing pullups on I2C
+        return PN532_ERROR_I2C_TIMEOUT;
+  }
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief    Checks the 'IRQ' pin to know if the PN532 is ready to send
+              a response or not
+
+    @note     The IRQ bit may stay high intentionally, and this isn't
+              always an error condition.  When PN532_COMMAND_INLISTPASSIVETARGET
+              is sent, for example, the PN532 will wait until a card
+              enters the magnetic field, and IRQ will remain high since
+              there is no response ready yet.  The IRQ pin will go low
+              as soon as a card enters the magnetic field and the data
+              has been retrieved from it.
+
+    @returns  1 if a response is ready, 0 if the PN532 is still busy or a
+              timeout occurred
+*/
+/**************************************************************************/
+bool pn532_bus_i2c_WaitForReady(uint32_t timeout)
+{
+  uint8_t busy = 1;
+  uint8_t busyTimeout = 0;
+
+  if (timeout)
+  {
+    /* Wait up to the specified number of ms for the IRQ */
+    while (busy)
+    {
+      busy = GPIOGetPinValue(CFG_PN532_I2C_IRQPORT, CFG_PN532_I2C_IRQPIN);
+      delay(1);
+      busyTimeout++;
+      if (busyTimeout == PN532_I2C_READYTIMEOUT)
+      {
+         return false;
+       }
+    }
+  }
+  else
+  {
+    /* Wait forever for the IRQ */
+    while (busy)
+    {
+      busy = GPIOGetPinValue(CFG_PN532_I2C_IRQPORT, CFG_PN532_I2C_IRQPIN);
+      delay(1);
+    }
+  }
+
+  return true;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Builds a standard PN532 frame using the supplied data
+
+    @param  pbtFrame  Pointer to the field that will hold the frame data
+    @param  pszFrame  Pointer to the field that will hold the frame length
+    @param  pbtData   Pointer to the data to insert in a frame
+    @param  swData    Length of the data to insert in bytes
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_EXTENDEDFRAME
+*/
+/**************************************************************************/
+pn532_error_t pn532_bus_i2c_BuildFrame(byte_t * pbtFrame, size_t * pszFrame, const byte_t * pbtData, const size_t szData)
+{
+  size_t szPos;
+  byte_t btDCS;
+
+  if (szData > PN532_NORMAL_FRAME__DATA_MAX_LEN)
+  {
+    // Extended frames currently unsupported
+    return PN532_ERROR_EXTENDEDFRAME;
+  }
+
+  // LEN - Packet length = data length (len) + checksum (1) + end of stream marker (1)
+  pbtFrame[3] = szData + 1;
+  // LCS - Packet length checksum
+  pbtFrame[4] = 256 - (szData + 1);
+  // TFI
+  pbtFrame[5] = 0xD4;
+  // DATA - Copy the PN53X command into the packet buffer
+  memcpy (pbtFrame + 6, pbtData, szData);
+
+  // DCS - Calculate data payload checksum
+  btDCS = (256 - 0xD4);
+  for (szPos = 0; szPos < szData; szPos++)
+  {
+    btDCS -= pbtData[szPos];
+  }
+  pbtFrame[6 + szData] = btDCS;
+
+  // 0x00 - End of stream marker
+  pbtFrame[szData + 7] = 0x00;
+
+  (*pszFrame) = szData + PN532_NORMAL_FRAME__OVERHEAD;
+
+  return PN532_ERROR_NONE;
+}
+
+/* ======================================================================
+   PUBLIC FUNCTIONS
+   ====================================================================== */
+
+/**************************************************************************/
+/*!
+    @brief  Initialises I2C and configures the PN532 HW
+*/
+/**************************************************************************/
+err_t pn532_bus_HWInit(void)
+{
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Initialising I2C%s", CFG_PRINTF_NEWLINE);
+  #endif
+  i2cInit(I2CMASTER);
+
+  // Set reset pin as output and reset device
+  LPC_GPIO->DIR[CFG_PN532_RSTPD_PORT] |= (1 << CFG_PN532_RSTPD_PIN);
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Resetting the PN532%s", CFG_PRINTF_NEWLINE);
+  #endif
+  LPC_GPIO->CLR[CFG_PN532_RSTPD_PORT] = (1 << CFG_PN532_RSTPD_PIN);
+  delay(400);
+  LPC_GPIO->SET[CFG_PN532_RSTPD_PORT] = (1 << CFG_PN532_RSTPD_PIN);
+
+  // Wait for the PN532 to finish booting
+  delay(100);
+
+  // Ping the I2C device first to see if it exists!
+  if (i2cCheckAddress(PN532_I2C_ADDRESS) == false)
+  {
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Can't find PN532 on the I2C bus%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return ERROR_I2C_DEVICENOTFOUND;
+  }
+
+  // Set IRQ pin to input
+  LPC_GPIO->DIR[CFG_PN532_I2C_IRQPORT] &= ~(1 << CFG_PN532_I2C_IRQPIN);
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sends the specified command to the PN532, automatically
+            creating an appropriate frame for it
+
+    @param  pdbData   Pointer to the byte data to send
+    @param  szData    Length in bytes of the data to send
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_EXTENDEDFRAME       // Extended frames not supported
+            - PN532_ERROR_BUSY                // Already busy with a command
+            - PN532_ERROR_I2C_NACK            // No ACK on I2C
+            - PN532_ERROR_READYSTATUSTIMEOUT  // Timeout waiting for ready bit
+            - PN532_ERROR_INVALIDACK          // No ACK frame received
+*/
+/**************************************************************************/
+pn532_error_t pn532_bus_SendCommand(const byte_t * pbtData, const size_t szData)
+{
+  pn532_error_t error = PN532_ERROR_NONE;
+  byte_t abtFrame[PN532_BUFFER_LEN] = { 0x00, 0x00, 0xff };
+  size_t szFrame = 0;
+  pn532_pcb_t *pn532 = pn532GetPCB();
+  uint32_t i;
+
+  // Check if we're busy
+  if (pn532->state == PN532_STATE_BUSY)
+  {
+    return PN532_ERROR_BUSY;
+  }
+
+  // Flag the stack as busy
+  pn532->state = PN532_STATE_BUSY;
+
+  // --------------------------------------------------------------------
+  // Send the command frame
+  // --------------------------------------------------------------------
+  // Build the frame
+  pn532_bus_i2c_BuildFrame (abtFrame, &szFrame, pbtData, szData);
+
+  // Keep track of the last command that was sent
+  pn532->lastCommand = pbtData[0];
+
+  // Output the frame data for debugging if requested
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Sending  (%02d): ", szFrame);
+  pn532PrintHex(abtFrame, szFrame);
+  #endif
+
+  // Send data to the PN532
+  error = pn532_bus_i2c_WriteData(abtFrame, szFrame);
+
+  if (error == PN532_ERROR_I2C_NACK)
+  {
+    // Most likely error is PN532_ERROR_I2C_NACK
+    // meaning no I2C ACK received from the PN532
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG ("No ACK received on I2C bus%s", CFG_PRINTF_NEWLINE);
+    #endif
+    pn532->state = PN532_STATE_READY;
+    return error;
+  }
+
+  // --------------------------------------------------------------------
+  // Wait for the IRQ/Ready flag
+  // --------------------------------------------------------------------
+  if (!(pn532_bus_i2c_WaitForReady(PN532_I2C_TIMEOUT)))
+  {
+    pn532->state = PN532_STATE_READY;
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG ("Timed out waiting for IRQ/Ready%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return PN532_ERROR_READYSTATUSTIMEOUT;
+  }
+
+  // --------------------------------------------------------------------
+  // Read the ACK frame
+  // --------------------------------------------------------------------
+  I2CWriteLength = 0;
+  I2CReadLength = 7;  // ACK + Ready bit = 7
+  I2CMasterBuffer[0] = PN532_I2C_ADDRESS | PN532_I2C_READBIT;
+  i2cEngine();
+
+  // Make sure the received ACK matches the prototype
+  do
+  {
+    const byte_t abtAck[6] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
+    byte_t abtRxBuf[6];
+    // memcpy(abtRxBuf, I2CSlaveBuffer+1, 6);
+    for ( i = 0; i < 6; i++ )
+    {
+      abtRxBuf[i] = I2CSlaveBuffer[i+1];
+    }
+    if (0 != (memcmp (abtRxBuf, abtAck, 6)))
+    {
+      #ifdef PN532_DEBUGMODE
+      PN532_DEBUG ("Invalid ACK: ");
+      pn532PrintHex(abtRxBuf, 6);
+      PN532_DEBUG("%s", CFG_PRINTF_NEWLINE);
+      #endif
+      pn532->state = PN532_STATE_READY;
+      return PN532_ERROR_INVALIDACK;
+    }
+
+    // --------------------------------------------------------------------
+    // Wait for the post-ACK IRQ/Ready flag
+    // --------------------------------------------------------------------
+    if (!(pn532_bus_i2c_WaitForReady(PN532_I2C_TIMEOUT)))
+    {
+      pn532->state = PN532_STATE_READY;
+      #ifdef PN532_DEBUGMODE
+      PN532_DEBUG ("Timed out waiting for IRQ/Ready%s", CFG_PRINTF_NEWLINE);
+      #endif
+      return PN532_ERROR_READYSTATUSTIMEOUT;
+    }
+  } while(0);
+
+  pn532->state = PN532_STATE_READY;
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads a response from the PN532
+
+    @note   Possible error message are:
+
+            - PN532_ERROR_BUSY
+            - PN532_ERROR_RESPONSEBUFFEREMPTY
+            - PN532_ERROR_PREAMBLEMISMATCH
+            - PN532_ERROR_APPLEVELERROR
+            - PN532_ERROR_EXTENDEDFRAME
+            - PN532_ERROR_LENCHECKSUMMISMATCH
+*/
+/**************************************************************************/
+pn532_error_t pn532_bus_ReadResponse(byte_t * pbtResponse, size_t * pszRxLen)
+{
+  uint8_t i;
+  pn532_pcb_t *pn532 = pn532GetPCB();
+
+  // Check if we're busy
+  if (pn532->state == PN532_STATE_BUSY)
+  {
+    return PN532_ERROR_BUSY;
+  }
+
+  // Flag the stack as busy
+  pn532->state = PN532_STATE_BUSY;
+
+  // Reset the app error flag
+  pn532->appError = PN532_APPERROR_NONE;
+
+  for ( i = 0; i < I2C_BUFSIZE; i++ )
+  {
+    I2CMasterBuffer[i] = 0x00;
+  }
+  I2CWriteLength = 0;
+  I2CReadLength = I2C_BUFSIZE;
+  I2CMasterBuffer[0] = PN532_I2C_ADDRESS | PN532_I2C_READBIT;
+  i2cEngine();
+
+  // Use the full I2C buffer size for now (until we're sure we have a good frame)
+  *pszRxLen = I2C_BUFSIZE - 1;
+
+  // Display the raw response data for debugging if requested
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Received (%02d): ", I2C_BUFSIZE-1);
+  pn532PrintHex(I2CSlaveBuffer+1, I2C_BUFSIZE-1);
+  #endif
+
+  // Check the frame type
+  if ((0x01 == I2CSlaveBuffer[4]) && (0xff == I2CSlaveBuffer[5]))
+  {
+    // Error frame
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Application level error (0x%02x)%s", I2CSlaveBuffer[6], CFG_PRINTF_NEWLINE);
+    #endif
+    // Set application error message ID
+    pn532->appError = I2CSlaveBuffer[6];
+    pn532->state = PN532_STATE_READY;
+    return PN532_ERROR_APPLEVELERROR;
+  }
+  else if ((0xff == I2CSlaveBuffer[4]) && (0xff == I2CSlaveBuffer[5]))
+  {
+    // Extended frame
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Extended frames currently unsupported%s", CFG_PRINTF_NEWLINE);
+    #endif
+    pn532->state = PN532_STATE_READY;
+    return PN532_ERROR_EXTENDEDFRAME;
+  }
+  else
+  {
+    // Normal frame
+    if (256 != ((I2CSlaveBuffer[4]) + (I2CSlaveBuffer[5])))
+    {
+      // TODO: Retry
+      #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Length checksum mismatch%s", CFG_PRINTF_NEWLINE);
+      #endif
+      pn532->state = PN532_STATE_READY;
+      return PN532_ERROR_LENCHECKSUMMISMATCH;
+    }
+  }
+
+  // Figure out how large the response really is
+  // Response Frame Len = pbtResponse[4] + 7 (00 00 FF LEN LCS TFI [DATA] DCS)
+  *pszRxLen = (I2CSlaveBuffer[4]) + 7;
+
+  // TODO: Find a solution for this horribly ugly Mifare Classic block write hack!
+  // Some responses to command 0x40 report the incorrect len, and don't take into
+  // account the 16 byte payload when working with Mifare Classic sectors.
+  // The response frame indicates len 10 (0x0A) in I2CSlaveBuffer[4] but it should be
+  // 10+16 = 26 (0x1A)
+  if ((*pszRxLen == 10) && (I2CSlaveBuffer[7] == 0x41) && (I2CSlaveBuffer[26] != 0x00))
+  {
+    // For some reason, the PN532 reports len 10 for responses to
+    // command 0x40 which includes the command data but does not
+    // take into account the response/payload data in the len byte
+    *pszRxLen+=16;
+  }
+
+  // Fill the response buffer
+  // memcpy(pbtResponse, I2CSlaveBuffer+1, *pszRxLen);
+  for ( i = 0; i < *pszRxLen; i++ )
+  {
+    pbtResponse[i] = I2CSlaveBuffer[i+1];
+  }
+
+  pn532->state = PN532_STATE_READY;
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief      Sends the wakeup sequence to the PN532.
+
+    @note   Possible error message are:
+
+            - PN532_ERROR_BUSY
+            - PN532_ERROR_I2C_NACK            // No I2C ACK
+            - PN532_ERROR_READYSTATUSTIMEOUT  // Timed out waiting for ready bit
+*/
+/**************************************************************************/
+pn532_error_t pn532_bus_Wakeup(void)
+{
+  pn532_error_t error = PN532_ERROR_NONE;
+  byte_t abtWakeUp[] = { 0x55,0x55,0x00,0x00,0x00,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00 };
+
+  pn532_pcb_t *pn532 = pn532GetPCB();
+
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Sending Wakeup Sequence%s", CFG_PRINTF_NEWLINE);
+  #endif
+  error = pn532_bus_i2c_WriteData(abtWakeUp,sizeof(abtWakeUp));
+  if (error)
+  {
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Wakeup Failed (Error: %d)%s", error, CFG_PRINTF_NEWLINE);
+    #endif
+    return error;
+  }
+
+  delay(100);
+
+  // Wait for the IRQ/Ready flag to indicate a response is ready
+  if (!(pn532_bus_i2c_WaitForReady(PN532_I2C_TIMEOUT)))
+  {
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG ("Timed out waiting for IRQ/Ready%s", CFG_PRINTF_NEWLINE);
+    #endif
+    error = PN532_ERROR_READYSTATUSTIMEOUT;
+  }
+
+  // Read and discard the ACK frame
+  I2CWriteLength = 0;
+  I2CReadLength = 7;  // ACK + Ready bit = 7
+  I2CMasterBuffer[0] = PN532_I2C_ADDRESS | PN532_I2C_READBIT;
+  i2cEngine();
+  delay(1);
+
+  // Wait for the IRQ/Ready flag to indicate a response is ready
+  if (!(pn532_bus_i2c_WaitForReady(PN532_I2C_TIMEOUT)))
+  {
+    error = PN532_ERROR_READYSTATUSTIMEOUT;
+  }
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Wakeup Complete%s", CFG_PRINTF_NEWLINE);
+  #endif
+
+  pn532->state = PN532_STATE_READY;
+  return error;
+}
+
+#endif  // #ifdef PN532_BUS_I2C
+#endif  // #ifdef CFG_PN532
diff --git a/reform2-lpc-fw/src/drivers/rf/nfc/pn532/pn532_bus_uart.c b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/pn532_bus_uart.c
new file mode 100644
index 0000000000000000000000000000000000000000..3f85efa6a056bcfc26d7af06b6791831944355e0
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/nfc/pn532/pn532_bus_uart.c
@@ -0,0 +1,334 @@
+/**************************************************************************/
+/*!
+    @file pn532_bus_uart.c
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_PN532
+
+#include <string.h>
+#include "pn532.h"
+#include "pn532_bus.h"
+
+#ifdef PN532_BUS_UART
+
+#include "core/delay/delay.h"
+#include "core/gpio/gpio.h"
+#include "core/uart/uart.h"
+
+/**************************************************************************/
+/*!
+    @brief  Builds a standard PN532 frame using the supplied data
+
+    @param  pbtFrame  Pointer to the field that will hold the frame data
+    @param  pszFrame  Pointer to the field that will hold the frame length
+    @param  pbtData   Pointer to the data to insert in a frame
+    @param  swData    Length of the data to insert in bytes
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_EXTENDEDFRAME
+*/
+/**************************************************************************/
+pn532_error_t pn532_bus_BuildFrame(byte_t * pbtFrame, size_t * pszFrame, const byte_t * pbtData, const size_t szData)
+{
+  if (szData > PN532_NORMAL_FRAME__DATA_MAX_LEN)
+  {
+    // Extended frames currently unsupported
+    return PN532_ERROR_EXTENDEDFRAME;
+  }
+
+  // LEN - Packet length = data length (len) + checksum (1) + end of stream marker (1)
+  pbtFrame[3] = szData + 1;
+  // LCS - Packet length checksum
+  pbtFrame[4] = 256 - (szData + 1);
+  // TFI
+  pbtFrame[5] = PN532_HOSTTOPN532;
+  // DATA - Copy the PN53X command into the packet buffer
+  memcpy (pbtFrame + 6, pbtData, szData);
+
+  // DCS - Calculate data payload checksum
+  byte_t btDCS = (256 - PN532_HOSTTOPN532);
+  size_t szPos;
+  for (szPos = 0; szPos < szData; szPos++)
+  {
+    btDCS -= pbtData[szPos];
+  }
+  pbtFrame[6 + szData] = btDCS;
+
+  // 0x00 - End of stream marker
+  pbtFrame[szData + 7] = 0x00;
+
+  (*pszFrame) = szData + PN532_NORMAL_FRAME__OVERHEAD;
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Initialises UART and configures the PN532
+*/
+/**************************************************************************/
+err_t pn532_bus_HWInit(void)
+{
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Initialising UART (%d)%s", PN532_UART_BAUDRATE, CFG_PRINTF_NEWLINE);
+  #endif
+  uartInit(PN532_UART_BAUDRATE);
+
+  // Set reset pin as output and reset device
+  LPC_GPIO->DIR[CFG_PN532_RSTPD_PORT] |= (1 << CFG_PN532_RSTPD_PIN);
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Resetting the PN532...\r\n");
+  #endif
+  LPC_GPIO->CLR[CFG_PN532_RSTPD_PORT] = (1 << CFG_PN532_RSTPD_PIN);
+  delay(400);
+  LPC_GPIO->SET[CFG_PN532_RSTPD_PORT] = (1 << CFG_PN532_RSTPD_PIN);
+
+  // Wait for the PN532 to finish booting
+  delay(100);
+
+  // ToDo: Find a way to check of device is connected!
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sends the specified command to the PN532, automatically
+            creating an appropriate frame for it
+
+    @param  pdbData   Pointer to the byte data to send
+    @param  szData    Length in bytes of the data to send
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_BUSY
+            - PN532_ERROR_NOACK
+            - PN532_ERROR_INVALIDACK
+*/
+/**************************************************************************/
+pn532_error_t pn532_bus_SendCommand(const byte_t * pbtData, const size_t szData)
+{
+  pn532_pcb_t *pn532 = pn532GetPCB();
+
+  // Check if we're busy
+  if (pn532->state == PN532_STATE_BUSY)
+  {
+    return PN532_ERROR_BUSY;
+  }
+
+  // Flag the stack as busy
+  pn532->state = PN532_STATE_BUSY;
+
+  // Every packet must start with "00 00 ff"
+  byte_t  abtFrame[PN532_BUFFER_LEN] = { 0x00, 0x00, 0xff };
+  size_t szFrame = 0;
+
+  // Build the frame
+  pn532_bus_BuildFrame (abtFrame, &szFrame, pbtData, szData);
+
+  // Keep track of the last command that was sent
+  pn532->lastCommand = pbtData[0];
+
+  // Output the frame data for debugging if requested
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Sending  (%02d): ", szFrame);
+  pn532PrintHex(abtFrame, szFrame);
+  #endif
+
+  // Send data to the PN532
+  uartSend (abtFrame, szFrame);
+
+  // Wait for ACK
+  byte_t abtRxBuf[6];
+  uart_pcb_t *uart = uartGetPCB();
+  delay(10);   // FIXME: How long should we wait for ACK?
+  if (uart->rxfifo.len < 6)
+  {
+    // Unable to read ACK
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG ("Unable to read ACK%s", CFG_PRINTF_NEWLINE);
+    #endif
+    pn532->state = PN532_STATE_READY;
+    return PN532_ERROR_NOACK;
+  }
+
+  // Read ACK ... this will also remove it from the buffer
+  const byte_t abtAck[6] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
+  abtRxBuf[0] = uartRxBufferRead();
+  abtRxBuf[1] = uartRxBufferRead();
+  abtRxBuf[2] = uartRxBufferRead();
+  abtRxBuf[3] = uartRxBufferRead();
+  abtRxBuf[4] = uartRxBufferRead();
+  abtRxBuf[5] = uartRxBufferRead();
+
+  // Make sure the received ACK matches the prototype
+  if (0 != (memcmp (abtRxBuf, abtAck, 6)))
+  {
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG ("Invalid ACK: ");
+    pn532PrintHex(abtRxBuf, 6);
+    PN532_DEBUG("%s", CFG_PRINTF_NEWLINE);
+    #endif
+    pn532->state = PN532_STATE_READY;
+    return PN532_ERROR_INVALIDACK;
+  }
+
+  pn532->state = PN532_STATE_READY;
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads a response from the PN532
+
+    @note   Possible error message are:
+
+            - PN532_ERROR_BUSY
+            - PN532_ERROR_RESPONSEBUFFEREMPTY
+            - PN532_ERROR_PREAMBLEMISMATCH
+            - PN532_ERROR_APPLEVELERROR
+            - PN532_ERROR_EXTENDEDFRAME
+            - PN532_ERROR_LENCHECKSUMMISMATCH
+*/
+/**************************************************************************/
+pn532_error_t pn532_bus_ReadResponse(byte_t * pbtResponse, size_t * pszRxLen)
+{
+  pn532_pcb_t *pn532 = pn532GetPCB();
+
+  // Check if we're busy
+  if (pn532->state == PN532_STATE_BUSY)
+  {
+    return PN532_ERROR_BUSY;
+  }
+
+  // Flag the stack as busy
+  pn532->state = PN532_STATE_BUSY;
+
+  // Reset the app error flag
+  pn532->appError = PN532_APPERROR_NONE;
+
+  // Read response from uart
+  if (!uartRxBufferReadArray(pbtResponse, pszRxLen))
+  {
+    pn532->state = PN532_STATE_READY;
+    return PN532_ERROR_RESPONSEBUFFEREMPTY;
+  }
+
+  // Display the raw response data for debugging if requested
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Received (%02d): ", *pszRxLen);
+  pn532PrintHex(pbtResponse, *pszRxLen);
+  #endif
+
+  // Check preamble
+  const byte_t pn53x_preamble[3] = { 0x00, 0x00, 0xff };
+  if (0 != (memcmp (pbtResponse, pn53x_preamble, 3)))
+  {
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Frame preamble + start code mismatch%s", CFG_PRINTF_NEWLINE);
+    #endif
+    pn532->state = PN532_STATE_READY;
+    return PN532_ERROR_PREAMBLEMISMATCH;
+  }
+
+  // Check the frame type
+  if ((0x01 == pbtResponse[3]) && (0xff == pbtResponse[4]))
+  {
+    // Error frame
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Application level error (0x%02x)%s", pbtResponse[5], CFG_PRINTF_NEWLINE);
+    #endif
+    // Set application error message ID
+    pn532->appError = pbtResponse[5];
+    pn532->state = PN532_STATE_READY;
+    return PN532_ERROR_APPLEVELERROR;
+  }
+  else if ((0xff == pbtResponse[3]) && (0xff == pbtResponse[4]))
+  {
+    // Extended frame
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Extended frames currently unsupported%s", CFG_PRINTF_NEWLINE);
+    #endif
+    pn532->state = PN532_STATE_READY;
+    return PN532_ERROR_EXTENDEDFRAME;
+  }
+  else
+  {
+    // Normal frame
+    if (256 != (pbtResponse[3] + pbtResponse[4]))
+    {
+      // TODO: Retry
+      #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Length checksum mismatch%s", CFG_PRINTF_NEWLINE);
+      #endif
+      pn532->state = PN532_STATE_READY;
+      return PN532_ERROR_LENCHECKSUMMISMATCH;
+    }
+    // size_t szPayloadLen = abtRx[3] - 2;
+  }
+
+  pn532->state = PN532_STATE_READY;
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief      Sends the wakeup sequence to the PN532.
+*/
+/**************************************************************************/
+pn532_error_t pn532_bus_Wakeup(void)
+{
+  size_t szLen;
+  byte_t abtWakeUp[] = { 0x55,0x55,0x00,0x00,0x00,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00 };
+
+  pn532_pcb_t *pn532 = pn532GetPCB();
+
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Sending Wakeup Sequence%s", CFG_PRINTF_NEWLINE);
+  #endif
+  uartSend(abtWakeUp,sizeof(abtWakeUp));
+  delay(100);
+
+  byte_t response[32];
+  pn532_bus_ReadResponse(response, &szLen);
+
+  // Todo: Check for error ... currently throws a checksum error
+  // that isn't really an error
+
+  pn532->state = PN532_STATE_READY;
+  return PN532_ERROR_NONE;
+}
+
+#endif  // #ifdef PN532_BUS_UART
+#endif  // #ifdef CFG_PN532
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/cc3000_common.c b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/cc3000_common.c
new file mode 100644
index 0000000000000000000000000000000000000000..cea141f04df40b5c15b592ebc40134857aa65630
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/cc3000_common.c
@@ -0,0 +1,168 @@
+/*****************************************************************************
+*
+*  cc3000_common.c.c  - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the   
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+//*****************************************************************************
+//
+//! \addtogroup common_api
+//! @{
+//
+//*****************************************************************************
+#include "projectconfig.h"
+
+#ifdef CFG_CC3000
+
+/******************************************************************************
+ *
+ * Include files
+ *
+ *****************************************************************************/
+#include "cc3000_common.h"
+#include "socket.h"
+#include "wlan.h"
+#include "evnt_handler.h"
+
+//*****************************************************************************
+//
+//!  __error__
+//!
+//!  @param  pcFilename - file name, where error occurred
+//!  @param  ulLine     - line number, where error occurred
+//!
+//!  @return none
+//!
+//!  @brief stub function for ASSERT macro
+//
+//*****************************************************************************
+void
+__error__(char *pcFilename, unsigned long ulLine)
+{
+    //TODO full up function
+}
+
+
+
+//*****************************************************************************
+//
+//!  UINT32_TO_STREAM_f
+//!
+//!  @param  p       pointer to the new stream
+//!  @param  u32     pointer to the 32 bit
+//!
+//!  @return               pointer to the new stream
+//!
+//!  @brief                This function is used for copying 32 bit to stream
+//!						   while converting to little endian format.
+//
+//*****************************************************************************
+
+unsigned char* UINT32_TO_STREAM_f (unsigned char *p, unsigned long u32)
+{
+	*(p)++ = (unsigned char)(u32);
+	*(p)++ = (unsigned char)((u32) >> 8);
+	*(p)++ = (unsigned char)((u32) >> 16);
+	*(p)++ = (unsigned char)((u32) >> 24);
+	return p;
+}
+
+//*****************************************************************************
+//
+//!  UINT16_TO_STREAM_f
+//!
+//!  @param  p       pointer to the new stream
+//!  @param  u32     pointer to the 16 bit
+//!
+//!  @return               pointer to the new stream
+//!
+//!  @brief               This function is used for copying 16 bit to stream
+//!                       while converting to little endian format.
+//
+//*****************************************************************************
+
+unsigned char* UINT16_TO_STREAM_f (unsigned char *p, unsigned short u16)
+{
+	*(p)++ = (unsigned char)(u16);
+	*(p)++ = (unsigned char)((u16) >> 8);
+	return p;
+}
+
+//*****************************************************************************
+//
+//!  STREAM_TO_UINT16_f
+//!
+//!  @param  p          pointer to the stream
+//!  @param  offset     offset in the stream
+//!
+//!  @return               pointer to the new 16 bit
+//!
+//!  @brief               This function is used for copying received stream to
+//!                       16 bit in little endian format.
+//
+//*****************************************************************************
+
+unsigned short STREAM_TO_UINT16_f(char* p, unsigned short offset)
+{
+        return (unsigned short)((unsigned short)((unsigned short)
+								(*(p + offset + 1)) << 8) + (unsigned short)(*(p + offset)));
+}
+
+//*****************************************************************************
+//
+//!  STREAM_TO_UINT32_f
+//!
+//!  @param  p          pointer to the stream
+//!  @param  offset     offset in the stream
+//!
+//!  @return               pointer to the new 32 bit
+//!
+//!  @brief               This function is used for copying received stream to
+//!                       32 bit in little endian format.
+//
+//*****************************************************************************
+
+unsigned long STREAM_TO_UINT32_f(char* p, unsigned short offset)
+{
+        return (unsigned long)((unsigned long)((unsigned long)
+							 (*(p + offset + 3)) << 24) + (unsigned long)((unsigned long)
+							 (*(p + offset + 2)) << 16) + (unsigned long)((unsigned long)
+							 (*(p + offset + 1)) << 8) + (unsigned long)(*(p + offset)));
+}
+
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/cc3000_common.h b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/cc3000_common.h
new file mode 100644
index 0000000000000000000000000000000000000000..858fe85c348072bd8fc8fd9873ecd1f2faccd4d7
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/cc3000_common.h
@@ -0,0 +1,357 @@
+/*****************************************************************************
+*
+*  cc3000_common.h  - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the   
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+//******************************************************************************
+// Include files
+//******************************************************************************
+#include <stdlib.h>
+#include <errno.h>
+#include <stdint.h>
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+//*****************************************************************************
+//                  ERROR CODES
+//*****************************************************************************
+#define ESUCCESS        0
+#define EFAIL          -1
+#define EERROR          EFAIL
+
+//*****************************************************************************
+//                  COMMON DEFINES
+//*****************************************************************************
+#define ERROR_SOCKET_INACTIVE   -57 
+
+#define WLAN_ENABLE      (1)   
+#define WLAN_DISABLE     (0)
+
+#define	MAC_ADDR_LEN	(6)
+
+#define	SP_PORTION_SIZE	(32)
+  
+/*Defines for minimal and maximal RX buffer size. This size includes the spi 
+  header and hci header.
+  The maximal buffer size derives from:
+    MTU + HCI header + SPI header + sendto() agrs size
+  The minimum buffer size derives from:
+    HCI header + SPI header + max args size
+
+  This buffer is used for receiving events and data.
+  The packet can not be longer than MTU size and CC3000 does not support 
+  fragmentation. Note that the same buffer is used for reception of the data 
+  and events from CC3000. That is why the minimum is defined. 
+  The calculation for the actual size of buffer for reception is:
+  Given the maximal data size MAX_DATA that is expected to be received by
+  application, the required buffer is:
+  Using recv() or recvfrom():
+ 
+    max(CC3000_MINIMAL_RX_SIZE, MAX_DATA + HEADERS_SIZE_DATA + fromlen
+    + ucArgsize + 1)
+ 
+  Using gethostbyname() with minimal buffer size will limit the host name
+  returned to 99 bytes only.
+  The 1 is used for the overrun detection 
+
+  Buffer size increased to 130 following the add_profile() with WEP security
+  which requires TX buffer size of 130 bytes: 
+  HEADERS_SIZE_EVNT + WLAN_ADD_PROFILE_WEP_PARAM_LEN + MAX SSID LEN + 4 * MAX KEY LEN = 130
+  MAX SSID LEN = 32 
+  MAX SSID LEN = 13 (with add_profile only ascii key setting is supported, 
+  therfore maximum key size is 13)
+*/
+
+#define CC3000_MINIMAL_RX_SIZE      (399 + 1)
+#define CC3000_MAXIMAL_RX_SIZE      (1519 + 1)
+
+/*Defines for minimal and maximal TX buffer size.
+  This buffer is used for sending events and data.
+  The packet can not be longer than MTU size and CC3000 does not support 
+  fragmentation. Note that the same buffer is used for transmission of the data
+  and commands. That is why the minimum is defined.
+  The calculation for the actual size of buffer for transmission is:
+  Given the maximal data size MAX_DATA, the required buffer is:
+  Using Sendto():
+ 
+   max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE
+   + SOCKET_SENDTO_PARAMS_LEN + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1)
+ 
+  Using Send():
+ 
+   max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE
+   + HCI_CMND_SEND_ARG_LENGTH + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1)
+ 
+  The 1 is used for the overrun detection */ 
+
+#define	CC3000_MINIMAL_TX_SIZE      (399 + 1)
+#define	CC3000_MAXIMAL_TX_SIZE      (1519 + 1)
+
+//TX and RX buffer sizes, allow to receive and transmit maximum data at length 8.
+#ifdef CC3000_TINY_DRIVER
+#define TINY_CC3000_MAXIMAL_RX_SIZE 44
+#define TINY_CC3000_MAXIMAL_TX_SIZE 59
+#endif
+
+/*In order to determine your preferred buffer size, 
+  change CC3000_MAXIMAL_RX_SIZE and CC3000_MAXIMAL_TX_SIZE to a value between
+  the minimal and maximal specified above. 
+  Note that the buffers are allocated by SPI.
+  In case you change the size of those buffers, you might need also to change
+  the linker file, since for example on MSP430 FRAM devices the buffers are
+  allocated in the FRAM section that is allocated manually and not by IDE.
+*/
+  
+#ifndef CC3000_TINY_DRIVER
+  
+	#define CC3000_RX_BUFFER_SIZE   (CC3000_MAXIMAL_RX_SIZE)
+	#define CC3000_TX_BUFFER_SIZE   (CC3000_MAXIMAL_TX_SIZE)
+  
+//if defined TINY DRIVER we use smaller RX and TX buffer in order to minimize RAM consumption
+#else
+	#define CC3000_RX_BUFFER_SIZE   (TINY_CC3000_MAXIMAL_RX_SIZE)
+	#define CC3000_TX_BUFFER_SIZE   (TINY_CC3000_MAXIMAL_TX_SIZE)
+
+#endif  
+
+//*****************************************************************************
+//                  Compound Types
+//*****************************************************************************
+typedef long time_t;
+typedef unsigned long clock_t;
+typedef long suseconds_t;
+
+typedef struct timeval timeval;
+
+struct timeval 
+{
+    time_t         tv_sec;                  /* seconds */
+    suseconds_t    tv_usec;                 /* microseconds */
+};
+
+typedef char *(*tFWPatches)(unsigned long *usLength);
+
+typedef char *(*tDriverPatches)(unsigned long *usLength);
+
+typedef char *(*tBootLoaderPatches)(unsigned long *usLength);
+
+typedef void (*tWlanCB)(long event_type, char * data, unsigned char length );
+
+typedef long (*tWlanReadInteruptPin)(void);
+
+typedef void (*tWlanInterruptEnable)(void);
+
+typedef void (*tWlanInterruptDisable)(void);
+
+typedef void (*tWriteWlanPin)(unsigned char val);
+
+typedef struct
+{
+	unsigned short	 usRxEventOpcode;
+	unsigned short	 usEventOrDataReceived;
+	unsigned char 	*pucReceivedData;
+	unsigned char 	*pucTxCommandBuffer;
+
+	tFWPatches 			sFWPatches;
+	tDriverPatches 		sDriverPatches;
+	tBootLoaderPatches 	sBootLoaderPatches;
+	tWlanCB	 			sWlanCB;
+    tWlanReadInteruptPin  ReadWlanInterruptPin;
+    tWlanInterruptEnable  WlanInterruptEnable;
+    tWlanInterruptDisable WlanInterruptDisable;
+    tWriteWlanPin         WriteWlanPin;
+
+	signed long		 slTransmitDataError;
+	unsigned short	 usNumberOfFreeBuffers;
+	unsigned short	 usSlBufferLength;
+	unsigned short	 usBufferSize;
+	unsigned short	 usRxDataPending;
+
+	unsigned long    NumberOfSentPackets;
+	unsigned long    NumberOfReleasedPackets;
+
+	unsigned char	 InformHostOnTxComplete;
+}sSimplLinkInformation;
+
+extern volatile sSimplLinkInformation tSLInformation;
+
+
+//*****************************************************************************
+// Prototypes for the APIs.
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//
+//!  SimpleLinkWaitEvent
+//!
+//!  @param  usOpcode      command operation code
+//!  @param  pRetParams    command return parameters
+//!
+//!  @return               none
+//!
+//!  @brief                Wait for event, pass it to the hci_event_handler and
+//!                        update the event opcode in a global variable.
+//
+//*****************************************************************************
+
+extern void SimpleLinkWaitEvent(unsigned short usOpcode, void *pRetParams);
+
+//*****************************************************************************
+//
+//!  SimpleLinkWaitData
+//!
+//!  @param  pBuf       data buffer
+//!  @param  from       from information
+//!  @param  fromlen	  from information length
+//!
+//!  @return               none
+//!
+//!  @brief                Wait for data, pass it to the hci_event_handler
+//! 					   and update in a global variable that there is 
+//!						   data to read.
+//
+//*****************************************************************************
+
+extern void SimpleLinkWaitData(unsigned char *pBuf, unsigned char *from, unsigned char *fromlen);
+
+//*****************************************************************************
+//
+//!  UINT32_TO_STREAM_f
+//!
+//!  \param  p       pointer to the new stream
+//!  \param  u32     pointer to the 32 bit
+//!
+//!  \return               pointer to the new stream
+//!
+//!  \brief                This function is used for copying 32 bit to stream
+//!						   while converting to little endian format.
+//
+//*****************************************************************************
+
+extern unsigned char* UINT32_TO_STREAM_f (unsigned char *p, unsigned long u32);
+
+//*****************************************************************************
+//
+//!  UINT16_TO_STREAM_f
+//!
+//!  \param  p       pointer to the new stream
+//!  \param  u32     pointer to the 16 bit
+//!
+//!  \return               pointer to the new stream
+//!
+//!  \brief               This function is used for copying 16 bit to stream 
+//!                       while converting to little endian format.
+//
+//*****************************************************************************
+
+extern unsigned char* UINT16_TO_STREAM_f (unsigned char *p, unsigned short u16);
+
+//*****************************************************************************
+//
+//!  STREAM_TO_UINT16_f
+//!
+//!  \param  p          pointer to the stream
+//!  \param  offset     offset in the stream
+//!
+//!  \return               pointer to the new 16 bit
+//!
+//!  \brief               This function is used for copying received stream to 
+//!                       16 bit in little endian format.
+//
+//*****************************************************************************
+
+extern unsigned short STREAM_TO_UINT16_f(char* p, unsigned short offset);
+
+//*****************************************************************************
+//
+//!  STREAM_TO_UINT32_f
+//!
+//!  \param  p          pointer to the stream
+//!  \param  offset     offset in the stream
+//!
+//!  \return               pointer to the new 32 bit
+//!
+//!  \brief               This function is used for copying received stream to
+//!                       32 bit in little endian format.
+//
+//*****************************************************************************
+
+extern unsigned long STREAM_TO_UINT32_f(char* p, unsigned short offset);
+
+
+//*****************************************************************************
+//                    COMMON MACROs
+//*****************************************************************************
+
+
+//This macro is used for copying 8 bit to stream while converting to little endian format.
+#define UINT8_TO_STREAM(_p, _val)	{*(_p)++ = (_val);}
+//This macro is used for copying 16 bit to stream while converting to little endian format.
+#define UINT16_TO_STREAM(_p, _u16)	(UINT16_TO_STREAM_f(_p, _u16))
+//This macro is used for copying 32 bit to stream while converting to little endian format.
+#define UINT32_TO_STREAM(_p, _u32)	(UINT32_TO_STREAM_f(_p, _u32))
+//This macro is used for copying a specified value length bits (l) to stream while converting to little endian format.
+#define ARRAY_TO_STREAM(p, a, l) 	{register short _i; for (_i = 0; _i < l; _i++) *(p)++ = ((unsigned char *) a)[_i];}
+//This macro is used for copying received stream to 8 bit in little endian format.
+#define STREAM_TO_UINT8(_p, _offset, _u8)	{_u8 = (unsigned char)(*(_p + _offset));}
+//This macro is used for copying received stream to 16 bit in little endian format.
+#define STREAM_TO_UINT16(_p, _offset, _u16)	{_u16 = STREAM_TO_UINT16_f(_p, _offset);}
+//This macro is used for copying received stream to 32 bit in little endian format.
+#define STREAM_TO_UINT32(_p, _offset, _u32)	{_u32 = STREAM_TO_UINT32_f(_p, _offset);}
+#define STREAM_TO_STREAM(p, a, l) 	{register short _i; for (_i = 0; _i < l; _i++) *(a)++= ((unsigned char *) p)[_i];}
+
+
+
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef  __cplusplus
+}
+#endif // __cplusplus
+
+#endif // __COMMON_H__
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/evnt_handler.c b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/evnt_handler.c
new file mode 100644
index 0000000000000000000000000000000000000000..8206657d5237e0d5c0c516f6fe4bf68fb4304d1f
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/evnt_handler.c
@@ -0,0 +1,846 @@
+/*****************************************************************************
+*
+*  evnt_handler.c  - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the   
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_CC3000
+//*****************************************************************************
+//
+//! \addtogroup evnt_handler_api
+//! @{
+//
+//******************************************************************************
+
+//******************************************************************************
+//                  INCLUDE FILES
+//******************************************************************************
+
+#include "cc3000_common.h"
+#include "string.h"
+#include "hci.h"
+#include "evnt_handler.h"
+#include "wlan.h"
+#include "socket.h"
+#include "netapp.h"
+#include "../spi.h"
+
+ 
+
+//*****************************************************************************
+//                  COMMON DEFINES
+//*****************************************************************************
+
+#define FLOW_CONTROL_EVENT_HANDLE_OFFSET		(0)
+#define FLOW_CONTROL_EVENT_BLOCK_MODE_OFFSET	(1)
+#define FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET	(2)
+#define FLOW_CONTROL_EVENT_SIZE					(4)
+
+#define BSD_RSP_PARAMS_SOCKET_OFFSET		(0)
+#define BSD_RSP_PARAMS_STATUS_OFFSET		(4)
+
+#define GET_HOST_BY_NAME_RETVAL_OFFSET	(0)
+#define GET_HOST_BY_NAME_ADDR_OFFSET	(4)
+
+#define ACCEPT_SD_OFFSET			(0)
+#define ACCEPT_RETURN_STATUS_OFFSET	(4)
+#define ACCEPT_ADDRESS__OFFSET		(8)
+
+#define SL_RECEIVE_SD_OFFSET			(0)
+#define SL_RECEIVE_NUM_BYTES_OFFSET		(4)
+#define SL_RECEIVE__FLAGS__OFFSET		(8)
+
+
+#define SELECT_STATUS_OFFSET			(0)
+#define SELECT_READFD_OFFSET			(4)
+#define SELECT_WRITEFD_OFFSET			(8)
+#define SELECT_EXFD_OFFSET				(12)
+
+
+#define NETAPP_IPCONFIG_IP_OFFSET				(0)
+#define NETAPP_IPCONFIG_SUBNET_OFFSET			(4)
+#define NETAPP_IPCONFIG_GW_OFFSET				(8)
+#define NETAPP_IPCONFIG_DHCP_OFFSET				(12)
+#define NETAPP_IPCONFIG_DNS_OFFSET				(16)
+#define NETAPP_IPCONFIG_MAC_OFFSET				(20)
+#define NETAPP_IPCONFIG_SSID_OFFSET				(26)
+
+#define NETAPP_IPCONFIG_IP_LENGTH				(4)
+#define NETAPP_IPCONFIG_MAC_LENGTH				(6)
+#define NETAPP_IPCONFIG_SSID_LENGTH				(32)
+
+
+#define NETAPP_PING_PACKETS_SENT_OFFSET			(0)
+#define NETAPP_PING_PACKETS_RCVD_OFFSET			(4)
+#define NETAPP_PING_MIN_RTT_OFFSET				(8)
+#define NETAPP_PING_MAX_RTT_OFFSET				(12)
+#define NETAPP_PING_AVG_RTT_OFFSET				(16)
+
+#define GET_SCAN_RESULTS_TABlE_COUNT_OFFSET				(0)
+#define GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET		(4)
+#define GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET		(8)
+#define GET_SCAN_RESULTS_FRAME_TIME_OFFSET				(10)
+#define GET_SCAN_RESULTS_SSID_MAC_LENGTH				(38)
+
+
+
+//*****************************************************************************
+//                  GLOBAL VARAIABLES
+//*****************************************************************************
+
+unsigned long socket_active_status = SOCKET_STATUS_INIT_VAL; 
+
+
+//*****************************************************************************
+//            Prototypes for the static functions
+//*****************************************************************************
+
+static long hci_event_unsol_flowcontrol_handler(char *pEvent);
+
+static void update_socket_active_status(char *resp_params);
+
+
+//*****************************************************************************
+//
+//!  hci_unsol_handle_patch_request
+//!
+//!  @param  event_hdr  event header
+//!
+//!  @return none
+//!
+//!  @brief   Handle unsolicited event from type patch request
+//
+//*****************************************************************************
+void hci_unsol_handle_patch_request(char *event_hdr)
+{
+	char *params = (char *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
+	unsigned long ucLength = 0;
+	char *patch;
+	
+	switch (*params)
+	{
+	case HCI_EVENT_PATCHES_DRV_REQ:
+		
+		if (tSLInformation.sDriverPatches)
+		{
+			patch = tSLInformation.sDriverPatches(&ucLength);
+			
+			if (patch)
+			{
+				hci_patch_send(HCI_EVENT_PATCHES_DRV_REQ, 
+											 tSLInformation.pucTxCommandBuffer, patch, ucLength);
+				return;
+			}
+		}
+		
+		// Send 0 length Patches response event
+		hci_patch_send(HCI_EVENT_PATCHES_DRV_REQ, 
+									 tSLInformation.pucTxCommandBuffer, 0, 0);
+		break;
+		
+	case HCI_EVENT_PATCHES_FW_REQ:
+		
+		if (tSLInformation.sFWPatches)
+		{
+			patch = tSLInformation.sFWPatches(&ucLength);
+			
+			// Build and send a patch
+			if (patch)
+			{
+				hci_patch_send(HCI_EVENT_PATCHES_FW_REQ, 
+											 tSLInformation.pucTxCommandBuffer, patch, ucLength);
+				return;
+			}
+		}
+		
+		// Send 0 length Patches response event
+		hci_patch_send(HCI_EVENT_PATCHES_FW_REQ, 
+									 tSLInformation.pucTxCommandBuffer, 0, 0);
+		break;
+		
+	case HCI_EVENT_PATCHES_BOOTLOAD_REQ:
+		
+		if (tSLInformation.sBootLoaderPatches)
+		{
+			patch = tSLInformation.sBootLoaderPatches(&ucLength);
+			
+			if (patch)
+			{
+				hci_patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ,  
+											 tSLInformation.pucTxCommandBuffer, patch, ucLength);
+				return;
+			}
+		}
+		
+		// Send 0 length Patches response event
+		hci_patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, 
+									 tSLInformation.pucTxCommandBuffer, 0, 0);
+		break;
+	}
+}
+
+
+
+//*****************************************************************************
+//
+//!  hci_event_handler
+//!
+//!  @param  pRetParams     incoming data buffer
+//!  @param  from           from information (in case of data received)
+//!  @param  fromlen        from information length (in case of data received)
+//!
+//!  @return         none
+//!
+//!  @brief          Parse the incoming events packets and issues corresponding
+//!                  event handler from global array of handlers pointers
+//
+//*****************************************************************************
+
+	
+unsigned char *
+hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen)
+{
+	unsigned char *pucReceivedData, ucArgsize;
+	unsigned short usLength;
+	unsigned char *pucReceivedParams;
+	unsigned short usReceivedEventOpcode = 0;
+	unsigned long retValue32;
+  unsigned char * RecvParams;
+  unsigned char *RetParams;
+	
+	
+	while (1)
+	{
+		if (tSLInformation.usEventOrDataReceived != 0)
+		{				
+			pucReceivedData = (tSLInformation.pucReceivedData);
+
+			if (*pucReceivedData == HCI_TYPE_EVNT)
+			{
+				// Event Received
+				STREAM_TO_UINT16((char *)pucReceivedData, HCI_EVENT_OPCODE_OFFSET,
+												 usReceivedEventOpcode);
+				pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE;		
+				RecvParams = pucReceivedParams;
+				RetParams = pRetParams;
+				
+				// In case unsolicited event received - here the handling finished
+				if (hci_unsol_event_handler((char *)pucReceivedData) == 0)
+				{
+					STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength);
+					
+					switch(usReceivedEventOpcode)
+					{		
+					case HCI_CMND_READ_BUFFER_SIZE:
+						{
+							STREAM_TO_UINT8((char *)pucReceivedParams, 0, 
+															tSLInformation.usNumberOfFreeBuffers);
+							STREAM_TO_UINT16((char *)pucReceivedParams, 1, 
+															 tSLInformation.usSlBufferLength);
+						}
+						break;
+						
+					case HCI_CMND_WLAN_CONFIGURE_PATCH:
+					case HCI_NETAPP_DHCP:
+					case HCI_NETAPP_PING_SEND:
+					case HCI_NETAPP_PING_STOP:
+					case HCI_NETAPP_ARP_FLUSH:
+					case HCI_NETAPP_SET_DEBUG_LEVEL:
+					case HCI_NETAPP_SET_TIMERS:
+					case HCI_EVNT_NVMEM_READ:
+					case HCI_EVNT_NVMEM_CREATE_ENTRY:
+					case HCI_CMND_NVMEM_WRITE_PATCH:
+					case HCI_NETAPP_PING_REPORT:
+					case HCI_EVNT_MDNS_ADVERTISE:
+						
+						STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET
+														,*(unsigned char *)pRetParams);
+						break;
+						
+					case HCI_CMND_SETSOCKOPT:
+					case HCI_CMND_WLAN_CONNECT:
+					case HCI_CMND_WLAN_IOCTL_STATUSGET:
+					case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE:
+					case HCI_CMND_WLAN_IOCTL_DEL_PROFILE:
+					case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY:
+					case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM:
+					case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START:
+					case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP:
+					case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX:
+					case HCI_CMND_EVENT_MASK:
+					case HCI_EVNT_WLAN_DISCONNECT:
+					case HCI_EVNT_SOCKET:
+					case HCI_EVNT_BIND:
+					case HCI_CMND_LISTEN:
+					case HCI_EVNT_CLOSE_SOCKET:
+					case HCI_EVNT_CONNECT:
+					case HCI_EVNT_NVMEM_WRITE:
+						
+						STREAM_TO_UINT32((char *)pucReceivedParams,0
+														 ,*(unsigned long *)pRetParams);
+						break;
+						
+					case HCI_EVNT_READ_SP_VERSION:
+						
+						STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET
+														,*(unsigned char *)pRetParams);
+						pRetParams = ((char *)pRetParams) + 1;
+						STREAM_TO_UINT32((char *)pucReceivedParams, 0, retValue32);
+						UINT32_TO_STREAM((unsigned char *)pRetParams, retValue32);				
+						break;
+						
+					case HCI_EVNT_BSD_GETHOSTBYNAME:
+						
+						STREAM_TO_UINT32((char *)pucReceivedParams
+						      ,GET_HOST_BY_NAME_RETVAL_OFFSET,*(unsigned long *)pRetParams);
+						pRetParams = ((char *)pRetParams) + 4;
+						STREAM_TO_UINT32((char *)pucReceivedParams
+									,GET_HOST_BY_NAME_ADDR_OFFSET,*(unsigned long *)pRetParams);					
+						break;
+						
+					case HCI_EVNT_ACCEPT:
+						{
+							STREAM_TO_UINT32((char *)pucReceivedParams,ACCEPT_SD_OFFSET
+															 ,*(unsigned long *)pRetParams);
+							pRetParams = ((char *)pRetParams) + 4;
+							STREAM_TO_UINT32((char *)pucReceivedParams
+										,ACCEPT_RETURN_STATUS_OFFSET,*(unsigned long *)pRetParams);
+              pRetParams = ((char *)pRetParams) + 4; 
+							
+							//This argument returns in network order
+							memcpy((unsigned char *)pRetParams, 
+								  pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr));	
+							break;
+						}
+						
+					case HCI_EVNT_RECV:
+					case HCI_EVNT_RECVFROM:
+						{
+							STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams);
+							pRetParams = ((char *)pRetParams) + 4;
+							STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams);
+							pRetParams = ((char *)pRetParams) + 4;
+							STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(unsigned long *)pRetParams);
+							
+							if(((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE)
+							{
+								set_socket_active_status(((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,SOCKET_STATUS_INACTIVE);
+							}
+							break;
+						}
+                                                
+                    case HCI_EVNT_SEND:
+					case HCI_EVNT_SENDTO:
+						{
+							STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams);
+							pRetParams = ((char *)pRetParams) + 4;
+							STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams);
+							pRetParams = ((char *)pRetParams) + 4;
+							
+							break;
+						}
+						
+					case HCI_EVNT_SELECT:
+						{ 
+							STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_STATUS_OFFSET,*(unsigned long *)pRetParams);
+							pRetParams = ((char *)pRetParams) + 4;
+							STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_READFD_OFFSET,*(unsigned long *)pRetParams);
+							pRetParams = ((char *)pRetParams) + 4;
+							STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(unsigned long *)pRetParams);
+							pRetParams = ((char *)pRetParams) + 4;
+							STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_EXFD_OFFSET,*(unsigned long *)pRetParams);			
+							break;
+						}
+						
+					case HCI_CMND_GETSOCKOPT:
+						
+						STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)pRetParams)->iStatus);
+						//This argument returns in network order
+						memcpy((unsigned char *)pRetParams, pucReceivedParams, 4);
+						break;
+						
+					case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS:
+						
+						STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(unsigned long *)pRetParams);
+						pRetParams = ((char *)pRetParams) + 4;   					
+						STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(unsigned long *)pRetParams);
+						pRetParams = ((char *)pRetParams) + 4;                                                        					
+						STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(unsigned long *)pRetParams);
+						pRetParams = ((char *)pRetParams) + 2;   					
+						STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(unsigned long *)pRetParams);
+						pRetParams = ((char *)pRetParams) + 2;  
+						memcpy((unsigned char *)pRetParams, (char *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH);	
+						break;
+						
+					case HCI_CMND_SIMPLE_LINK_START:
+						break;
+						
+					case HCI_NETAPP_IPCONFIG:
+						
+						//Read IP address
+						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
+						RecvParams += 4;
+						
+						//Read subnet
+						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
+						RecvParams += 4;
+						
+						//Read default GW
+						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
+						RecvParams += 4;
+						
+						//Read DHCP server                                          	
+						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
+						RecvParams += 4;
+						
+						//Read DNS server                                           
+						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
+						RecvParams += 4;
+						
+						//Read Mac address                            	
+						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH);
+						RecvParams += 6;
+						
+						//Read SSID
+						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH);
+	
+					}
+				}
+				
+				if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode)
+				{
+					tSLInformation.usRxEventOpcode = 0;
+				}
+			}
+			else
+			{				
+				pucReceivedParams = pucReceivedData;
+				STREAM_TO_UINT8((char *)pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET, ucArgsize);
+				
+				STREAM_TO_UINT16((char *)pucReceivedData, HCI_PACKET_LENGTH_OFFSET, usLength);
+
+				// Data received: note that the only case where from and from length 
+				// are not null is in recv from, so fill the args accordingly
+				if (from)
+				{
+					STREAM_TO_UINT32((char *)(pucReceivedData + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(unsigned long *)fromlen);
+					memcpy(from, (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen);
+				}
+				
+				memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize,
+							 usLength - ucArgsize);
+				
+				tSLInformation.usRxDataPending = 0;
+			}
+		
+			tSLInformation.usEventOrDataReceived = 0;
+			
+			SpiResumeSpi();
+			
+			// Since we are going to TX - we need to handle this event after the 
+			// ResumeSPi since we need interrupts
+			if ((*pucReceivedData == HCI_TYPE_EVNT) &&
+					(usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ))
+			{
+				hci_unsol_handle_patch_request((char *)pucReceivedData);
+			}
+			
+			if ((tSLInformation.usRxEventOpcode == 0) && (tSLInformation.usRxDataPending == 0))
+			{
+				return NULL;
+			}	
+		}
+	}
+
+}
+
+//*****************************************************************************
+//
+//!  hci_unsol_event_handler
+//!
+//!  @param  event_hdr   event header
+//!
+//!  @return             1 if event supported and handled
+//!                      0 if event is not supported
+//!
+//!  @brief              Handle unsolicited events
+//
+//*****************************************************************************
+long
+hci_unsol_event_handler(char *event_hdr)
+{
+	char * data = NULL;
+	long event_type;
+	unsigned long NumberOfReleasedPackets;
+	unsigned long NumberOfSentPackets;
+	
+	STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET,event_type);
+	
+	if (event_type & HCI_EVNT_UNSOL_BASE)
+	{
+		switch(event_type)
+		{
+	
+		case HCI_EVNT_DATA_UNSOL_FREE_BUFF:
+			{
+				hci_event_unsol_flowcontrol_handler(event_hdr);
+				
+				NumberOfReleasedPackets = tSLInformation.NumberOfReleasedPackets;
+				NumberOfSentPackets = tSLInformation.NumberOfSentPackets;
+								
+				if (NumberOfReleasedPackets == NumberOfSentPackets)
+				{
+					if (tSLInformation.InformHostOnTxComplete)
+					{
+						tSLInformation.sWlanCB(HCI_EVENT_CC3000_CAN_SHUT_DOWN, NULL, 0);
+					}
+				}				
+				return 1;
+				
+			}
+		}
+	}
+	
+	if(event_type & HCI_EVNT_WLAN_UNSOL_BASE)
+	{           
+		switch(event_type)
+		{
+		case HCI_EVNT_WLAN_KEEPALIVE:
+		case HCI_EVNT_WLAN_UNSOL_CONNECT:
+		case HCI_EVNT_WLAN_UNSOL_DISCONNECT:
+		case HCI_EVNT_WLAN_UNSOL_INIT:
+		case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE:
+			
+			if( tSLInformation.sWlanCB )
+			{
+				tSLInformation.sWlanCB(event_type, 0, 0);
+			}
+			break;
+			
+		case HCI_EVNT_WLAN_UNSOL_DHCP:
+			{
+				unsigned char	params[NETAPP_IPCONFIG_MAC_OFFSET + 1];	// extra byte is for the status
+				unsigned char *recParams = params;
+				
+				data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE;
+				
+				//Read IP address
+				STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
+				data += 4;
+				//Read subnet
+				STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
+				data += 4;
+				//Read default GW
+				STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); 
+				data += 4;
+				//Read DHCP server  
+				STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);     
+				data += 4;
+				//Read DNS server  
+				STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); 
+				// read the status
+				STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, *recParams);
+
+
+				if( tSLInformation.sWlanCB )
+				{
+					tSLInformation.sWlanCB(event_type, (char *)params, sizeof(params));
+				}
+			}
+			break;
+			
+		case HCI_EVNT_WLAN_ASYNC_PING_REPORT:
+			{
+				netapp_pingreport_args_t params;			
+				data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE;			
+				STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, params.packets_sent);			
+				STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_RCVD_OFFSET, params.packets_received);			
+				STREAM_TO_UINT32(data, NETAPP_PING_MIN_RTT_OFFSET, params.min_round_time);		
+				STREAM_TO_UINT32(data, NETAPP_PING_MAX_RTT_OFFSET, params.max_round_time);	
+				STREAM_TO_UINT32(data, NETAPP_PING_AVG_RTT_OFFSET, params.avg_round_time);
+				
+				if( tSLInformation.sWlanCB )
+				{
+					tSLInformation.sWlanCB(event_type, (char *)&params, sizeof(params));
+				}
+			}
+			break;
+		case HCI_EVNT_BSD_TCP_CLOSE_WAIT:
+			{
+				data = (char *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
+				if( tSLInformation.sWlanCB )
+				{
+					tSLInformation.sWlanCB(event_type, data, 0);
+				}
+			}
+			break;
+			
+		//'default' case which means "event not supported" 	
+		default: 
+			return (0);
+		}
+		return(1);
+	}
+	
+	if ((event_type == HCI_EVNT_SEND) || (event_type == HCI_EVNT_SENDTO)
+			|| (event_type == HCI_EVNT_WRITE))
+	{
+                char *pArg;
+                long status;
+                
+                pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr);
+                STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET,status);
+                
+                if (ERROR_SOCKET_INACTIVE == status)
+                {
+                    // The only synchronous event that can come from SL device in form of 
+                    // command complete is "Command Complete" on data sent, in case SL device 
+                    // was unable to transmit
+                    STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, tSLInformation.slTransmitDataError);
+                    update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr));
+                    
+                    return (1);
+                }
+                else
+                    return (0);
+	}
+	
+	return(0);
+}
+
+//*****************************************************************************
+//
+//!  hci_unsolicited_event_handler
+//!
+//!  @param None
+//!
+//!  @return         ESUCCESS if successful, EFAIL if an error occurred
+//!
+//!  @brief          Parse the incoming unsolicited event packets and issues 
+//!                  corresponding event handler.
+//
+//*****************************************************************************
+long
+hci_unsolicited_event_handler(void)
+{
+	unsigned long   res = 0;
+	unsigned char *pucReceivedData;
+	
+	if (tSLInformation.usEventOrDataReceived != 0)
+	{
+		pucReceivedData = (tSLInformation.pucReceivedData);
+		
+		if (*pucReceivedData == HCI_TYPE_EVNT)
+		{			
+			
+			// In case unsolicited event received - here the handling finished
+			if (hci_unsol_event_handler((char *)pucReceivedData) == 1)
+			{
+				
+				// There was an unsolicited event received - we can release the buffer
+				// and clean the event received 
+				tSLInformation.usEventOrDataReceived = 0;
+				
+				res = 1;
+				SpiResumeSpi();
+			}
+		}
+	}
+	
+	return res;
+}
+
+//*****************************************************************************
+//
+//!  set_socket_active_status
+//!
+//!  @param Sd
+//!	 @param Status
+//!  @return         none
+//!
+//!  @brief          Check if the socket ID and status are valid and set 
+//!                  accordingly  the global socket status
+//
+//*****************************************************************************
+void set_socket_active_status(long Sd, long Status)
+{
+	if(M_IS_VALID_SD(Sd) && M_IS_VALID_STATUS(Status))
+	{
+		socket_active_status &= ~(1 << Sd);      /* clean socket's mask */
+		socket_active_status |= (Status << Sd); /* set new socket's mask */
+	}
+}
+
+
+//*****************************************************************************
+//
+//!  hci_event_unsol_flowcontrol_handler
+//!
+//!  @param  pEvent  pointer to the string contains parameters for IPERF
+//!  @return         ESUCCESS if successful, EFAIL if an error occurred
+//!
+//!  @brief  Called in case unsolicited event from type
+//!          HCI_EVNT_DATA_UNSOL_FREE_BUFF has received.
+//!				   Keep track on the number of packets transmitted and update the
+//!					 number of free buffer in the SL device.
+//
+//*****************************************************************************
+long
+hci_event_unsol_flowcontrol_handler(char *pEvent)
+{
+	
+	long temp, value;
+	unsigned short i;
+	unsigned short  pusNumberOfHandles=0;
+	char *pReadPayload;
+	
+	STREAM_TO_UINT16((char *)pEvent,HCI_EVENT_HEADER_SIZE,pusNumberOfHandles);
+	pReadPayload = ((char *)pEvent +
+									HCI_EVENT_HEADER_SIZE + sizeof(pusNumberOfHandles));	
+	temp = 0;
+	
+	for(i = 0; i < pusNumberOfHandles ; i++)
+	{
+		STREAM_TO_UINT16(pReadPayload, FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET, value);
+		temp += value;
+		pReadPayload += FLOW_CONTROL_EVENT_SIZE;  
+	}
+	
+	tSLInformation.usNumberOfFreeBuffers += temp;
+	tSLInformation.NumberOfReleasedPackets += temp;
+	
+	return(ESUCCESS);
+}
+
+//*****************************************************************************
+//
+//!  get_socket_active_status
+//!
+//!  @param  Sd  Socket IS
+//!  @return     Current status of the socket.   
+//!
+//!  @brief  Retrieve socket status
+//
+//*****************************************************************************
+
+long
+get_socket_active_status(long Sd)
+{
+	if(M_IS_VALID_SD(Sd))
+	{
+		return (socket_active_status & (1 << Sd)) ? SOCKET_STATUS_INACTIVE : SOCKET_STATUS_ACTIVE;
+	}
+	return SOCKET_STATUS_INACTIVE;
+}
+
+//*****************************************************************************
+//
+//!  update_socket_active_status
+//!
+//!  @param  resp_params  Socket IS
+//!  @return     Current status of the socket.   
+//!
+//!  @brief  Retrieve socket status
+//
+//*****************************************************************************
+void
+update_socket_active_status(char *resp_params)
+{
+	long status, sd;
+	
+	STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_SOCKET_OFFSET,sd);
+	STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_STATUS_OFFSET,status);
+	
+	if(ERROR_SOCKET_INACTIVE == status)
+	{
+		set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
+	}
+}
+
+
+//*****************************************************************************
+//
+//!  SimpleLinkWaitEvent
+//!
+//!  @param  usOpcode      command operation code
+//!  @param  pRetParams    command return parameters
+//!
+//!  @return               none
+//!
+//!  @brief                Wait for event, pass it to the hci_event_handler and
+//!                        update the event opcode in a global variable.
+//
+//*****************************************************************************
+
+void 
+SimpleLinkWaitEvent(unsigned short usOpcode, void *pRetParams)
+{
+	// In the blocking implementation the control to caller will be returned only 
+	// after the end of current transaction
+	tSLInformation.usRxEventOpcode = usOpcode;
+	hci_event_handler(pRetParams, 0, 0);
+}
+
+//*****************************************************************************
+//
+//!  SimpleLinkWaitData
+//!
+//!  @param  pBuf       data buffer
+//!  @param  from       from information
+//!  @param  fromlen	from information length
+//!
+//!  @return               none
+//!
+//!  @brief                Wait for data, pass it to the hci_event_handler
+//! 					   and update in a global variable that there is 
+//!						   data to read.
+//
+//*****************************************************************************
+
+void 
+SimpleLinkWaitData(unsigned char *pBuf, unsigned char *from, 
+									 unsigned char *fromlen)
+{
+	// In the blocking implementation the control to caller will be returned only 
+	// after the end of current transaction, i.e. only after data will be received
+	tSLInformation.usRxDataPending = 1;
+	hci_event_handler(pBuf, from, fromlen);
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/evnt_handler.h b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/evnt_handler.h
new file mode 100644
index 0000000000000000000000000000000000000000..b79d5adda8cd0a98c828d5d87473d7f5053d91d8
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/evnt_handler.h
@@ -0,0 +1,166 @@
+/*****************************************************************************
+*
+*  evnt_handler.h  - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the   
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#ifndef __EVENT_HANDLER_H__
+#define __EVENT_HANDLER_H__
+#include "hci.h"
+#include "socket.h"
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+//*****************************************************************************
+//
+// Prototypes for the APIs.
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+//!  hci_event_handler
+//!
+//!  @param  pRetParams     incoming data buffer
+//!  @param  from           from information (in case of data received)
+//!  @param  fromlen        from information length (in case of data received)
+//!
+//!  @return         none
+//!
+//!  @brief          Parse the incoming events packets and issues corresponding
+//!                  event handler from global array of handlers pointers
+//
+//*****************************************************************************
+extern unsigned char *hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen);
+
+//*****************************************************************************
+//
+//!  hci_unsol_event_handler
+//!
+//!  @param  event_hdr   event header
+//!
+//!  @return             1 if event supported and handled
+//!                      0 if event is not supported
+//!
+//!  @brief              Handle unsolicited events
+//
+//*****************************************************************************
+extern long hci_unsol_event_handler(char *event_hdr);
+
+//*****************************************************************************
+//
+//!  hci_unsolicited_event_handler
+//!
+//!  @param None
+//!
+//!  @return         ESUCCESS if successful, EFAIL if an error occurred
+//!
+//!  @brief          Parse the incoming unsolicited event packets and issues 
+//!                  corresponding event handler.
+//
+//*****************************************************************************
+extern long hci_unsolicited_event_handler(void);
+
+#define M_BSD_RESP_PARAMS_OFFSET(hci_event_hdr)((char *)(hci_event_hdr) + HCI_EVENT_HEADER_SIZE)
+
+#define SOCKET_STATUS_ACTIVE       0
+#define SOCKET_STATUS_INACTIVE     1
+/* Init socket_active_status = 'all ones': init all sockets with SOCKET_STATUS_INACTIVE.
+   Will be changed by 'set_socket_active_status' upon 'connect' and 'accept' calls */
+#define SOCKET_STATUS_INIT_VAL  0xFFFF
+#define M_IS_VALID_SD(sd) ((0 <= (sd)) && ((sd) <= 7))
+#define M_IS_VALID_STATUS(status) (((status) == SOCKET_STATUS_ACTIVE)||((status) == SOCKET_STATUS_INACTIVE))
+
+extern unsigned long socket_active_status;
+
+extern void set_socket_active_status(long Sd, long Status);
+extern long get_socket_active_status(long Sd);
+
+typedef struct _bsd_accept_return_t
+{
+    long             iSocketDescriptor;
+    long             iStatus;
+    sockaddr   		tSocketAddress;
+    
+} tBsdReturnParams;
+
+
+typedef struct _bsd_read_return_t
+{
+    long             iSocketDescriptor;
+    long             iNumberOfBytes;
+    unsigned long	 uiFlags;
+} tBsdReadReturnParams;
+
+#define BSD_RECV_FROM_FROMLEN_OFFSET	(4)
+#define BSD_RECV_FROM_FROM_OFFSET		(16)
+
+
+typedef struct _bsd_select_return_t
+{
+    long					iStatus;
+	unsigned long 			uiRdfd;
+	unsigned long 			uiWrfd;
+	unsigned long 			uiExfd;
+} tBsdSelectRecvParams;
+
+
+typedef struct _bsd_getsockopt_return_t
+{
+	unsigned char			ucOptValue[4];
+	char						iStatus;
+} tBsdGetSockOptReturnParams;
+
+typedef struct _bsd_gethostbyname_return_t
+{
+    long             retVal;
+    long             outputAddress;
+} tBsdGethostbynameParams;
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef  __cplusplus
+}
+#endif // __cplusplus
+
+#endif // __EVENT_HANDLER_H__
+
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/hci.c b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/hci.c
new file mode 100644
index 0000000000000000000000000000000000000000..fe08b602aff45f37a3a99d177378f53989a1e92b
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/hci.c
@@ -0,0 +1,233 @@
+/*****************************************************************************
+*
+*  hci.c  - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the   
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_CC3000
+
+//*****************************************************************************
+//
+//! \addtogroup hci_app
+//! @{
+//
+//*****************************************************************************
+
+#include "cc3000_common.h"
+#include "hci.h"
+#include "../spi.h"
+#include "evnt_handler.h"
+#include "wlan.h"
+
+#define SL_PATCH_PORTION_SIZE		(1000)
+
+
+//*****************************************************************************
+//
+//!  hci_command_send
+//!
+//!  @param  usOpcode     command operation code
+//!  @param  pucBuff      pointer to the command's arguments buffer
+//!  @param  ucArgsLength length of the arguments
+//!
+//!  @return              none
+//!
+//!  @brief               Initiate an HCI command.
+//
+//*****************************************************************************
+unsigned short 
+hci_command_send(unsigned short usOpcode, unsigned char *pucBuff,
+                     unsigned char ucArgsLength)
+{ 
+	unsigned char *stream;
+	
+	stream = (pucBuff + SPI_HEADER_SIZE);
+	
+	UINT8_TO_STREAM(stream, HCI_TYPE_CMND);
+	stream = UINT16_TO_STREAM(stream, usOpcode);
+	UINT8_TO_STREAM(stream, ucArgsLength);
+	
+	//Update the opcode of the event we will be waiting for
+	SpiWrite(pucBuff, ucArgsLength + SIMPLE_LINK_HCI_CMND_HEADER_SIZE);
+	
+	return(0);
+}
+
+//*****************************************************************************
+//
+//!  hci_data_send
+//!
+//!  @param  usOpcode        command operation code
+//!	 @param  ucArgs					 pointer to the command's arguments buffer
+//!  @param  usArgsLength    length of the arguments
+//!  @param  ucTail          pointer to the data buffer
+//!  @param  usTailLength    buffer length
+//!
+//!  @return none
+//!
+//!  @brief              Initiate an HCI data write operation
+//
+//*****************************************************************************
+long
+hci_data_send(unsigned char ucOpcode, 
+							unsigned char *ucArgs,
+							unsigned short usArgsLength, 
+							unsigned short usDataLength,
+							const unsigned char *ucTail,
+							unsigned short usTailLength)
+{
+	unsigned char *stream;
+	
+	stream = ((ucArgs) + SPI_HEADER_SIZE);
+	
+	UINT8_TO_STREAM(stream, HCI_TYPE_DATA);
+	UINT8_TO_STREAM(stream, ucOpcode);
+	UINT8_TO_STREAM(stream, usArgsLength);
+	stream = UINT16_TO_STREAM(stream, usArgsLength + usDataLength + usTailLength);
+	
+	// Send the packet over the SPI
+	SpiWrite(ucArgs, SIMPLE_LINK_HCI_DATA_HEADER_SIZE + usArgsLength + usDataLength + usTailLength);
+	
+	return(ESUCCESS);
+}
+
+
+//*****************************************************************************
+//
+//!  hci_data_command_send
+//!
+//!  @param  usOpcode      command operation code
+//!  @param  pucBuff       pointer to the data buffer
+//!  @param  ucArgsLength  arguments length
+//!  @param  ucDataLength  data length
+//!
+//!  @return none
+//!
+//!  @brief              Prepeare HCI header and initiate an HCI data write operation
+//
+//*****************************************************************************
+void hci_data_command_send(unsigned short usOpcode, unsigned char *pucBuff,
+                     unsigned char ucArgsLength,unsigned short ucDataLength)
+{ 
+ 	unsigned char *stream = (pucBuff + SPI_HEADER_SIZE);
+	
+	UINT8_TO_STREAM(stream, HCI_TYPE_DATA);
+	UINT8_TO_STREAM(stream, usOpcode);
+	UINT8_TO_STREAM(stream, ucArgsLength);
+	stream = UINT16_TO_STREAM(stream, ucArgsLength + ucDataLength);
+	
+	// Send the command over SPI on data channel
+	SpiWrite(pucBuff, ucArgsLength + ucDataLength + SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE);
+	
+	return;
+}
+
+//*****************************************************************************
+//
+//!  hci_patch_send
+//!
+//!  @param  usOpcode      command operation code
+//!  @param  pucBuff       pointer to the command's arguments buffer
+//!  @param  patch         pointer to patch content buffer 
+//!  @param  usDataLength  data length
+//!
+//!  @return              none
+//!
+//!  @brief               Prepeare HCI header and initiate an HCI patch write operation
+//
+//*****************************************************************************
+void
+hci_patch_send(unsigned char ucOpcode, unsigned char *pucBuff, char *patch, unsigned short usDataLength)
+{ 
+ 	unsigned char *data_ptr = (pucBuff + SPI_HEADER_SIZE);
+	unsigned short usTransLength;
+	unsigned char *stream = (pucBuff + SPI_HEADER_SIZE);
+	
+	UINT8_TO_STREAM(stream, HCI_TYPE_PATCH);
+	UINT8_TO_STREAM(stream, ucOpcode);
+	stream = UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE);
+	
+	if (usDataLength <= SL_PATCH_PORTION_SIZE)
+	{
+		UINT16_TO_STREAM(stream, usDataLength);
+		stream = UINT16_TO_STREAM(stream, usDataLength);
+		memcpy((pucBuff + SPI_HEADER_SIZE) + HCI_PATCH_HEADER_SIZE, patch, usDataLength);
+		
+		// Update the opcode of the event we will be waiting for
+		SpiWrite(pucBuff, usDataLength + HCI_PATCH_HEADER_SIZE);
+	}
+	else
+	{
+		
+		usTransLength = (usDataLength/SL_PATCH_PORTION_SIZE);
+		UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE + usTransLength*SIMPLE_LINK_HCI_PATCH_HEADER_SIZE);
+		stream = UINT16_TO_STREAM(stream, SL_PATCH_PORTION_SIZE);
+		memcpy(pucBuff + SPI_HEADER_SIZE + HCI_PATCH_HEADER_SIZE, patch, SL_PATCH_PORTION_SIZE);
+		usDataLength -= SL_PATCH_PORTION_SIZE;
+		patch += SL_PATCH_PORTION_SIZE;
+		
+		// Update the opcode of the event we will be waiting for
+		SpiWrite(pucBuff, SL_PATCH_PORTION_SIZE + HCI_PATCH_HEADER_SIZE);
+		
+		while (usDataLength)
+		{
+			if (usDataLength <= SL_PATCH_PORTION_SIZE)
+			{
+				usTransLength = usDataLength;
+				usDataLength = 0;
+				
+			}
+			else
+			{
+				usTransLength = SL_PATCH_PORTION_SIZE;
+				usDataLength -= usTransLength;
+			}
+			
+			*(unsigned short *)data_ptr = usTransLength;
+			memcpy(data_ptr + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE, patch, usTransLength);
+			patch += usTransLength;
+			
+			// Update the opcode of the event we will be waiting for
+			SpiWrite((unsigned char *)data_ptr, usTransLength + sizeof(usTransLength));
+		}
+	}
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//
+//*****************************************************************************
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/hci.h b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/hci.h
new file mode 100644
index 0000000000000000000000000000000000000000..b714ee95b660b24ee6c249ab72c61d141e29043c
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/hci.h
@@ -0,0 +1,328 @@
+/*****************************************************************************
+*
+*  hci.h  - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the   
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#ifndef __HCI_H__
+#define __HCI_H__
+
+#include "cc3000_common.h"
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+#define SPI_HEADER_SIZE 				   			(5)
+#define SIMPLE_LINK_HCI_CMND_HEADER_SIZE 			(4)
+#define HEADERS_SIZE_CMD        					(SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE)
+#define SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE 		(5)
+#define SIMPLE_LINK_HCI_DATA_HEADER_SIZE 			(5)
+#define SIMPLE_LINK_HCI_PATCH_HEADER_SIZE 			(2)
+
+
+//*****************************************************************************
+//
+// Values that can be used as HCI Commands and HCI Packet header defines
+//
+//*****************************************************************************
+#define  HCI_TYPE_CMND          0x1
+#define  HCI_TYPE_DATA          0x2
+#define  HCI_TYPE_PATCH         0x3
+#define  HCI_TYPE_EVNT          0x4
+
+
+#define HCI_EVENT_PATCHES_DRV_REQ			(1)
+#define HCI_EVENT_PATCHES_FW_REQ			(2)
+#define HCI_EVENT_PATCHES_BOOTLOAD_REQ		(3)
+
+
+#define  HCI_CMND_WLAN_BASE  (0x0000)
+#define  HCI_CMND_WLAN_CONNECT  0x0001
+#define  HCI_CMND_WLAN_DISCONNECT   0x0002
+#define  HCI_CMND_WLAN_IOCTL_SET_SCANPARAM    0x0003
+#define  HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY  0x0004
+#define  HCI_CMND_WLAN_IOCTL_ADD_PROFILE  0x0005
+#define  HCI_CMND_WLAN_IOCTL_DEL_PROFILE  0x0006
+#define  HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS  0x0007
+#define  HCI_CMND_EVENT_MASK    0x0008
+#define  HCI_CMND_WLAN_IOCTL_STATUSGET 0x0009
+#define  HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START        0x000A
+#define  HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP         0x000B
+#define  HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX   0x000C
+#define  HCI_CMND_WLAN_CONFIGURE_PATCH					0x000D
+
+
+#define  HCI_CMND_SOCKET_BASE   0x1000
+#define  HCI_CMND_SOCKET        0x1001
+#define  HCI_CMND_BIND          0x1002
+#define  HCI_CMND_RECV          0x1004
+#define  HCI_CMND_ACCEPT        0x1005
+#define  HCI_CMND_LISTEN        0x1006
+#define  HCI_CMND_CONNECT       0x1007
+#define  HCI_CMND_BSD_SELECT 	0x1008
+#define  HCI_CMND_SETSOCKOPT    0x1009
+#define  HCI_CMND_GETSOCKOPT    0x100A
+#define  HCI_CMND_CLOSE_SOCKET  0x100B
+#define  HCI_CMND_RECVFROM      0x100D
+#define  HCI_CMND_GETHOSTNAME   0x1010
+#define  HCI_CMND_MDNS_ADVERTISE	   0x1011
+
+
+#define HCI_DATA_BASE								0x80
+
+#define HCI_CMND_SEND           					(0x01 + HCI_DATA_BASE)
+#define HCI_CMND_SENDTO        						(0x03 + HCI_DATA_BASE)
+#define HCI_DATA_BSD_RECVFROM						(0x04 + HCI_DATA_BASE)
+#define HCI_DATA_BSD_RECV							(0x05 + HCI_DATA_BASE)
+
+
+#define HCI_CMND_NVMEM_CBASE		(0x0200)
+
+
+#define HCI_CMND_NVMEM_CREATE_ENTRY (0x0203)
+#define HCI_CMND_NVMEM_SWAP_ENTRY  	(0x0205)
+#define HCI_CMND_NVMEM_READ    		(0x0201)
+#define HCI_CMND_NVMEM_WRITE   		(0x0090)
+#define HCI_CMND_NVMEM_WRITE_PATCH	(0x0204)
+#define HCI_CMND_READ_SP_VERSION  	(0x0207)
+
+#define  HCI_CMND_READ_BUFFER_SIZE  0x400B
+#define  HCI_CMND_SIMPLE_LINK_START 0x4000
+
+#define HCI_CMND_NETAPP_BASE		0x2000
+
+#define HCI_NETAPP_DHCP				    (0x0001 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_PING_SEND                        (0x0002 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_PING_REPORT                      (0x0003 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_PING_STOP                        (0x0004 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_IPCONFIG                         (0x0005 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_ARP_FLUSH			    (0x0006 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_SET_DEBUG_LEVEL					(0x0008 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_SET_TIMERS						(0x0009 + HCI_CMND_NETAPP_BASE)
+
+
+
+
+
+
+//*****************************************************************************
+//
+// Values that can be used as HCI Events defines
+//
+//*****************************************************************************
+#define  HCI_EVNT_WLAN_BASE     0x0000
+#define  HCI_EVNT_WLAN_CONNECT  0x0001
+#define  HCI_EVNT_WLAN_DISCONNECT \
+                                0x0002
+#define  HCI_EVNT_WLAN_IOCTL_ADD_PROFILE  \
+                                0x0005
+
+
+#define  HCI_EVNT_SOCKET              HCI_CMND_SOCKET
+#define  HCI_EVNT_BIND                HCI_CMND_BIND
+#define  HCI_EVNT_RECV                HCI_CMND_RECV
+#define  HCI_EVNT_ACCEPT              HCI_CMND_ACCEPT
+#define  HCI_EVNT_LISTEN              HCI_CMND_LISTEN
+#define  HCI_EVNT_CONNECT             HCI_CMND_CONNECT
+#define  HCI_EVNT_SELECT              HCI_CMND_BSD_SELECT
+#define  HCI_EVNT_CLOSE_SOCKET        HCI_CMND_CLOSE_SOCKET
+#define  HCI_EVNT_RECVFROM            HCI_CMND_RECVFROM
+#define  HCI_EVNT_SETSOCKOPT          HCI_CMND_SETSOCKOPT
+#define  HCI_EVNT_GETSOCKOPT          HCI_CMND_GETSOCKOPT
+#define  HCI_EVNT_BSD_GETHOSTBYNAME   HCI_CMND_GETHOSTNAME
+#define  HCI_EVNT_MDNS_ADVERTISE   HCI_CMND_MDNS_ADVERTISE
+ 
+#define  HCI_EVNT_SEND          0x1003
+#define  HCI_EVNT_WRITE         0x100E
+#define  HCI_EVNT_SENDTO        0x100F
+
+#define HCI_EVNT_PATCHES_REQ    0x1000
+
+#define HCI_EVNT_UNSOL_BASE    0x4000
+
+#define HCI_EVNT_WLAN_UNSOL_BASE     (0x8000)
+
+#define HCI_EVNT_WLAN_UNSOL_CONNECT  	 (0x0001 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_UNSOL_DISCONNECT   (0x0002 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_UNSOL_INIT         (0x0004 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_TX_COMPLETE         (0x0008 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_UNSOL_DHCP         (0x0010 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_ASYNC_PING_REPORT  (0x0040 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE  (0x0080 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_KEEPALIVE			 (0x0200  + HCI_EVNT_WLAN_UNSOL_BASE)
+#define	HCI_EVNT_BSD_TCP_CLOSE_WAIT      (0x0800 + HCI_EVNT_WLAN_UNSOL_BASE)
+
+#define HCI_EVNT_DATA_UNSOL_FREE_BUFF \
+                                0x4100
+
+#define HCI_EVNT_NVMEM_CREATE_ENTRY \
+                                HCI_CMND_NVMEM_CREATE_ENTRY
+#define HCI_EVNT_NVMEM_SWAP_ENTRY HCI_CMND_NVMEM_SWAP_ENTRY
+
+#define HCI_EVNT_NVMEM_READ     HCI_CMND_NVMEM_READ
+#define HCI_EVNT_NVMEM_WRITE    (0x0202)
+
+#define HCI_EVNT_READ_SP_VERSION  	\
+				HCI_CMND_READ_SP_VERSION
+
+#define  HCI_EVNT_INPROGRESS    0xFFFF
+
+
+#define HCI_DATA_RECVFROM       0x84
+#define HCI_DATA_RECV           0x85
+#define HCI_DATA_NVMEM          0x91
+
+#define HCI_EVENT_CC3000_CAN_SHUT_DOWN 0x99
+
+//*****************************************************************************
+//
+// Prototypes for the structures for APIs.
+//
+//*****************************************************************************
+
+#define HCI_DATA_HEADER_SIZE		(5)
+#define HCI_EVENT_HEADER_SIZE		(5)
+#define HCI_DATA_CMD_HEADER_SIZE	(5)
+#define HCI_PATCH_HEADER_SIZE		(6)
+
+#define HCI_PACKET_TYPE_OFFSET		(0)
+#define HCI_PACKET_ARGSIZE_OFFSET	(2)
+#define HCI_PACKET_LENGTH_OFFSET	(3)
+
+
+#define HCI_EVENT_OPCODE_OFFSET (1)
+#define HCI_EVENT_LENGTH_OFFSET	(3)
+#define HCI_EVENT_STATUS_OFFSET	(4)
+#define HCI_DATA_LENGTH_OFFSET	(3)
+  
+  
+
+
+//*****************************************************************************
+//
+// Prototypes for the APIs.
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+//!  hci_command_send
+//!
+//!  @param  usOpcode     command operation code
+//!  @param  pucBuff      pointer to the command's arguments buffer
+//!  @param  ucArgsLength length of the arguments
+//!
+//!  @return              none
+//!
+//!  @brief               Initiate an HCI command.
+//
+//*****************************************************************************
+extern unsigned short hci_command_send(unsigned short usOpcode, 
+                                   unsigned char *ucArgs,
+                                   unsigned char ucArgsLength);
+ 
+
+//*****************************************************************************
+//
+//!  hci_data_send
+//!
+//!  @param  usOpcode        command operation code
+//!	 @param  ucArgs					 pointer to the command's arguments buffer
+//!  @param  usArgsLength    length of the arguments
+//!  @param  ucTail          pointer to the data buffer
+//!  @param  usTailLength    buffer length
+//!
+//!  @return none
+//!
+//!  @brief              Initiate an HCI data write operation
+//
+//*****************************************************************************
+extern long hci_data_send(unsigned char ucOpcode,
+                                      unsigned char *ucArgs,
+                                      unsigned short usArgsLength,
+                                      unsigned short usDataLength,
+                                      const unsigned char *ucTail,
+                                      unsigned short usTailLength);
+
+
+//*****************************************************************************
+//
+//!  hci_data_command_send
+//!
+//!  @param  usOpcode      command operation code
+//!  @param  pucBuff       pointer to the data buffer
+//!  @param  ucArgsLength  arguments length
+//!  @param  ucDataLength  data length
+//!
+//!  @return none
+//!
+//!  @brief              Prepare HCI header and initiate an HCI data write operation
+//
+//*****************************************************************************
+extern void hci_data_command_send(unsigned short usOpcode, unsigned char *pucBuff,
+                     unsigned char ucArgsLength, unsigned short ucDataLength);
+
+//*****************************************************************************
+//
+//!  hci_patch_send
+//!
+//!  @param  usOpcode      command operation code
+//!  @param  pucBuff       pointer to the command's arguments buffer
+//!  @param  patch         pointer to patch content buffer 
+//!  @param  usDataLength  data length
+//!
+//!  @return              none
+//!
+//!  @brief               Prepare HCI header and initiate an HCI patch write operation
+//
+//*****************************************************************************
+extern void hci_patch_send(unsigned char ucOpcode, unsigned char *pucBuff, char *patch, unsigned short usDataLength);
+
+
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef  __cplusplus
+}
+#endif // __cplusplus
+
+#endif // __HCI_H__
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/host_driver_version.h b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/host_driver_version.h
new file mode 100644
index 0000000000000000000000000000000000000000..c218704a2ee20696967ee772f2141d8ef1899f60
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/host_driver_version.h
@@ -0,0 +1,55 @@
+/*****************************************************************************
+*
+*  host_driver_version.h  - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the   
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#ifndef __HOST_DRIVER_VERSION_H__
+#define __HOST_DRIVER_VERSION_H__
+
+#define DRIVER_VERSION_NUMBER   13
+
+
+
+#endif // __VERSION_H__
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/netapp.c b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/netapp.c
new file mode 100644
index 0000000000000000000000000000000000000000..b8947ee4ff5c67d5cba4f9e1763caaf09ca7818f
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/netapp.c
@@ -0,0 +1,464 @@
+/*****************************************************************************
+*
+*  netapp.c  - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the   
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_CC3000
+
+#include <string.h>
+#include "netapp.h"
+#include "hci.h"
+#include "socket.h"
+#include "evnt_handler.h"
+#include "nvmem.h"
+
+#define MIN_TIMER_VAL_SECONDS      20
+#define MIN_TIMER_SET(t)    if ((0 != t) && (t < MIN_TIMER_VAL_SECONDS)) \
+                            { \
+                                t = MIN_TIMER_VAL_SECONDS; \
+                            }
+
+
+#define NETAPP_DHCP_PARAMS_LEN 				(20)
+#define NETAPP_SET_TIMER_PARAMS_LEN 		(20)
+#define NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN	(4)
+#define NETAPP_PING_SEND_PARAMS_LEN			(16)
+
+
+//*****************************************************************************
+//
+//!  netapp_config_mac_adrress
+//!
+//!  @param  mac   device mac address, 6 bytes. Saved: yes 
+//!
+//!  @return       return on success 0, otherwise error.
+//!
+//!  @brief        Configure device MAC address and store it in NVMEM. 
+//!                The value of the MAC address configured through the API will
+//!		             be stored in CC3000 non volatile memory, thus preserved 
+//!                over resets.
+//
+//*****************************************************************************
+long netapp_config_mac_adrress(unsigned char * mac)
+{
+	return  nvmem_set_mac_address(mac);
+}
+
+//*****************************************************************************
+//
+//!  netapp_dhcp
+//!
+//!  @param  aucIP               device mac address, 6 bytes. Saved: yes 
+//!  @param  aucSubnetMask       device mac address, 6 bytes. Saved: yes 
+//!  @param  aucDefaultGateway   device mac address, 6 bytes. Saved: yes 
+//!  @param  aucDNSServer        device mac address, 6 bytes. Saved: yes 
+//!
+//!  @return       return on success 0, otherwise error.
+//!
+//!  @brief       netapp_dhcp is used to configure the network interface, 
+//!               static or dynamic (DHCP).\n In order to activate DHCP mode, 
+//!               aucIP, aucSubnetMask, aucDefaultGateway must be 0.
+//!               The default mode of CC3000 is DHCP mode.
+//!               Note that the configuration is saved in non volatile memory
+//!               and thus preserved over resets.
+//!	 
+//! @note         If the mode is altered a reset of CC3000 device is required 
+//!               in order to apply changes.\nAlso note that asynchronous event 
+//!               of DHCP_EVENT, which is generated when an IP address is 
+//!               allocated either by the DHCP server or due to static 
+//!               allocation is generated only upon a connection to the 
+//!               AP was established. 
+//!
+//*****************************************************************************
+long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned long *aucDefaultGateway, unsigned long *aucDNSServer)
+{
+	signed char scRet;
+	unsigned char *ptr;
+	unsigned char *args;
+	
+	scRet = EFAIL;
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in temporary command buffer
+	ARRAY_TO_STREAM(args,aucIP,4);
+	ARRAY_TO_STREAM(args,aucSubnetMask,4);
+	ARRAY_TO_STREAM(args,aucDefaultGateway,4);
+	args = UINT32_TO_STREAM(args, 0);
+	ARRAY_TO_STREAM(args,aucDNSServer,4);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_NETAPP_DHCP, ptr, NETAPP_DHCP_PARAMS_LEN);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_NETAPP_DHCP, &scRet);
+	
+	return(scRet);
+}
+
+
+//*****************************************************************************
+//
+//!  netapp_timeout_values
+//!
+//!  @param  aucDHCP    DHCP lease time request, also impact 
+//!                     the DHCP renew timeout. Range: [0-0xffffffff] seconds,
+//!                     0 or 0xffffffff == infinity lease timeout.
+//!                     Resolution:10 seconds. Influence: only after 
+//!                     reconnecting to the AP. 
+//!                     Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds.
+//!                     The parameter is saved into the CC3000 NVMEM. 
+//!                     The default value on CC3000 is 14400 seconds.
+//!	 
+//!  @param  aucARP     ARP refresh timeout, if ARP entry is not updated by
+//!                     incoming packet, the ARP entry will be  deleted by
+//!                     the end of the timeout. 
+//!                     Range: [0-0xffffffff] seconds, 0 == infinity ARP timeout
+//!                     Resolution: 10 seconds. Influence: on runtime.
+//!                     Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds
+//!                     The parameter is saved into the CC3000 NVMEM. 
+//!	                    The default value on CC3000 is 3600 seconds.
+//!
+//!  @param  aucKeepalive   Keepalive event sent by the end of keepalive timeout
+//!                         Range: [0-0xffffffff] seconds, 0 == infinity timeout
+//!                         Resolution: 10 seconds.
+//!                         Influence: on runtime.
+//!                         Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec
+//!                         The parameter is saved into the CC3000 NVMEM. 
+//!                         The default value on CC3000 is 10 seconds.
+//!
+//!  @param  aucInactivity   Socket inactivity timeout, socket timeout is
+//!                          refreshed by incoming or outgoing packet, by the
+//!                          end of the socket timeout the socket will be closed
+//!                          Range: [0-0xffffffff] sec, 0 == infinity timeout.
+//!                          Resolution: 10 seconds. Influence: on runtime.
+//!                          Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec
+//!                          The parameter is saved into the CC3000 NVMEM. 
+//!	                         The default value on CC3000 is 60 seconds.
+//!
+//!  @return       return on success 0, otherwise error.
+//!
+//!  @brief       Set new timeout values. Function set new timeout values for: 
+//!               DHCP lease timeout, ARP  refresh timeout, keepalive event 
+//!               timeout and socket inactivity timeout 
+//!	 
+//! @note         If a parameter set to non zero value which is less than 20s,
+//!               it will be set automatically to 20s.
+//!
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+long 
+netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP,unsigned long *aucKeepalive,	unsigned long *aucInactivity)
+{
+	signed char scRet;
+	unsigned char *ptr;
+	unsigned char *args;
+	
+	scRet = EFAIL;
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + HEADERS_SIZE_CMD);
+	
+	// Set minimal values of timers 
+	MIN_TIMER_SET(*aucDHCP)
+    MIN_TIMER_SET(*aucARP)
+	MIN_TIMER_SET(*aucKeepalive)
+	MIN_TIMER_SET(*aucInactivity)
+					
+	// Fill in temporary command buffer
+	args = UINT32_TO_STREAM(args, *aucDHCP);
+	args = UINT32_TO_STREAM(args, *aucARP);
+	args = UINT32_TO_STREAM(args, *aucKeepalive);
+	args = UINT32_TO_STREAM(args, *aucInactivity);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_NETAPP_SET_TIMERS, ptr, NETAPP_SET_TIMER_PARAMS_LEN);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_NETAPP_SET_TIMERS, &scRet);
+	
+	return(scRet);
+}
+#endif
+
+
+//*****************************************************************************
+//
+//!  netapp_ping_send
+//!
+//!  @param  ip              destination IP address
+//!  @param  pingAttempts    number of echo requests to send
+//!  @param  pingSize        send buffer size which may be up to 1400 bytes 
+//!  @param  pingTimeout     Time to wait for a response,in milliseconds.
+//!
+//!  @return       return on success 0, otherwise error.
+//!
+//!  @brief       send ICMP ECHO_REQUEST to network hosts 
+//!	 
+//! @note         If an operation finished successfully asynchronous ping report 
+//!               event will be generated. The report structure is as defined
+//!               by structure netapp_pingreport_args_t.
+//!
+//! @warning      Calling this function while a previous Ping Requests are in 
+//!               progress will stop the previous ping request.
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+long
+netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, unsigned long ulPingSize, unsigned long ulPingTimeout)
+{
+	signed char scRet;
+	unsigned char *ptr, *args;
+	
+	scRet = EFAIL;
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in temporary command buffer
+	args = UINT32_TO_STREAM(args, *ip);
+	args = UINT32_TO_STREAM(args, ulPingAttempts);
+	args = UINT32_TO_STREAM(args, ulPingSize);
+	args = UINT32_TO_STREAM(args, ulPingTimeout);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_NETAPP_PING_SEND, ptr, NETAPP_PING_SEND_PARAMS_LEN);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_NETAPP_PING_SEND, &scRet);
+	
+	return(scRet);
+}
+#endif
+
+//*****************************************************************************
+//
+//!  netapp_ping_report
+//!
+//!  @param  none
+//!
+//!  @return  none
+//!
+//!  @brief   Request for ping status. This API triggers the CC3000 to send 
+//!           asynchronous events: HCI_EVNT_WLAN_ASYNC_PING_REPORT.
+//!           This event will carry  the report structure:
+//!           netapp_pingreport_args_t. This structure is filled in with ping
+//!           results up till point of triggering API.
+//!           netapp_pingreport_args_t:\n packets_sent - echo sent,
+//!           packets_received - echo reply, min_round_time - minimum
+//!           round time, max_round_time - max round time,
+//!           avg_round_time - average round time
+//!	 
+//! @note     When a ping operation is not active, the returned structure 
+//!           fields are 0.
+//!
+//*****************************************************************************
+
+
+#ifndef CC3000_TINY_DRIVER
+void netapp_ping_report()
+{
+	unsigned char *ptr;
+	ptr = tSLInformation.pucTxCommandBuffer;
+	signed char scRet;
+	
+	scRet = EFAIL;
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_NETAPP_PING_REPORT, ptr, 0);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_NETAPP_PING_REPORT, &scRet); 
+}
+#endif
+
+//*****************************************************************************
+//
+//!  netapp_ping_stop
+//!
+//!  @param  none
+//!
+//!  @return  On success, zero is returned. On error, -1 is returned.      
+//!
+//!  @brief   Stop any ping request.
+//!	 
+//!
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+long netapp_ping_stop()
+{
+	signed char scRet;
+	unsigned char *ptr;
+	
+	scRet = EFAIL;
+	ptr = tSLInformation.pucTxCommandBuffer;
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_NETAPP_PING_STOP, ptr, 0);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_NETAPP_PING_STOP, &scRet);
+	
+	return(scRet);
+}
+#endif
+
+//*****************************************************************************
+//
+//!  netapp_ipconfig
+//!
+//!  @param[out]  ipconfig  This argument is a pointer to a 
+//!                         tNetappIpconfigRetArgs structure. This structure is
+//!                         filled in with the network interface configuration.
+//!                         tNetappIpconfigRetArgs:\n aucIP - ip address,
+//!                         aucSubnetMask - mask, aucDefaultGateway - default
+//!                         gateway address, aucDHCPServer - dhcp server address
+//!                         aucDNSServer - dns server address, uaMacAddr - mac
+//!                         address, uaSSID - connected AP ssid
+//!
+//!  @return  none
+//!
+//!  @brief   Obtain the CC3000 Network interface information.
+//!           Note that the information is available only after the WLAN
+//!       		connection was established. Calling this function before
+//!           associated, will cause non-defined values to be returned.
+//!	 
+//! @note     The function is useful for figuring out the IP Configuration of
+//!       		the device when DHCP is used and for figuring out the SSID of
+//!       		the Wireless network the device is associated with.
+//!
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig )
+{
+	unsigned char *ptr;
+	
+	ptr = tSLInformation.pucTxCommandBuffer;
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_NETAPP_IPCONFIG, ptr, 0);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_NETAPP_IPCONFIG, ipconfig );
+	
+}
+#else
+void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig )
+{
+
+}
+#endif
+
+//*****************************************************************************
+//
+//!  netapp_arp_flush
+//!
+//!  @param  none
+//!
+//!  @return  none
+//!
+//!  @brief  Flushes ARP table
+//!
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+long netapp_arp_flush(void)
+{
+	signed char scRet;
+	unsigned char *ptr;
+	
+	scRet = EFAIL;
+	ptr = tSLInformation.pucTxCommandBuffer;
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_NETAPP_ARP_FLUSH, ptr, 0);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_NETAPP_ARP_FLUSH, &scRet);
+	
+	return(scRet);
+}
+#endif
+
+//*****************************************************************************
+//
+//!  netapp_set_debug_level
+//!
+//!  @param[in]      level    debug level. Bitwise [0-8],
+//!                         0(disable)or 1(enable).\n Bitwise map: 0 - Critical
+//!                         message, 1 information message, 2 - core messages, 3 -
+//!                         HCI messages, 4 - Network stack messages, 5 - wlan
+//!                         messages, 6 - wlan driver messages, 7 - epprom messages,
+//!                         8 - general messages. Default: 0x13f. Saved: no
+//!
+//!  @return  On success, zero is returned. On error, -1 is returned
+//!
+//!  @brief   Debug messages sent via the UART debug channel, this function
+//!              enable/disable the debug level
+//!
+//*****************************************************************************
+
+
+#ifndef CC3000_TINY_DRIVER
+long netapp_set_debug_level(unsigned long ulLevel)
+{
+	signed char scRet;
+    unsigned char *ptr, *args;
+
+    scRet = EFAIL;
+    ptr = tSLInformation.pucTxCommandBuffer;
+    args = (ptr + HEADERS_SIZE_CMD);
+
+    //
+    // Fill in temporary command buffer
+    //
+    args = UINT32_TO_STREAM(args, ulLevel);
+
+
+    //
+    // Initiate a HCI command
+    //
+    hci_command_send(HCI_NETAPP_SET_DEBUG_LEVEL, ptr, NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN);
+
+    //
+	// Wait for command complete event
+	//
+	SimpleLinkWaitEvent(HCI_NETAPP_SET_DEBUG_LEVEL, &scRet);
+
+    return(scRet);
+
+}
+#endif
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/netapp.h b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/netapp.h
new file mode 100644
index 0000000000000000000000000000000000000000..8c9e7e83d3ccf7c9db075b41387397aba6e89be0
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/netapp.h
@@ -0,0 +1,342 @@
+/*****************************************************************************
+*
+*  netapp.h  - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the   
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#ifndef __NETAPP_H__
+#define	__NETAPP_H__
+
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+//*****************************************************************************
+//
+//! \addtogroup netapp_api
+//! @{
+//
+//*****************************************************************************
+
+typedef struct _netapp_dhcp_ret_args_t
+{
+    unsigned char aucIP[4];
+	unsigned char aucSubnetMask[4];
+	unsigned char aucDefaultGateway[4];
+	unsigned char aucDHCPServer[4];
+	unsigned char aucDNSServer[4];
+}tNetappDhcpParams;
+
+typedef struct _netapp_ipconfig_ret_args_t
+{
+    unsigned char aucIP[4];
+	unsigned char aucSubnetMask[4];
+	unsigned char aucDefaultGateway[4];
+	unsigned char aucDHCPServer[4];
+	unsigned char aucDNSServer[4];
+	unsigned char uaMacAddr[6];
+	unsigned char uaSSID[32];
+}tNetappIpconfigRetArgs;
+
+
+/*Ping send report parameters*/
+typedef struct _netapp_pingreport_args
+{
+	unsigned long packets_sent;
+	unsigned long packets_received;
+	unsigned long min_round_time;
+	unsigned long max_round_time;
+	unsigned long avg_round_time;
+} netapp_pingreport_args_t;
+
+
+//*****************************************************************************
+//
+//!  netapp_config_mac_adrress
+//!
+//!  @param  mac   device mac address, 6 bytes. Saved: yes 
+//!
+//!  @return       return on success 0, otherwise error.
+//!
+//!  @brief        Configure device MAC address and store it in NVMEM. 
+//!                The value of the MAC address configured through the API will
+//!		             be stored in CC3000 non volatile memory, thus preserved 
+//!                over resets.
+//
+//*****************************************************************************
+extern long  netapp_config_mac_adrress( unsigned char *mac );
+
+//*****************************************************************************
+//
+//!  netapp_dhcp
+//!
+//!  @param  aucIP               device mac address, 6 bytes. Saved: yes 
+//!  @param  aucSubnetMask       device mac address, 6 bytes. Saved: yes 
+//!  @param  aucDefaultGateway   device mac address, 6 bytes. Saved: yes 
+//!  @param  aucDNSServer        device mac address, 6 bytes. Saved: yes 
+//!
+//!  @return       return on success 0, otherwise error.
+//!
+//!  @brief       netapp_dhcp is used to configure the network interface, 
+//!               static or dynamic (DHCP).\n In order to activate DHCP mode, 
+//!               aucIP, aucSubnetMask, aucDefaultGateway must be 0.
+//!               The default mode of CC3000 is DHCP mode.
+//!               Note that the configuration is saved in non volatile memory
+//!               and thus preserved over resets.
+//!	 
+//! @note         If the mode is altered a reset of CC3000 device is required 
+//!               in order to apply changes.\nAlso note that asynchronous event 
+//!               of DHCP_EVENT, which is generated when an IP address is 
+//!               allocated either by the DHCP server or due to static 
+//!               allocation is generated only upon a connection to the 
+//!               AP was established. 
+//!
+//*****************************************************************************
+extern 	long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned long *aucDefaultGateway, unsigned long *aucDNSServer);
+
+
+
+//*****************************************************************************
+//
+//!  netapp_timeout_values
+//!
+//!  @param  aucDHCP    DHCP lease time request, also impact 
+//!                     the DHCP renew timeout. Range: [0-0xffffffff] seconds,
+//!                     0 or 0xffffffff == infinity lease timeout.
+//!                     Resolution:10 seconds. Influence: only after 
+//!                     reconnecting to the AP. 
+//!                     Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds.
+//!                     The parameter is saved into the CC3000 NVMEM. 
+//!                     The default value on CC3000 is 14400 seconds.
+//!	 
+//!  @param  aucARP     ARP refresh timeout, if ARP entry is not updated by
+//!                     incoming packet, the ARP entry will be  deleted by
+//!                     the end of the timeout. 
+//!                     Range: [0-0xffffffff] seconds, 0 == infinity ARP timeout
+//!                     Resolution: 10 seconds. Influence: on runtime.
+//!                     Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds
+//!                     The parameter is saved into the CC3000 NVMEM. 
+//!	                    The default value on CC3000 is 3600 seconds.
+//!
+//!  @param  aucKeepalive   Keepalive event sent by the end of keepalive timeout
+//!                         Range: [0-0xffffffff] seconds, 0 == infinity timeout
+//!                         Resolution: 10 seconds.
+//!                         Influence: on runtime.
+//!                         Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec
+//!                         The parameter is saved into the CC3000 NVMEM. 
+//!                         The default value on CC3000 is 10 seconds.
+//!
+//!  @param  aucInactivity   Socket inactivity timeout, socket timeout is
+//!                          refreshed by incoming or outgoing packet, by the
+//!                          end of the socket timeout the socket will be closed
+//!                          Range: [0-0xffffffff] sec, 0 == infinity timeout.
+//!                          Resolution: 10 seconds. Influence: on runtime.
+//!                          Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec
+//!                          The parameter is saved into the CC3000 NVMEM. 
+//!	                         The default value on CC3000 is 60 seconds.
+//!
+//!  @return       return on success 0, otherwise error.
+//!
+//!  @brief       Set new timeout values. Function set new timeout values for: 
+//!               DHCP lease timeout, ARP  refresh timeout, keepalive event 
+//!               timeout and socket inactivity timeout 
+//!	 
+//! @note         If a parameter set to non zero value which is less than 20s,
+//!               it will be set automatically to 20s.
+//!
+//*****************************************************************************
+ #ifndef CC3000_TINY_DRIVER
+extern long netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP,unsigned long *aucKeepalive,	unsigned long *aucInactivity);
+#endif
+
+//*****************************************************************************
+//
+//!  netapp_ping_send
+//!
+//!  @param  ip              destination IP address
+//!  @param  pingAttempts    number of echo requests to send
+//!  @param  pingSize        send buffer size which may be up to 1400 bytes 
+//!  @param  pingTimeout     Time to wait for a response,in milliseconds.
+//!
+//!  @return       return on success 0, otherwise error.
+//!
+//!  @brief       send ICMP ECHO_REQUEST to network hosts 
+//!	 
+//! @note         If an operation finished successfully asynchronous ping report 
+//!               event will be generated. The report structure is as defined
+//!               by structure netapp_pingreport_args_t.
+//!
+//! @warning      Calling this function while a previous Ping Requests are in 
+//!               progress will stop the previous ping request.
+//*****************************************************************************
+
+ #ifndef CC3000_TINY_DRIVER
+extern long netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, unsigned long ulPingSize, unsigned long ulPingTimeout);
+#endif
+
+//*****************************************************************************
+//
+//!  netapp_ping_stop
+//!
+//!  @param  none
+//!
+//!  @return  On success, zero is returned. On error, -1 is returned.      
+//!
+//!  @brief   Stop any ping request.
+//!	 
+//!
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+extern long netapp_ping_stop();
+#endif
+//*****************************************************************************
+//
+//!  netapp_ping_report
+//!
+//!  @param  none
+//!
+//!  @return  none
+//!
+//!  @brief   Request for ping status. This API triggers the CC3000 to send 
+//!           asynchronous events: HCI_EVNT_WLAN_ASYNC_PING_REPORT.
+//!           This event will carry  the report structure:
+//!           netapp_pingreport_args_t. This structure is filled in with ping
+//!           results up till point of triggering API.
+//!           netapp_pingreport_args_t:\n packets_sent - echo sent,
+//!           packets_received - echo reply, min_round_time - minimum
+//!           round time, max_round_time - max round time,
+//!           avg_round_time - average round time
+//!	 
+//! @note     When a ping operation is not active, the returned structure 
+//!           fields are 0.
+//!
+//*****************************************************************************
+#ifndef CC3000_TINY_DRIVER
+extern void netapp_ping_report();
+#endif
+
+
+//*****************************************************************************
+//
+//!  netapp_ipconfig
+//!
+//!  @param[out]  ipconfig  This argument is a pointer to a 
+//!                         tNetappIpconfigRetArgs structure. This structure is
+//!                         filled in with the network interface configuration.
+//!                         tNetappIpconfigRetArgs:\n aucIP - ip address,
+//!                         aucSubnetMask - mask, aucDefaultGateway - default
+//!                         gateway address, aucDHCPServer - dhcp server address
+//!                         aucDNSServer - dns server address, uaMacAddr - mac
+//!                         address, uaSSID - connected AP ssid
+//!
+//!  @return  none
+//!
+//!  @brief   Obtain the CC3000 Network interface information.
+//!           Note that the information is available only after the WLAN
+//!       	  connection was established. Calling this function before
+//!           associated, will cause non-defined values to be returned.
+//!	 
+//! @note     The function is useful for figuring out the IP Configuration of
+//!       		the device when DHCP is used and for figuring out the SSID of
+//!       		the Wireless network the device is associated with.
+//!
+//*****************************************************************************
+
+extern void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig );
+
+
+//*****************************************************************************
+//
+//!  netapp_arp_flush
+//!
+//!  @param  none
+//!
+//!  @return  none
+//!
+//!  @brief  Flushes ARP table
+//!
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+extern long netapp_arp_flush();
+#endif
+
+
+//*****************************************************************************
+//
+//!  netapp_set_debug_level
+//!
+//!  @param[in]      level    debug level. Bitwise [0-8],
+//!                         0(disable)or 1(enable).\n Bitwise map: 0 - Critical
+//!                         message, 1 information message, 2 - core messages, 3 -
+//!                         HCI messages, 4 - Network stack messages, 5 - wlan
+//!                         messages, 6 - wlan driver messages, 7 - epprom messages,
+//!                         8 - general messages. Default: 0x13f. Saved: no
+//!
+//!  @return  On success, zero is returned. On error, -1 is returned
+//!
+//!  @brief   Debug messages sent via the UART debug channel, this function
+//!              enable/disable the debug level
+//!
+//*****************************************************************************
+
+
+#ifndef CC3000_TINY_DRIVER
+long netapp_set_debug_level(unsigned long ulLevel);
+#endif
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef	__cplusplus
+}
+#endif // __cplusplus
+
+#endif	// __NETAPP_H__
+
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/nvmem.c b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/nvmem.c
new file mode 100644
index 0000000000000000000000000000000000000000..572a0f5dc2bdb6172317701e21ab52788b671d92
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/nvmem.c
@@ -0,0 +1,343 @@
+/*****************************************************************************
+*
+*  nvmem.c  - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the   
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_CC3000
+
+//*****************************************************************************
+//
+//! \addtogroup nvmem_api
+//! @{
+//
+//*****************************************************************************
+
+#include <stdio.h>
+#include <string.h>
+#include "nvmem.h"
+#include "hci.h"
+#include "socket.h"
+#include "evnt_handler.h"
+
+//*****************************************************************************
+//
+// Prototypes for the structures for APIs.
+//
+//*****************************************************************************
+
+#define NVMEM_READ_PARAMS_LEN 	(12)
+#define NVMEM_CREATE_PARAMS_LEN 	(8)
+#define NVMEM_WRITE_PARAMS_LEN  (16)
+
+//*****************************************************************************
+//
+//!  nvmem_read
+//!
+//!  @param  ulFileId   nvmem file id:\n
+//!                     NVMEM_NVS_FILEID, NVMEM_NVS_SHADOW_FILEID,
+//!                     NVMEM_WLAN_CONFIG_FILEID, NVMEM_WLAN_CONFIG_SHADOW_FILEID,
+//!                     NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
+//!                     NVMEM_MAC_FILEID, NVMEM_FRONTEND_VARS_FILEID,
+//!                     NVMEM_IP_CONFIG_FILEID, NVMEM_IP_CONFIG_SHADOW_FILEID,
+//!                     NVMEM_BOOTLOADER_SP_FILEID, NVMEM_RM_FILEID,
+//!                     and user files 12-15.
+//!  @param  ulLength    number of bytes to read 
+//!  @param  ulOffset    ulOffset in file from where to read  
+//!  @param  buff        output buffer pointer
+//!
+//!  @return       number of bytes read, otherwise error.
+//!
+//!  @brief       Reads data from the file referred by the ulFileId parameter. 
+//!               Reads data from file ulOffset till length. Err if the file can't
+//!               be used, is invalid, or if the read is out of bounds. 
+//!	 
+//*****************************************************************************
+
+signed long 
+nvmem_read(unsigned long ulFileId, unsigned long ulLength, unsigned long ulOffset, unsigned char *buff)
+{
+	unsigned char ucStatus = 0xFF;
+	unsigned char *ptr;
+	unsigned char *args;
+	
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in HCI packet structure
+	args = UINT32_TO_STREAM(args, ulFileId);
+	args = UINT32_TO_STREAM(args, ulLength);
+	args = UINT32_TO_STREAM(args, ulOffset);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_NVMEM_READ, ptr, NVMEM_READ_PARAMS_LEN);
+	SimpleLinkWaitEvent(HCI_CMND_NVMEM_READ, &ucStatus);
+	
+	// In case there is data - read it - even if an error code is returned
+   // Note: It is the user responsibility to ignore the data in case of an error code
+	
+	// Wait for the data in a synchronous way. Here we assume that the buffer is 
+	// big enough to store also parameters of nvmem
+	
+	SimpleLinkWaitData(buff, 0, 0);
+	
+	return(ucStatus);
+}
+
+//*****************************************************************************
+//
+//!  nvmem_write
+//!
+//!  @param  ulFileId nvmem file id:\n
+//!                   NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
+//!                   NVMEM_MAC_FILEID, NVMEM_BOOTLOADER_SP_FILEID,
+//!                   and user files 12-15.
+//!  @param  ulLength       number of bytes to write  
+//!  @param  ulEntryOffset  offset in file to start write operation from 
+//!  @param  buff           data to write
+//!
+//!  @return       on success 0, error otherwise.
+//!
+//!  @brief       Write data to nvmem.
+//!               writes data to file referred by the ulFileId parameter. 
+//!               Writes data to file ulOffset till ulLength.The file id will be 
+//!               marked invalid till the write is done. The file entry doesn't
+//!               need to be valid - only allocated.
+//!	 
+//*****************************************************************************
+
+signed long 
+nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long 
+						ulEntryOffset, unsigned char *buff)
+{
+	long iRes;
+	unsigned char *ptr;
+	unsigned char *args;
+	
+	iRes = EFAIL;
+	
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE);
+	
+	// Fill in HCI packet structure
+	args = UINT32_TO_STREAM(args, ulFileId);
+	args = UINT32_TO_STREAM(args, 12);
+	args = UINT32_TO_STREAM(args, ulLength);
+	args = UINT32_TO_STREAM(args, ulEntryOffset);
+	
+	memcpy((ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE + 
+					NVMEM_WRITE_PARAMS_LEN),buff,ulLength);
+	
+	// Initiate a HCI command but it will come on data channel
+	hci_data_command_send(HCI_CMND_NVMEM_WRITE, ptr, NVMEM_WRITE_PARAMS_LEN,
+												ulLength);
+	
+	SimpleLinkWaitEvent(HCI_EVNT_NVMEM_WRITE, &iRes);
+	
+	return(iRes);
+}
+
+
+//*****************************************************************************
+//
+//!  nvmem_set_mac_address
+//!
+//!  @param  mac   mac address to be set
+//!
+//!  @return       on success 0, error otherwise.
+//!
+//!  @brief       Write MAC address to EEPROM. 
+//!               mac address as appears over the air (OUI first)
+//!	 
+//*****************************************************************************
+
+unsigned char nvmem_set_mac_address(unsigned char *mac)
+{
+	return  nvmem_write(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac);
+}
+
+//*****************************************************************************
+//
+//!  nvmem_get_mac_address
+//!
+//!  @param[out]  mac   mac address  
+//!
+//!  @return       on success 0, error otherwise.
+//!
+//!  @brief       Read MAC address from EEPROM. 
+//!               mac address as appears over the air (OUI first)
+//!	 
+//*****************************************************************************
+
+unsigned char nvmem_get_mac_address(unsigned char *mac)
+{
+	return  nvmem_read(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac);
+}
+
+//*****************************************************************************
+//
+//!  nvmem_write_patch
+//!
+//!  @param  ulFileId   nvmem file id:\n
+//!                     NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
+//!  @param  spLength   number of bytes to write 
+//!  @param  spData     SP data to write
+//!
+//!  @return       on success 0, error otherwise.
+//!
+//!  @brief      program a patch to a specific file ID. 
+//!              The SP data is assumed to be organized in 2-dimensional.
+//!              Each line is SP_PORTION_SIZE bytes long. Actual programming is 
+//!              applied in SP_PORTION_SIZE bytes portions.
+//!	 
+//*****************************************************************************
+
+unsigned char nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, const unsigned char *spData)
+{
+	unsigned char 	status = 0;
+	unsigned short	offset = 0;
+	unsigned char*      spDataPtr = (unsigned char*)spData;
+	
+	while ((status == 0) && (spLength >= SP_PORTION_SIZE))
+	{
+		status = nvmem_write(ulFileId, SP_PORTION_SIZE, offset, spDataPtr);
+		offset += SP_PORTION_SIZE;
+		spLength -= SP_PORTION_SIZE;
+		spDataPtr += SP_PORTION_SIZE;
+	}
+	
+	if (status !=0)
+	{
+		// NVMEM error occurred
+		return status;
+	}
+	
+	if (spLength != 0)
+	{
+		// if reached here, a reminder is left
+		status = nvmem_write(ulFileId, spLength, offset, spDataPtr);
+	}
+	
+	return status;
+}
+
+//*****************************************************************************
+//
+//!  nvmem_read_sp_version
+//!
+//!  @param[out]  patchVer    first number indicates package ID and the second 
+//!                           number indicates package build number   
+//!
+//!  @return       on success  0, error otherwise.
+//!
+//!  @brief      Read patch version. read package version (WiFi FW patch, 
+//!              driver-supplicant-NS patch, bootloader patch)
+//!	 
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+unsigned char nvmem_read_sp_version(unsigned char* patchVer)
+{
+	unsigned char *ptr;
+	// 1st byte is the status and the rest is the SP version
+	unsigned char	retBuf[5];	
+	
+	ptr = tSLInformation.pucTxCommandBuffer;
+  
+   // Initiate a HCI command, no args are required
+	hci_command_send(HCI_CMND_READ_SP_VERSION, ptr, 0);	
+	SimpleLinkWaitEvent(HCI_CMND_READ_SP_VERSION, retBuf);
+	
+	// package ID
+	*patchVer = retBuf[3];			
+	// package build number
+	*(patchVer+1) = retBuf[4];		
+	
+	return(retBuf[0]);
+}
+#endif
+
+//*****************************************************************************
+//
+//!  nvmem_create_entry
+//!
+//!  @param       ulFileId    nvmem file Id:\n
+//!                           * NVMEM_AES128_KEY_FILEID: 12
+//!                           * NVMEM_SHARED_MEM_FILEID: 13
+//!                           * and fileIDs 14 and 15
+//!  @param       ulNewLen    entry ulLength  
+//!
+//!  @return       on success 0, error otherwise.
+//!
+//!  @brief      Create new file entry and allocate space on the NVMEM. 
+//!              Applies only to user files.
+//!              Modify the size of file.
+//!              If the entry is unallocated - allocate it to size 
+//!              ulNewLen (marked invalid).
+//!              If it is allocated then deallocate it first.
+//!              To just mark the file as invalid without resizing - 
+//!              set ulNewLen=0.
+//!	 
+//*****************************************************************************
+
+signed long 
+nvmem_create_entry(unsigned long ulFileId, unsigned long ulNewLen)
+{
+	unsigned char *ptr; 
+	unsigned char *args;
+	unsigned short retval;
+	
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in HCI packet structure
+	args = UINT32_TO_STREAM(args, ulFileId);
+	args = UINT32_TO_STREAM(args, ulNewLen);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_NVMEM_CREATE_ENTRY,ptr, NVMEM_CREATE_PARAMS_LEN);
+	
+	SimpleLinkWaitEvent(HCI_CMND_NVMEM_CREATE_ENTRY, &retval);
+	
+	return(retval);
+}
+
+
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/nvmem.h b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/nvmem.h
new file mode 100644
index 0000000000000000000000000000000000000000..d44e62db5dd2fafcf4ad7b9c2dff26afe3c9b37e
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/nvmem.h
@@ -0,0 +1,250 @@
+/*****************************************************************************
+*
+*  nvmem.h  - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the   
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#ifndef __NVRAM_H__
+#define __NVRAM_H__
+
+#include "cc3000_common.h"
+
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+//*****************************************************************************
+//
+//! \addtogroup nvmem_api
+//! @{
+//
+//*****************************************************************************
+
+/****************************************************************************
+**
+**	Definitions for File IDs
+**	
+****************************************************************************/
+/* NVMEM file ID - system files*/
+#define NVMEM_NVS_FILEID 							(0)
+#define NVMEM_NVS_SHADOW_FILEID 					(1)
+#define NVMEM_WLAN_CONFIG_FILEID 					(2)
+#define NVMEM_WLAN_CONFIG_SHADOW_FILEID 			(3)
+#define NVMEM_WLAN_DRIVER_SP_FILEID					(4)
+#define NVMEM_WLAN_FW_SP_FILEID						(5)
+#define NVMEM_MAC_FILEID 							(6)
+#define NVMEM_FRONTEND_VARS_FILEID 					(7)
+#define NVMEM_IP_CONFIG_FILEID 						(8)
+#define NVMEM_IP_CONFIG_SHADOW_FILEID 				(9)
+#define NVMEM_BOOTLOADER_SP_FILEID 					(10)
+#define NVMEM_RM_FILEID			 					(11)
+
+/* NVMEM file ID - user files*/
+#define NVMEM_AES128_KEY_FILEID	 					(12)
+#define NVMEM_SHARED_MEM_FILEID	 					(13)
+#define NVMEM_USER_FILE_1_FILEID					(14)
+#define NVMEM_VERSION_LENGTH						(5)
+
+/*  max entry in order to invalid nvmem              */
+#define NVMEM_MAX_ENTRY                              (16)
+
+
+//*****************************************************************************
+//
+//!  nvmem_read
+//!
+//!  @param  ulFileId   nvmem file id:\n
+//!                     NVMEM_NVS_FILEID, NVMEM_NVS_SHADOW_FILEID,
+//!                     NVMEM_WLAN_CONFIG_FILEID, NVMEM_WLAN_CONFIG_SHADOW_FILEID,
+//!                     NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
+//!                     NVMEM_MAC_FILEID, NVMEM_FRONTEND_VARS_FILEID,
+//!                     NVMEM_IP_CONFIG_FILEID, NVMEM_IP_CONFIG_SHADOW_FILEID,
+//!                     NVMEM_BOOTLOADER_SP_FILEID, NVMEM_RM_FILEID,
+//!                     and user files 12-15.
+//!  @param  ulLength    number of bytes to read 
+//!  @param  ulOffset    ulOffset in file from where to read  
+//!  @param  buff        output buffer pointer
+//!
+//!  @return       number of bytes read, otherwise error.
+//!
+//!  @brief       Reads data from the file referred by the ulFileId parameter. 
+//!               Reads data from file ulOffset till length. Err if the file can't
+//!               be used, is invalid, or if the read is out of bounds. 
+//!	 
+//*****************************************************************************
+
+extern signed long nvmem_read(unsigned long file_id, unsigned long length, unsigned long offset, unsigned char *buff);
+
+//*****************************************************************************
+//
+//!  nvmem_write
+//!
+//!  @param  ulFileId nvmem file id:\n
+//!                   NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
+//!                   NVMEM_MAC_FILEID, NVMEM_BOOTLOADER_SP_FILEID,
+//!                   and user files 12-15.
+//!  @param  ulLength       number of bytes to write  
+//!  @param  ulEntryOffset  offset in file to start write operation from 
+//!  @param  buff           data to write
+//!
+//!  @return       on success 0, error otherwise.
+//!
+//!  @brief       Write data to nvmem.
+//!               writes data to file referred by the ulFileId parameter. 
+//!               Writes data to file ulOffset till ulLength.The file id will be 
+//!               marked invalid till the write is done. The file entry doesn't
+//!               need to be valid - only allocated.
+//!	 
+//*****************************************************************************
+
+extern signed long nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long ulEntryOffset, unsigned char *buff);
+
+
+//*****************************************************************************
+//
+//!  nvmem_set_mac_address
+//!
+//!  @param  mac   mac address to be set
+//!
+//!  @return       on success 0, error otherwise.
+//!
+//!  @brief       Write MAC address to EEPROM. 
+//!               mac address as appears over the air (OUI first)
+//!	 
+//*****************************************************************************
+extern	unsigned char nvmem_set_mac_address(unsigned char *mac);
+
+
+//*****************************************************************************
+//
+//!  nvmem_get_mac_address
+//!
+//!  @param[out]  mac   mac address  
+//!
+//!  @return       on success 0, error otherwise.
+//!
+//!  @brief       Read MAC address from EEPROM. 
+//!               mac address as appears over the air (OUI first)
+//!	 
+//*****************************************************************************
+extern	unsigned char nvmem_get_mac_address(unsigned char *mac);
+
+
+//*****************************************************************************
+//
+//!  nvmem_write_patch
+//!
+//!  @param  ulFileId   nvmem file id:\n
+//!                     NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
+//!  @param  spLength   number of bytes to write 
+//!  @param  spData     SP data to write
+//!
+//!  @return       on success 0, error otherwise.
+//!
+//!  @brief      program a patch to a specific file ID. 
+//!              The SP data is assumed to be organized in 2-dimensional.
+//!              Each line is SP_PORTION_SIZE bytes long. Actual programming is 
+//!              applied in SP_PORTION_SIZE bytes portions.
+//!	 
+//*****************************************************************************
+extern	unsigned char nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, const unsigned char *spData);
+
+
+//*****************************************************************************
+//
+//!  nvmem_read_sp_version
+//!
+//!  @param[out]  patchVer    first number indicates package ID and the second 
+//!                           number indicates package build number   
+//!
+//!  @return       on success 0, error otherwise.
+//!
+//!  @brief      Read patch version. read package version (WiFi FW patch, 
+//!              driver-supplicant-NS patch, bootloader patch)
+//!	 
+//*****************************************************************************
+#ifndef CC3000_TINY_DRIVER 
+extern	unsigned char nvmem_read_sp_version(unsigned char* patchVer);
+#endif
+
+//*****************************************************************************
+//
+//!  nvmem_create_entry
+//!
+//!  @param       ulFileId    nvmem file Id:\n
+//!                           * NVMEM_AES128_KEY_FILEID: 12
+//!                           * NVMEM_SHARED_MEM_FILEID: 13
+//!                           * and fileIDs 14 and 15
+//!  @param       ulNewLen    entry ulLength  
+//!
+//!  @return       on success 0, error otherwise.
+//!
+//!  @brief      Create new file entry and allocate space on the NVMEM. 
+//!              Applies only to user files.
+//!              Modify the size of file.
+//!              If the entry is unallocated - allocate it to size 
+//!              ulNewLen (marked invalid).
+//!              If it is allocated then deallocate it first.
+//!              To just mark the file as invalid without resizing - 
+//!              set ulNewLen=0.
+//!	 
+//*****************************************************************************
+extern signed long nvmem_create_entry(unsigned long file_id, unsigned long newlen);
+
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+
+
+#ifdef  __cplusplus
+}
+#endif // __cplusplus
+
+#endif // __NVRAM_H__
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/security.c b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/security.c
new file mode 100644
index 0000000000000000000000000000000000000000..14fd7c98fbda9c0b49a5b19c4be91cc45b415615
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/security.c
@@ -0,0 +1,537 @@
+/*****************************************************************************
+*
+*  security.c  - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the   
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_CC3000
+
+//*****************************************************************************
+//
+//! \addtogroup security_api
+//! @{
+//
+//*****************************************************************************
+
+#include "security.h"
+
+#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
+// foreward sbox
+const unsigned char sbox[256] =   { 
+//0     1    2      3     4    5     6     7      8    9     A      B    C     D     E     F
+0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0
+0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1
+0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2
+0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3
+0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4
+0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5
+0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6
+0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7
+0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8
+0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9
+0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A
+0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B
+0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C
+0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D
+0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E
+0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; //F   
+// inverse sbox
+const unsigned char rsbox[256] =
+{ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
+// round constant
+const unsigned char Rcon[11] = {
+  0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
+
+
+unsigned char expandedKey[176];
+
+//*****************************************************************************
+//
+//!  expandKey
+//!
+//!  @param  key          AES128 key - 16 bytes
+//!  @param  expandedKey  expanded AES128 key
+//!
+//!  @return  none
+//!
+//!  @brief  expend a 16 bytes key for AES128 implementation
+//!
+//*****************************************************************************
+
+void expandKey(unsigned char *expandedKey,
+               unsigned char *key)
+{
+  unsigned short ii, buf1;
+  for (ii=0;ii<16;ii++)
+    expandedKey[ii] = key[ii];
+  for (ii=1;ii<11;ii++){
+    buf1 = expandedKey[ii*16 - 4];
+    expandedKey[ii*16 + 0] = sbox[expandedKey[ii*16 - 3]]^expandedKey[(ii-1)*16 + 0]^Rcon[ii];
+    expandedKey[ii*16 + 1] = sbox[expandedKey[ii*16 - 2]]^expandedKey[(ii-1)*16 + 1];
+    expandedKey[ii*16 + 2] = sbox[expandedKey[ii*16 - 1]]^expandedKey[(ii-1)*16 + 2];
+    expandedKey[ii*16 + 3] = sbox[buf1                  ]^expandedKey[(ii-1)*16 + 3];
+    expandedKey[ii*16 + 4] = expandedKey[(ii-1)*16 + 4]^expandedKey[ii*16 + 0];
+    expandedKey[ii*16 + 5] = expandedKey[(ii-1)*16 + 5]^expandedKey[ii*16 + 1];
+    expandedKey[ii*16 + 6] = expandedKey[(ii-1)*16 + 6]^expandedKey[ii*16 + 2];
+    expandedKey[ii*16 + 7] = expandedKey[(ii-1)*16 + 7]^expandedKey[ii*16 + 3];
+    expandedKey[ii*16 + 8] = expandedKey[(ii-1)*16 + 8]^expandedKey[ii*16 + 4];
+    expandedKey[ii*16 + 9] = expandedKey[(ii-1)*16 + 9]^expandedKey[ii*16 + 5];
+    expandedKey[ii*16 +10] = expandedKey[(ii-1)*16 +10]^expandedKey[ii*16 + 6];
+    expandedKey[ii*16 +11] = expandedKey[(ii-1)*16 +11]^expandedKey[ii*16 + 7];
+    expandedKey[ii*16 +12] = expandedKey[(ii-1)*16 +12]^expandedKey[ii*16 + 8];
+    expandedKey[ii*16 +13] = expandedKey[(ii-1)*16 +13]^expandedKey[ii*16 + 9];
+    expandedKey[ii*16 +14] = expandedKey[(ii-1)*16 +14]^expandedKey[ii*16 +10];
+    expandedKey[ii*16 +15] = expandedKey[(ii-1)*16 +15]^expandedKey[ii*16 +11];
+  }
+	
+}
+
+//*****************************************************************************
+//
+//!  galois_mul2
+//!
+//!  @param  value    argument to multiply
+//!
+//!  @return  multiplied argument
+//!
+//!  @brief  multiply by 2 in the galois field
+//!
+//*****************************************************************************
+
+unsigned char galois_mul2(unsigned char value)
+{
+	if (value>>7)
+	{
+		value = value << 1;
+		return (value^0x1b);
+	} else
+		return value<<1;
+}
+
+//*****************************************************************************
+//
+//!  aes_encr
+//!
+//!  @param[in]  expandedKey expanded AES128 key
+//!  @param[in/out] state 16 bytes of plain text and cipher text
+//!
+//!  @return  none
+//!
+//!  @brief   internal implementation of AES128 encryption.
+//!           straight forward aes encryption implementation
+//!           first the group of operations
+//!          - addRoundKey
+//!          - subbytes
+//!          - shiftrows
+//!          - mixcolums
+//!          is executed 9 times, after this addroundkey to finish the 9th 
+//!          round, after that the 10th round without mixcolums
+//!          no further subfunctions to save cycles for function calls
+//!          no structuring with "for (....)" to save cycles.
+//!	 
+//!
+//*****************************************************************************
+
+void aes_encr(unsigned char *state, unsigned char *expandedKey)
+{
+  unsigned char buf1, buf2, buf3, round;
+		
+  for (round = 0; round < 9; round ++){
+    // addroundkey, sbox and shiftrows
+    // row 0
+    state[ 0]  = sbox[(state[ 0] ^ expandedKey[(round*16)     ])];
+    state[ 4]  = sbox[(state[ 4] ^ expandedKey[(round*16) +  4])];
+    state[ 8]  = sbox[(state[ 8] ^ expandedKey[(round*16) +  8])];
+    state[12]  = sbox[(state[12] ^ expandedKey[(round*16) + 12])];
+    // row 1
+    buf1 = state[1] ^ expandedKey[(round*16) + 1];
+    state[ 1]  = sbox[(state[ 5] ^ expandedKey[(round*16) +  5])];
+    state[ 5]  = sbox[(state[ 9] ^ expandedKey[(round*16) +  9])];
+    state[ 9]  = sbox[(state[13] ^ expandedKey[(round*16) + 13])];
+    state[13]  = sbox[buf1];
+    // row 2
+    buf1 = state[2] ^ expandedKey[(round*16) + 2];
+    buf2 = state[6] ^ expandedKey[(round*16) + 6];
+    state[ 2]  = sbox[(state[10] ^ expandedKey[(round*16) + 10])];
+    state[ 6]  = sbox[(state[14] ^ expandedKey[(round*16) + 14])];
+    state[10]  = sbox[buf1];
+    state[14]  = sbox[buf2];
+    // row 3
+    buf1 = state[15] ^ expandedKey[(round*16) + 15];
+    state[15]  = sbox[(state[11] ^ expandedKey[(round*16) + 11])];
+    state[11]  = sbox[(state[ 7] ^ expandedKey[(round*16) +  7])];
+    state[ 7]  = sbox[(state[ 3] ^ expandedKey[(round*16) +  3])];
+    state[ 3]  = sbox[buf1];
+    
+    // mixcolums //////////
+    // col1
+    buf1 = state[0] ^ state[1] ^ state[2] ^ state[3];
+    buf2 = state[0];
+    buf3 = state[0]^state[1]; buf3=galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1;
+    buf3 = state[1]^state[2]; buf3=galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1;
+    buf3 = state[2]^state[3]; buf3=galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1;
+    buf3 = state[3]^buf2;     buf3=galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1;
+    // col2
+    buf1 = state[4] ^ state[5] ^ state[6] ^ state[7];
+    buf2 = state[4];
+    buf3 = state[4]^state[5]; buf3=galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1;
+    buf3 = state[5]^state[6]; buf3=galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1;
+    buf3 = state[6]^state[7]; buf3=galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1;
+    buf3 = state[7]^buf2;     buf3=galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1;
+    // col3
+    buf1 = state[8] ^ state[9] ^ state[10] ^ state[11];
+    buf2 = state[8];
+    buf3 = state[8]^state[9];   buf3=galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1;
+    buf3 = state[9]^state[10];  buf3=galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1;
+    buf3 = state[10]^state[11]; buf3=galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1;
+    buf3 = state[11]^buf2;      buf3=galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1;
+    // col4
+    buf1 = state[12] ^ state[13] ^ state[14] ^ state[15];
+    buf2 = state[12];
+    buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1;
+    buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1;
+    buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1;
+    buf3 = state[15]^buf2;      buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1;    
+		
+  }
+  // 10th round without mixcols
+  state[ 0]  = sbox[(state[ 0] ^ expandedKey[(round*16)     ])];
+  state[ 4]  = sbox[(state[ 4] ^ expandedKey[(round*16) +  4])];
+  state[ 8]  = sbox[(state[ 8] ^ expandedKey[(round*16) +  8])];
+  state[12]  = sbox[(state[12] ^ expandedKey[(round*16) + 12])];
+  // row 1
+  buf1 = state[1] ^ expandedKey[(round*16) + 1];
+  state[ 1]  = sbox[(state[ 5] ^ expandedKey[(round*16) +  5])];
+  state[ 5]  = sbox[(state[ 9] ^ expandedKey[(round*16) +  9])];
+  state[ 9]  = sbox[(state[13] ^ expandedKey[(round*16) + 13])];
+  state[13]  = sbox[buf1];
+  // row 2
+  buf1 = state[2] ^ expandedKey[(round*16) + 2];
+  buf2 = state[6] ^ expandedKey[(round*16) + 6];
+  state[ 2]  = sbox[(state[10] ^ expandedKey[(round*16) + 10])];
+  state[ 6]  = sbox[(state[14] ^ expandedKey[(round*16) + 14])];
+  state[10]  = sbox[buf1];
+  state[14]  = sbox[buf2];
+  // row 3
+  buf1 = state[15] ^ expandedKey[(round*16) + 15];
+  state[15]  = sbox[(state[11] ^ expandedKey[(round*16) + 11])];
+  state[11]  = sbox[(state[ 7] ^ expandedKey[(round*16) +  7])];
+  state[ 7]  = sbox[(state[ 3] ^ expandedKey[(round*16) +  3])];
+  state[ 3]  = sbox[buf1];
+  // last addroundkey
+  state[ 0]^=expandedKey[160];
+  state[ 1]^=expandedKey[161];
+  state[ 2]^=expandedKey[162];
+  state[ 3]^=expandedKey[163];
+  state[ 4]^=expandedKey[164];
+  state[ 5]^=expandedKey[165];
+  state[ 6]^=expandedKey[166];
+  state[ 7]^=expandedKey[167];
+  state[ 8]^=expandedKey[168];
+  state[ 9]^=expandedKey[169];
+  state[10]^=expandedKey[170];
+  state[11]^=expandedKey[171];
+  state[12]^=expandedKey[172];
+  state[13]^=expandedKey[173];
+  state[14]^=expandedKey[174]; 
+  state[15]^=expandedKey[175];
+} 
+
+//*****************************************************************************
+//
+//!  aes_decr
+//!
+//!  @param[in]  expandedKey expanded AES128 key
+//!  @param[in\out] state 16 bytes of cipher text and plain text
+//!
+//!  @return  none
+//!
+//!  @brief   internal implementation of AES128 decryption.
+//!           straight forward aes decryption implementation
+//!           the order of substeps is the exact reverse of decryption
+//!           inverse functions:
+//!            - addRoundKey is its own inverse
+//!            - rsbox is inverse of sbox
+//!            - rightshift instead of leftshift
+//!            - invMixColumns = barreto + mixColumns
+//!           no further subfunctions to save cycles for function calls
+//!           no structuring with "for (....)" to save cycles
+//!
+//*****************************************************************************
+
+void aes_decr(unsigned char *state, unsigned char *expandedKey)
+{
+  unsigned char buf1, buf2, buf3;
+  signed char round;
+  round = 9;
+	
+  // initial addroundkey
+  state[ 0]^=expandedKey[160];
+  state[ 1]^=expandedKey[161];
+  state[ 2]^=expandedKey[162];
+  state[ 3]^=expandedKey[163];
+  state[ 4]^=expandedKey[164];
+  state[ 5]^=expandedKey[165];
+  state[ 6]^=expandedKey[166];
+  state[ 7]^=expandedKey[167];
+  state[ 8]^=expandedKey[168];
+  state[ 9]^=expandedKey[169];
+  state[10]^=expandedKey[170];
+  state[11]^=expandedKey[171];
+  state[12]^=expandedKey[172];
+  state[13]^=expandedKey[173];
+  state[14]^=expandedKey[174]; 
+  state[15]^=expandedKey[175];
+	
+  // 10th round without mixcols
+  state[ 0]  = rsbox[state[ 0]] ^ expandedKey[(round*16)     ];
+  state[ 4]  = rsbox[state[ 4]] ^ expandedKey[(round*16) +  4];
+  state[ 8]  = rsbox[state[ 8]] ^ expandedKey[(round*16) +  8];
+  state[12]  = rsbox[state[12]] ^ expandedKey[(round*16) + 12];
+  // row 1
+  buf1 =       rsbox[state[13]] ^ expandedKey[(round*16) +  1];
+  state[13]  = rsbox[state[ 9]] ^ expandedKey[(round*16) + 13];
+  state[ 9]  = rsbox[state[ 5]] ^ expandedKey[(round*16) +  9];
+  state[ 5]  = rsbox[state[ 1]] ^ expandedKey[(round*16) +  5];
+  state[ 1]  = buf1;
+  // row 2
+  buf1 =       rsbox[state[ 2]] ^ expandedKey[(round*16) + 10];
+  buf2 =       rsbox[state[ 6]] ^ expandedKey[(round*16) + 14];
+  state[ 2]  = rsbox[state[10]] ^ expandedKey[(round*16) +  2];
+  state[ 6]  = rsbox[state[14]] ^ expandedKey[(round*16) +  6];
+  state[10]  = buf1;
+  state[14]  = buf2;
+  // row 3
+  buf1 =       rsbox[state[ 3]] ^ expandedKey[(round*16) + 15];
+  state[ 3]  = rsbox[state[ 7]] ^ expandedKey[(round*16) +  3];
+  state[ 7]  = rsbox[state[11]] ^ expandedKey[(round*16) +  7];
+  state[11]  = rsbox[state[15]] ^ expandedKey[(round*16) + 11];
+  state[15]  = buf1;
+	
+  for (round = 8; round >= 0; round--){
+    // barreto
+    //col1
+    buf1 = galois_mul2(galois_mul2(state[0]^state[2]));
+    buf2 = galois_mul2(galois_mul2(state[1]^state[3]));
+    state[0] ^= buf1;     state[1] ^= buf2;    state[2] ^= buf1;    state[3] ^= buf2;
+    //col2
+    buf1 = galois_mul2(galois_mul2(state[4]^state[6]));
+    buf2 = galois_mul2(galois_mul2(state[5]^state[7]));
+    state[4] ^= buf1;    state[5] ^= buf2;    state[6] ^= buf1;    state[7] ^= buf2;
+    //col3
+    buf1 = galois_mul2(galois_mul2(state[8]^state[10]));
+    buf2 = galois_mul2(galois_mul2(state[9]^state[11]));
+    state[8] ^= buf1;    state[9] ^= buf2;    state[10] ^= buf1;    state[11] ^= buf2;
+    //col4
+    buf1 = galois_mul2(galois_mul2(state[12]^state[14]));
+    buf2 = galois_mul2(galois_mul2(state[13]^state[15]));
+    state[12] ^= buf1;    state[13] ^= buf2;    state[14] ^= buf1;    state[15] ^= buf2;
+    // mixcolums //////////
+    // col1
+    buf1 = state[0] ^ state[1] ^ state[2] ^ state[3];
+    buf2 = state[0];
+    buf3 = state[0]^state[1]; buf3=galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1;
+    buf3 = state[1]^state[2]; buf3=galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1;
+    buf3 = state[2]^state[3]; buf3=galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1;
+    buf3 = state[3]^buf2;     buf3=galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1;
+    // col2
+    buf1 = state[4] ^ state[5] ^ state[6] ^ state[7];
+    buf2 = state[4];
+    buf3 = state[4]^state[5]; buf3=galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1;
+    buf3 = state[5]^state[6]; buf3=galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1;
+    buf3 = state[6]^state[7]; buf3=galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1;
+    buf3 = state[7]^buf2;     buf3=galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1;
+    // col3
+    buf1 = state[8] ^ state[9] ^ state[10] ^ state[11];
+    buf2 = state[8];
+    buf3 = state[8]^state[9];   buf3=galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1;
+    buf3 = state[9]^state[10];  buf3=galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1;
+    buf3 = state[10]^state[11]; buf3=galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1;
+    buf3 = state[11]^buf2;      buf3=galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1;
+    // col4
+    buf1 = state[12] ^ state[13] ^ state[14] ^ state[15];
+    buf2 = state[12];
+    buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1;
+    buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1;
+    buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1;
+    buf3 = state[15]^buf2;      buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1;    
+		
+    // addroundkey, rsbox and shiftrows
+    // row 0
+    state[ 0]  = rsbox[state[ 0]] ^ expandedKey[(round*16)     ];
+    state[ 4]  = rsbox[state[ 4]] ^ expandedKey[(round*16) +  4];
+    state[ 8]  = rsbox[state[ 8]] ^ expandedKey[(round*16) +  8];
+    state[12]  = rsbox[state[12]] ^ expandedKey[(round*16) + 12];
+    // row 1
+    buf1 =       rsbox[state[13]] ^ expandedKey[(round*16) +  1];
+    state[13]  = rsbox[state[ 9]] ^ expandedKey[(round*16) + 13];
+    state[ 9]  = rsbox[state[ 5]] ^ expandedKey[(round*16) +  9];
+    state[ 5]  = rsbox[state[ 1]] ^ expandedKey[(round*16) +  5];
+    state[ 1]  = buf1;
+    // row 2
+    buf1 =       rsbox[state[ 2]] ^ expandedKey[(round*16) + 10];
+    buf2 =       rsbox[state[ 6]] ^ expandedKey[(round*16) + 14];
+    state[ 2]  = rsbox[state[10]] ^ expandedKey[(round*16) +  2];
+    state[ 6]  = rsbox[state[14]] ^ expandedKey[(round*16) +  6];
+    state[10]  = buf1;
+    state[14]  = buf2;
+    // row 3
+    buf1 =       rsbox[state[ 3]] ^ expandedKey[(round*16) + 15];
+    state[ 3]  = rsbox[state[ 7]] ^ expandedKey[(round*16) +  3];
+    state[ 7]  = rsbox[state[11]] ^ expandedKey[(round*16) +  7];
+    state[11]  = rsbox[state[15]] ^ expandedKey[(round*16) + 11];
+    state[15]  = buf1;
+  }
+	
+} 
+
+//*****************************************************************************
+//
+//!  aes_encrypt
+//!
+//!  @param[in]  key   AES128 key of size 16 bytes
+//!  @param[in\out] state   16 bytes of plain text and cipher text
+//!
+//!  @return  none
+//!
+//!  @brief   AES128 encryption:
+//!           Given AES128 key and  16 bytes plain text, cipher text of 16 bytes
+//!           is computed. The AES implementation is in mode ECB (Electronic 
+//!           Code Book). 
+//!	 
+//!
+//*****************************************************************************
+
+void aes_encrypt(unsigned char *state,
+                 unsigned char *key)
+{
+	// expand the key into 176 bytes
+	expandKey(expandedKey, key);       
+	aes_encr(state, expandedKey);
+}
+
+//*****************************************************************************
+//
+//!  aes_decrypt
+//!
+//!  @param[in]  key   AES128 key of size 16 bytes
+//!  @param[in\out] state   16 bytes of cipher text and plain text
+//!
+//!  @return  none
+//!
+//!  @brief   AES128 decryption:
+//!           Given AES128 key and  16 bytes cipher text, plain text of 16 bytes
+//!           is computed The AES implementation is in mode ECB 
+//!           (Electronic Code Book).
+//!	 
+//!
+//*****************************************************************************
+
+void aes_decrypt(unsigned char *state,
+                 unsigned char *key)
+{
+    expandKey(expandedKey, key);       // expand the key into 176 bytes
+    aes_decr(state, expandedKey);
+}
+
+//*****************************************************************************
+//
+//!  aes_read_key
+//!
+//!  @param[out]  key   AES128 key of size 16 bytes
+//!
+//!  @return  on success 0, error otherwise.
+//!
+//!  @brief   Reads AES128 key from EEPROM
+//!           Reads the AES128 key from fileID #12 in EEPROM
+//!           returns an error if the key does not exist. 
+//!	 
+//!
+//*****************************************************************************
+
+signed long aes_read_key(unsigned char *key)
+{
+	signed long	returnValue;
+	
+	returnValue = nvmem_read(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key);
+
+	return returnValue;
+}
+
+//*****************************************************************************
+//
+//!  aes_write_key
+//!
+//!  @param[out]  key   AES128 key of size 16 bytes
+//!
+//!  @return  on success 0, error otherwise.
+//!
+//!  @brief   writes AES128 key from EEPROM
+//!           Writes the AES128 key to fileID #12 in EEPROM
+//!	 
+//!
+//*****************************************************************************
+
+signed long aes_write_key(unsigned char *key)
+{
+	signed long	returnValue;
+
+	returnValue = nvmem_write(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key);
+
+	return returnValue;
+}
+
+#endif //CC3000_UNENCRYPTED_SMART_CONFIG
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/security.h b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/security.h
new file mode 100644
index 0000000000000000000000000000000000000000..5c70c2926efaff3a900b6446afd81ace69f4b8ea
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/security.h
@@ -0,0 +1,126 @@
+/*****************************************************************************
+*
+*  security.h  - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the   
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#ifndef __SECURITY__
+#define __SECURITY__
+
+#include "nvmem.h"
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+#define AES128_KEY_SIZE		16
+
+#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
+
+
+//*****************************************************************************
+//
+//!  aes_encrypt
+//!
+//!  @param[in]  key   AES128 key of size 16 bytes
+//!  @param[in\out] state   16 bytes of plain text and cipher text
+//!
+//!  @return  none
+//!
+//!  @brief   AES128 encryption:
+//!           Given AES128 key and  16 bytes plain text, cipher text of 16 bytes
+//!           is computed. The AES implementation is in mode ECB (Electronic 
+//!           Code Book). 
+//!	 
+//!
+//*****************************************************************************
+extern void aes_encrypt(unsigned char *state, unsigned char *key);
+
+//*****************************************************************************
+//
+//!  aes_decrypt
+//!
+//!  @param[in]  key   AES128 key of size 16 bytes
+//!  @param[in\out] state   16 bytes of cipher text and plain text
+//!
+//!  @return  none
+//!
+//!  @brief   AES128 decryption:
+//!           Given AES128 key and  16 bytes cipher text, plain text of 16 bytes
+//!           is computed The AES implementation is in mode ECB 
+//!           (Electronic Code Book).
+//!	 
+//!
+//*****************************************************************************
+extern void aes_decrypt(unsigned char *state, unsigned char *key);
+
+
+//*****************************************************************************
+//
+//!  aes_read_key
+//!
+//!  @param[out]  key   AES128 key of size 16 bytes
+//!
+//!  @return  on success 0, error otherwise.
+//!
+//!  @brief   Reads AES128 key from EEPROM
+//!           Reads the AES128 key from fileID #12 in EEPROM
+//!           returns an error if the key does not exist. 
+//!	 
+//!
+//*****************************************************************************
+extern signed long aes_read_key(unsigned char *key);
+
+//*****************************************************************************
+//
+//!  aes_write_key
+//!
+//!  @param[out]  key   AES128 key of size 16 bytes
+//!
+//!  @return  on success 0, error otherwise.
+//!
+//!  @brief   writes AES128 key from EEPROM
+//!           Writes the AES128 key to fileID #12 in EEPROM
+//!	 
+//!
+//*****************************************************************************
+extern signed long aes_write_key(unsigned char *key);
+
+#endif //CC3000_UNENCRYPTED_SMART_CONFIG
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/socket.c b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/socket.c
new file mode 100644
index 0000000000000000000000000000000000000000..0200e7d99ecd8a910dfd9c80ba290f37b44eb645
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/socket.c
@@ -0,0 +1,1173 @@
+/*****************************************************************************
+*
+*  socket.c  - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the   
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_CC3000
+
+//*****************************************************************************
+//
+//! \addtogroup socket_api
+//! @{
+//
+//*****************************************************************************
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "hci.h"
+#include "socket.h"
+#include "evnt_handler.h"
+#include "netapp.h"
+
+
+
+//Enable this flag if and only if you must comply with BSD socket 
+//close() function
+#ifdef _API_USE_BSD_CLOSE
+   #define close(sd) closesocket(sd)
+#endif
+
+//Enable this flag if and only if you must comply with BSD socket read() and 
+//write() functions
+#ifdef _API_USE_BSD_READ_WRITE
+              #define read(sd, buf, len, flags) recv(sd, buf, len, flags)
+              #define write(sd, buf, len, flags) send(sd, buf, len, flags)
+#endif
+
+#define SOCKET_OPEN_PARAMS_LEN				(12)
+#define SOCKET_CLOSE_PARAMS_LEN				(4)
+#define SOCKET_ACCEPT_PARAMS_LEN			(4)
+#define SOCKET_BIND_PARAMS_LEN				(20)
+#define SOCKET_LISTEN_PARAMS_LEN			(8)
+#define SOCKET_GET_HOST_BY_NAME_PARAMS_LEN	(9)
+#define SOCKET_CONNECT_PARAMS_LEN			(20)
+#define SOCKET_SELECT_PARAMS_LEN			(44)
+#define SOCKET_SET_SOCK_OPT_PARAMS_LEN		(20)
+#define SOCKET_GET_SOCK_OPT_PARAMS_LEN		(12)
+#define SOCKET_RECV_FROM_PARAMS_LEN			(12)
+#define SOCKET_SENDTO_PARAMS_LEN			(24)
+#define SOCKET_MDNS_ADVERTISE_PARAMS_LEN	(12)
+
+
+// The legnth of arguments for the SEND command: sd + buff_offset + len + flags, 
+// while size of each parameter is 32 bit - so the total length is 16 bytes;
+
+#define HCI_CMND_SEND_ARG_LENGTH	(16)
+
+
+#define SELECT_TIMEOUT_MIN_MICRO_SECONDS  5000
+
+#define HEADERS_SIZE_DATA       (SPI_HEADER_SIZE + 5)
+
+#define SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE  (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE)
+
+#define MDNS_DEVICE_SERVICE_MAX_LENGTH 	(32)
+
+
+//*****************************************************************************
+//
+//! HostFlowControlConsumeBuff
+//!
+//!  @param  sd  socket descriptor
+//!
+//!  @return 0 in case there are buffers available, 
+//!          -1 in case of bad socket
+//!          -2 if there are no free buffers present (only when 
+//!          SEND_NON_BLOCKING is enabled)
+//!
+//!  @brief  if SEND_NON_BLOCKING not define - block until have free buffer 
+//!          becomes available, else return immediately  with correct status 
+//!          regarding the buffers available.
+//
+//*****************************************************************************
+int
+HostFlowControlConsumeBuff(int sd)
+{
+#ifndef SEND_NON_BLOCKING
+	/* wait in busy loop */
+	do
+	{
+		// In case last transmission failed then we will return the last failure 
+		// reason here.
+		// Note that the buffer will not be allocated in this case
+		if (tSLInformation.slTransmitDataError != 0)
+		{
+			errno = tSLInformation.slTransmitDataError;
+			tSLInformation.slTransmitDataError = 0;
+			return errno;
+		}
+		
+		if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd))
+			return -1;
+	} while(0 == tSLInformation.usNumberOfFreeBuffers);
+	
+	tSLInformation.usNumberOfFreeBuffers--;
+	
+	return 0;
+#else
+	
+	// In case last transmission failed then we will return the last failure 
+	// reason here.
+	// Note that the buffer will not be allocated in this case
+	if (tSLInformation.slTransmitDataError != 0)
+	{
+		errno = tSLInformation.slTransmitDataError;
+		tSLInformation.slTransmitDataError = 0;
+		return errno;
+	}
+	if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd))
+		return -1;
+	
+	//If there are no available buffers, return -2. It is recommended to use  
+	// select or receive to see if there is any buffer occupied with received data
+	// If so, call receive() to release the buffer.
+	if(0 == tSLInformation.usNumberOfFreeBuffers)
+	{
+		return -2;
+	}
+	else
+	{
+		tSLInformation.usNumberOfFreeBuffers--;
+		return 0;
+	}
+#endif
+}
+
+//*****************************************************************************
+//
+//! socket
+//!
+//!  @param  domain    selects the protocol family which will be used for 
+//!                    communication. On this version only AF_INET is supported
+//!  @param  type      specifies the communication semantics. On this version 
+//!                    only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported
+//!  @param  protocol  specifies a particular protocol to be used with the 
+//!                    socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are 
+//!                    supported.
+//!
+//!  @return  On success, socket handle that is used for consequent socket 
+//!           operations. On error, -1 is returned.
+//!
+//!  @brief  create an endpoint for communication
+//!          The socket function creates a socket that is bound to a specific 
+//!          transport service provider. This function is called by the 
+//!          application layer to obtain a socket handle.
+//
+//*****************************************************************************
+
+int
+socket(long domain, long type, long protocol)
+{
+	long ret;
+	unsigned char *ptr, *args;
+	
+	ret = EFAIL;
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in HCI packet structure
+	args = UINT32_TO_STREAM(args, domain);
+	args = UINT32_TO_STREAM(args, type);
+	args = UINT32_TO_STREAM(args, protocol);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN);
+	
+	// Since we are in blocking state - wait for event complete
+	SimpleLinkWaitEvent(HCI_CMND_SOCKET, &ret);
+	
+	// Process the event 
+	errno = ret;
+	
+	set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
+	
+	return(ret);
+}
+
+//*****************************************************************************
+//
+//! closesocket
+//!
+//!  @param  sd    socket handle.
+//!
+//!  @return  On success, zero is returned. On error, -1 is returned.
+//!
+//!  @brief  The socket function closes a created socket.
+//
+//*****************************************************************************
+
+long
+closesocket(long sd)
+{
+	long ret;
+	unsigned char *ptr, *args;
+	
+	ret = EFAIL;
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in HCI packet structure
+	args = UINT32_TO_STREAM(args, sd);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_CLOSE_SOCKET,
+									 ptr, SOCKET_CLOSE_PARAMS_LEN);
+	
+	// Since we are in blocking state - wait for event complete
+	SimpleLinkWaitEvent(HCI_CMND_CLOSE_SOCKET, &ret);
+	errno = ret;
+	
+	// since 'close' call may result in either OK (and then it closed) or error 
+	// mark this socket as invalid 
+	set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
+	
+	return(ret);
+}
+
+//*****************************************************************************
+//
+//! accept
+//!
+//!  @param[in]   sd      socket descriptor (handle)              
+//!  @param[out]  addr    the argument addr is a pointer to a sockaddr structure
+//!                       This structure is filled in with the address of the  
+//!                       peer socket, as known to the communications layer.        
+//!                       determined. The exact format of the address returned             
+//!                       addr is by the socket's address sockaddr. 
+//!                       On this version only AF_INET is supported.
+//!                       This argument returns in network order.
+//!  @param[out] addrlen  the addrlen argument is a value-result argument: 
+//!                       it should initially contain the size of the structure
+//!                       pointed to by addr.
+//!
+//!  @return  For socket in blocking mode:
+//!				      On success, socket handle. on failure negative
+//!			      For socket in non-blocking mode:
+//!				     - On connection establishment, socket handle
+//!				     - On connection pending, SOC_IN_PROGRESS (-2)
+//!			       - On failure, SOC_ERROR	(-1)
+//!
+//!  @brief  accept a connection on a socket:
+//!          This function is used with connection-based socket types 
+//!          (SOCK_STREAM). It extracts the first connection request on the 
+//!          queue of pending connections, creates a new connected socket, and
+//!          returns a new file descriptor referring to that socket.
+//!          The newly created socket is not in the listening state. 
+//!          The original socket sd is unaffected by this call. 
+//!          The argument sd is a socket that has been created with socket(),
+//!          bound to a local address with bind(), and is  listening for 
+//!          connections after a listen(). The argument addr is a pointer 
+//!          to a sockaddr structure. This structure is filled in with the 
+//!          address of the peer socket, as known to the communications layer.
+//!          The exact format of the address returned addr is determined by the 
+//!          socket's address family. The addrlen argument is a value-result
+//!          argument: it should initially contain the size of the structure
+//!          pointed to by addr, on return it will contain the actual 
+//!          length (in bytes) of the address returned.
+//!
+//! @sa     socket ; bind ; listen
+//
+//*****************************************************************************
+
+long
+accept(long sd, sockaddr *addr, socklen_t *addrlen)
+{
+	long ret;
+	unsigned char *ptr, *args;
+	tBsdReturnParams tAcceptReturnArguments;
+	
+	ret = EFAIL;
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in temporary command buffer
+	args = UINT32_TO_STREAM(args, sd);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_ACCEPT,
+									 ptr, SOCKET_ACCEPT_PARAMS_LEN);
+	
+	// Since we are in blocking state - wait for event complete
+	SimpleLinkWaitEvent(HCI_CMND_ACCEPT, &tAcceptReturnArguments);
+	
+	
+	// need specify return parameters!!!
+	memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN);
+	*addrlen = ASIC_ADDR_LEN;
+	errno = tAcceptReturnArguments.iStatus; 
+	ret = errno;
+	
+	// if succeeded, iStatus = new socket descriptor. otherwise - error number 
+	if(M_IS_VALID_SD(ret))
+	{
+		set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
+	}
+	else
+	{
+		set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
+	}
+	
+	return(ret);
+}
+
+//*****************************************************************************
+//
+//! bind
+//!
+//!  @param[in]   sd      socket descriptor (handle)              
+//!  @param[out]  addr    specifies the destination address. On this version 
+//!                       only AF_INET is supported.
+//!  @param[out] addrlen  contains the size of the structure pointed to by addr.
+//!
+//!  @return  	On success, zero is returned. On error, -1 is returned.
+//!
+//!  @brief  assign a name to a socket
+//!          This function gives the socket the local address addr.
+//!          addr is addrlen bytes long. Traditionally, this is called when a 
+//!          socket is created with socket, it exists in a name space (address 
+//!          family) but has no name assigned.
+//!          It is necessary to assign a local address before a SOCK_STREAM
+//!          socket may receive connections.
+//!
+//! @sa     socket ; accept ; listen
+//
+//*****************************************************************************
+
+long
+bind(long sd, const sockaddr *addr, long addrlen)
+{
+	long ret;
+	unsigned char *ptr, *args;
+	
+	ret = EFAIL;
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + HEADERS_SIZE_CMD);
+	
+	addrlen = ASIC_ADDR_LEN;
+	
+	// Fill in temporary command buffer
+	args = UINT32_TO_STREAM(args, sd);
+	args = UINT32_TO_STREAM(args, 0x00000008);
+	args = UINT32_TO_STREAM(args, addrlen);
+	ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_BIND,
+									 ptr, SOCKET_BIND_PARAMS_LEN);
+	
+	// Since we are in blocking state - wait for event complete
+	SimpleLinkWaitEvent(HCI_CMND_BIND, &ret);
+	
+	errno = ret;
+  
+	return(ret);
+}
+
+//*****************************************************************************
+//
+//! listen
+//!
+//!  @param[in]   sd      socket descriptor (handle)              
+//!  @param[in]  backlog  specifies the listen queue depth. On this version
+//!                       backlog is not supported.
+//!  @return  	On success, zero is returned. On error, -1 is returned.
+//!
+//!  @brief  listen for connections on a socket
+//!          The willingness to accept incoming connections and a queue
+//!          limit for incoming connections are specified with listen(),
+//!          and then the connections are accepted with accept.
+//!          The listen() call applies only to sockets of type SOCK_STREAM
+//!          The backlog parameter defines the maximum length the queue of
+//!          pending connections may grow to. 
+//!
+//! @sa     socket ; accept ; bind
+//!
+//! @note   On this version, backlog is not supported
+//
+//*****************************************************************************
+
+long
+listen(long sd, long backlog)
+{
+	long ret;
+	unsigned char *ptr, *args;
+	
+	ret = EFAIL;
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in temporary command buffer
+	args = UINT32_TO_STREAM(args, sd);
+	args = UINT32_TO_STREAM(args, backlog);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_LISTEN,
+									 ptr, SOCKET_LISTEN_PARAMS_LEN);
+	
+	// Since we are in blocking state - wait for event complete
+	SimpleLinkWaitEvent(HCI_CMND_LISTEN, &ret);
+	errno = ret;
+	
+	return(ret);
+}
+
+//*****************************************************************************
+//
+//! gethostbyname
+//!
+//!  @param[in]   hostname     host name              
+//!  @param[in]   usNameLen    name length 
+//!  @param[out]  out_ip_addr  This parameter is filled in with host IP address. 
+//!                            In case that host name is not resolved, 
+//!                            out_ip_addr is zero.                  
+//!  @return  	On success, positive is returned. On error, negative is returned
+//!
+//!  @brief  Get host IP by name. Obtain the IP Address of machine on network, 
+//!          by its name.
+//!
+//!  @note  On this version, only blocking mode is supported. Also note that
+//!		     the function requires DNS server to be configured prior to its usage.
+//
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+int 
+gethostbyname(char * hostname, unsigned short usNameLen, 
+							unsigned long* out_ip_addr)
+{
+	tBsdGethostbynameParams ret;
+	unsigned char *ptr, *args;
+	
+	errno = EFAIL;
+	
+	if (usNameLen > HOSTNAME_MAX_LENGTH)
+	{
+		return errno;
+	}
+	
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
+	
+	// Fill in HCI packet structure
+	args = UINT32_TO_STREAM(args, 8);
+	args = UINT32_TO_STREAM(args, usNameLen);
+	ARRAY_TO_STREAM(args, hostname, usNameLen);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN
+									 + usNameLen - 1);
+	
+	// Since we are in blocking state - wait for event complete
+	SimpleLinkWaitEvent(HCI_EVNT_BSD_GETHOSTBYNAME, &ret);
+	
+	errno = ret.retVal;
+	
+	(*((long*)out_ip_addr)) = ret.outputAddress;
+	
+	return (errno);
+	
+}
+#endif
+
+//*****************************************************************************
+//
+//! connect
+//!
+//!  @param[in]   sd       socket descriptor (handle)         
+//!  @param[in]   addr     specifies the destination addr. On this version
+//!                        only AF_INET is supported.
+//!  @param[out]  addrlen  contains the size of the structure pointed to by addr    
+//!  @return  	On success, zero is returned. On error, -1 is returned
+//!
+//!  @brief  initiate a connection on a socket 
+//!          Function connects the socket referred to by the socket descriptor 
+//!          sd, to the address specified by addr. The addrlen argument 
+//!          specifies the size of addr. The format of the address in addr is 
+//!          determined by the address space of the socket. If it is of type 
+//!          SOCK_DGRAM, this call specifies the peer with which the socket is 
+//!          to be associated; this address is that to which datagrams are to be
+//!          sent, and the only address from which datagrams are to be received.  
+//!          If the socket is of type SOCK_STREAM, this call attempts to make a 
+//!          connection to another socket. The other socket is specified  by 
+//!          address, which is an address in the communications space of the
+//!          socket. Note that the function implements only blocking behavior 
+//!          thus the caller will be waiting either for the connection 
+//!          establishment or for the connection establishment failure.
+//!
+//!  @sa socket
+//
+//*****************************************************************************
+
+long
+connect(long sd, const sockaddr *addr, long addrlen)
+{
+	long int ret;
+	unsigned char *ptr, *args;
+	
+	ret = EFAIL;
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
+	addrlen = 8;
+	
+	// Fill in temporary command buffer
+	args = UINT32_TO_STREAM(args, sd);
+	args = UINT32_TO_STREAM(args, 0x00000008);
+	args = UINT32_TO_STREAM(args, addrlen);
+	ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_CONNECT,
+									 ptr, SOCKET_CONNECT_PARAMS_LEN);
+	
+	// Since we are in blocking state - wait for event complete
+	SimpleLinkWaitEvent(HCI_CMND_CONNECT, &ret);
+	
+	errno = ret;
+	
+	return((long)ret);
+}
+
+
+//*****************************************************************************
+//
+//! select
+//!
+//!  @param[in]   nfds       the highest-numbered file descriptor in any of the
+//!                           three sets, plus 1.     
+//!  @param[out]   writesds   socket descriptors list for write monitoring
+//!  @param[out]   readsds    socket descriptors list for read monitoring  
+//!  @param[out]   exceptsds  socket descriptors list for exception monitoring
+//!  @param[in]   timeout     is an upper bound on the amount of time elapsed
+//!                           before select() returns. Null means infinity 
+//!                           timeout. The minimum timeout is 5 milliseconds,
+//!                          less than 5 milliseconds will be set
+//!                           automatically to 5 milliseconds.
+//!  @return  	On success, select() returns the number of file descriptors
+//!             contained in the three returned descriptor sets (that is, the
+//!             total number of bits that are set in readfds, writefds,
+//!             exceptfds) which may be zero if the timeout expires before
+//!             anything interesting  happens.
+//!             On error, -1 is returned.
+//!                   *readsds - return the sockets on which Read request will
+//!                              return without delay with valid data.
+//!                   *writesds - return the sockets on which Write request 
+//!                                 will return without delay.
+//!                   *exceptsds - return the sockets which closed recently.
+//!
+//!  @brief  Monitor socket activity  
+//!          Select allow a program to monitor multiple file descriptors,
+//!          waiting until one or more of the file descriptors become 
+//!         "ready" for some class of I/O operation 
+//!
+//!  @Note   If the timeout value set to less than 5ms it will automatically set
+//!          to 5ms to prevent overload of the system
+//!
+//!  @sa socket
+//
+//*****************************************************************************
+
+int
+select(long nfds, cc3000_fd_set *readsds, cc3000_fd_set *writesds,
+       cc3000_fd_set *exceptsds, struct timeval *timeout)
+{
+	unsigned char *ptr, *args;
+	tBsdSelectRecvParams tParams;
+	unsigned long is_blocking;
+	
+	if( timeout == NULL)
+	{
+		is_blocking = 1; /* blocking , infinity timeout */
+	}
+	else
+	{
+		is_blocking = 0; /* no blocking, timeout */
+	}
+	
+	// Fill in HCI packet structure
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in temporary command buffer
+	args = UINT32_TO_STREAM(args, nfds);
+	args = UINT32_TO_STREAM(args, 0x00000014);
+	args = UINT32_TO_STREAM(args, 0x00000014);
+	args = UINT32_TO_STREAM(args, 0x00000014);
+	args = UINT32_TO_STREAM(args, 0x00000014);
+	args = UINT32_TO_STREAM(args, is_blocking);
+	args = UINT32_TO_STREAM(args, ((readsds) ? *(unsigned long*)readsds : 0));
+	args = UINT32_TO_STREAM(args, ((writesds) ? *(unsigned long*)writesds : 0));
+	args = UINT32_TO_STREAM(args, ((exceptsds) ? *(unsigned long*)exceptsds : 0));
+	
+	if (timeout)
+	{
+		if ( 0 == timeout->tv_sec && timeout->tv_usec < 
+				SELECT_TIMEOUT_MIN_MICRO_SECONDS)
+		{
+			timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS;
+		}
+		args = UINT32_TO_STREAM(args, timeout->tv_sec);
+		args = UINT32_TO_STREAM(args, timeout->tv_usec);
+	}
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN);
+	
+	// Since we are in blocking state - wait for event complete
+	SimpleLinkWaitEvent(HCI_EVNT_SELECT, &tParams);
+	
+	// Update actually read FD
+	if (tParams.iStatus >= 0)
+	{
+		if (readsds)
+		{
+			memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd));
+		}
+		
+		if (writesds)
+		{
+			memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd)); 
+		}
+		
+		if (exceptsds)
+		{
+			memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd)); 
+		}
+		
+		return(tParams.iStatus);
+		
+	}
+	else
+	{
+		errno = tParams.iStatus;
+		return(-1);
+	}
+}
+
+//*****************************************************************************
+//
+//! setsockopt
+//!
+//!  @param[in]   sd          socket handle
+//!  @param[in]   level       defines the protocol level for this option
+//!  @param[in]   optname     defines the option name to Interrogate
+//!  @param[in]   optval      specifies a value for the option
+//!  @param[in]   optlen      specifies the length of the option value
+//!  @return  	On success, zero is returned. On error, -1 is returned
+//!
+//!  @brief  set socket options
+//!          This function manipulate the options associated with a socket.
+//!          Options may exist at multiple protocol levels; they are always
+//!          present at the uppermost socket level.
+//!          When manipulating socket options the level at which the option 
+//!          resides and the name of the option must be specified.  
+//!          To manipulate options at the socket level, level is specified as 
+//!          SOL_SOCKET. To manipulate options at any other level the protocol 
+//!          number of the appropriate protocol controlling the option is 
+//!          supplied. For example, to indicate that an option is to be 
+//!          interpreted by the TCP protocol, level should be set to the 
+//!          protocol number of TCP; 
+//!          The parameters optval and optlen are used to access optval - 
+//!          use for setsockopt(). For getsockopt() they identify a buffer
+//!          in which the value for the requested option(s) are to 
+//!          be returned. For getsockopt(), optlen is a value-result 
+//!          parameter, initially containing the size of the buffer 
+//!          pointed to by option_value, and modified on return to 
+//!          indicate the actual size of the value returned. If no option 
+//!          value is to be supplied or returned, option_value may be NULL.
+//!
+//!  @Note   On this version the following two socket options are enabled:
+//!    			 The only protocol level supported in this version
+//!          is SOL_SOCKET (level).
+//!		       1. SOCKOPT_RECV_TIMEOUT (optname)
+//!			      SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout 
+//!           in milliseconds.
+//!		        In that case optval should be pointer to unsigned long.
+//!		       2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on 
+//!           or off.
+//!		        In that case optval should be SOCK_ON or SOCK_OFF (optval).
+//!
+//!  @sa getsockopt
+//
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+int
+setsockopt(long sd, long level, long optname, const void *optval,
+					 socklen_t optlen)
+{
+	int ret;
+	unsigned char *ptr, *args;
+	
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in temporary command buffer
+	args = UINT32_TO_STREAM(args, sd);
+	args = UINT32_TO_STREAM(args, level);
+	args = UINT32_TO_STREAM(args, optname);
+	args = UINT32_TO_STREAM(args, 0x00000008);
+	args = UINT32_TO_STREAM(args, optlen);
+	ARRAY_TO_STREAM(args, ((unsigned char *)optval), optlen);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_SETSOCKOPT,
+									 ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN  + optlen);
+	
+	// Since we are in blocking state - wait for event complete
+	SimpleLinkWaitEvent(HCI_CMND_SETSOCKOPT, &ret);
+	
+	if (ret >= 0)
+	{
+		return (0);
+	}
+	else
+	{
+		errno = ret;
+		return (-1);
+	}
+}
+#endif
+
+//*****************************************************************************
+//
+//! getsockopt
+//!
+//!  @param[in]   sd          socket handle
+//!  @param[in]   level       defines the protocol level for this option
+//!  @param[in]   optname     defines the option name to Interrogate
+//!  @param[out]   optval      specifies a value for the option
+//!  @param[out]   optlen      specifies the length of the option value
+//!  @return  	On success, zero is returned. On error, -1 is returned
+//!
+//!  @brief  set socket options
+//!          This function manipulate the options associated with a socket.
+//!          Options may exist at multiple protocol levels; they are always
+//!          present at the uppermost socket level.
+//!          When manipulating socket options the level at which the option 
+//!          resides and the name of the option must be specified.  
+//!          To manipulate options at the socket level, level is specified as 
+//!          SOL_SOCKET. To manipulate options at any other level the protocol 
+//!          number of the appropriate protocol controlling the option is 
+//!          supplied. For example, to indicate that an option is to be 
+//!          interpreted by the TCP protocol, level should be set to the 
+//!          protocol number of TCP; 
+//!          The parameters optval and optlen are used to access optval - 
+//!          use for setsockopt(). For getsockopt() they identify a buffer
+//!          in which the value for the requested option(s) are to 
+//!          be returned. For getsockopt(), optlen is a value-result 
+//!          parameter, initially containing the size of the buffer 
+//!          pointed to by option_value, and modified on return to 
+//!          indicate the actual size of the value returned. If no option 
+//!          value is to be supplied or returned, option_value may be NULL.
+//!
+//!  @Note   On this version the following two socket options are enabled:
+//!    			 The only protocol level supported in this version
+//!          is SOL_SOCKET (level).
+//!		       1. SOCKOPT_RECV_TIMEOUT (optname)
+//!			      SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout 
+//!           in milliseconds.
+//!		        In that case optval should be pointer to unsigned long.
+//!		       2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on 
+//!           or off.
+//!		        In that case optval should be SOCK_ON or SOCK_OFF (optval).
+//!
+//!  @sa setsockopt
+//
+//*****************************************************************************
+
+int
+getsockopt (long sd, long level, long optname, void *optval, socklen_t *optlen)
+{
+	unsigned char *ptr, *args;
+	tBsdGetSockOptReturnParams  tRetParams;
+	
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in temporary command buffer
+	args = UINT32_TO_STREAM(args, sd);
+	args = UINT32_TO_STREAM(args, level);
+	args = UINT32_TO_STREAM(args, optname);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_GETSOCKOPT,
+									 ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN);
+	
+	// Since we are in blocking state - wait for event complete
+	SimpleLinkWaitEvent(HCI_CMND_GETSOCKOPT, &tRetParams);
+	
+	if (((signed char)tRetParams.iStatus) >= 0)
+	{
+		*optlen = 4;
+		memcpy(optval, tRetParams.ucOptValue, 4);
+		return (0);
+	}
+	else
+	{
+		errno = tRetParams.iStatus;
+		return (-1);
+	}
+}
+
+//*****************************************************************************
+//
+//!  simple_link_recv
+//!
+//!  @param sd       socket handle
+//!  @param buf      read buffer
+//!  @param len      buffer length
+//!  @param flags    indicates blocking or non-blocking operation
+//!  @param from     pointer to an address structure indicating source address
+//!  @param fromlen  source address structure size
+//!
+//!  @return         Return the number of bytes received, or -1 if an error
+//!                  occurred
+//!
+//!  @brief          Read data from socket
+//!                  Return the length of the message on successful completion.
+//!                  If a message is too long to fit in the supplied buffer,
+//!                  excess bytes may be discarded depending on the type of
+//!                  socket the message is received from
+//
+//*****************************************************************************
+int
+simple_link_recv(long sd, void *buf, long len, long flags, sockaddr *from,
+                socklen_t *fromlen, long opcode)
+{
+	unsigned char *ptr, *args;
+	tBsdReadReturnParams tSocketReadEvent;
+	
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in HCI packet structure
+	args = UINT32_TO_STREAM(args, sd);
+	args = UINT32_TO_STREAM(args, len);
+	args = UINT32_TO_STREAM(args, flags);
+	
+	// Generate the read command, and wait for the 
+	hci_command_send(opcode,  ptr, SOCKET_RECV_FROM_PARAMS_LEN);
+	
+	// Since we are in blocking state - wait for event complete
+	SimpleLinkWaitEvent(opcode, &tSocketReadEvent);
+	
+	// In case the number of bytes is more then zero - read data
+	if (tSocketReadEvent.iNumberOfBytes > 0)
+	{
+		// Wait for the data in a synchronous way. Here we assume that the bug is 
+		// big enough to store also parameters of receive from too....
+		SimpleLinkWaitData(buf, (unsigned char *)from, (unsigned char *)fromlen);
+	}
+	
+	errno = tSocketReadEvent.iNumberOfBytes;
+	
+	return(tSocketReadEvent.iNumberOfBytes);
+}
+
+//*****************************************************************************
+//
+//!  recv
+//!
+//!  @param[in]  sd     socket handle
+//!  @param[out] buf    Points to the buffer where the message should be stored
+//!  @param[in]  len    Specifies the length in bytes of the buffer pointed to 
+//!                     by the buffer argument.
+//!  @param[in] flags   Specifies the type of message reception. 
+//!                     On this version, this parameter is not supported.
+//!
+//!  @return         Return the number of bytes received, or -1 if an error
+//!                  occurred
+//!
+//!  @brief          function receives a message from a connection-mode socket
+//!
+//!  @sa recvfrom
+//!
+//!  @Note On this version, only blocking mode is supported.
+//
+//*****************************************************************************
+
+int
+recv(long sd, void *buf, long len, long flags)
+{
+	return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV));
+}
+
+//*****************************************************************************
+//
+//!  recvfrom
+//!
+//!  @param[in]  sd     socket handle
+//!  @param[out] buf    Points to the buffer where the message should be stored
+//!  @param[in]  len    Specifies the length in bytes of the buffer pointed to 
+//!                     by the buffer argument.
+//!  @param[in] flags   Specifies the type of message reception. 
+//!                     On this version, this parameter is not supported.
+//!  @param[in] from   pointer to an address structure indicating the source
+//!                    address: sockaddr. On this version only AF_INET is
+//!                    supported.
+//!  @param[in] fromlen   source address tructure size
+//!
+//!  @return         Return the number of bytes received, or -1 if an error
+//!                  occurred
+//!
+//!  @brief         read data from socket
+//!                 function receives a message from a connection-mode or
+//!                 connectionless-mode socket. Note that raw sockets are not
+//!                 supported.
+//!
+//!  @sa recv
+//!
+//!  @Note On this version, only blocking mode is supported.
+//
+//*****************************************************************************
+int
+recvfrom(long sd, void *buf, long len, long flags, sockaddr *from,
+         socklen_t *fromlen)
+{
+	return(simple_link_recv(sd, buf, len, flags, from, fromlen,
+													HCI_CMND_RECVFROM));
+}
+
+//*****************************************************************************
+//
+//!  simple_link_send
+//!
+//!  @param sd       socket handle
+//!  @param buf      write buffer
+//!  @param len      buffer length
+//!  @param flags    On this version, this parameter is not supported
+//!  @param to       pointer to an address structure indicating destination
+//!                  address
+//!  @param tolen    destination address structure size
+//!
+//!  @return         Return the number of bytes transmitted, or -1 if an error
+//!                  occurred, or -2 in case there are no free buffers available
+//!                 (only when SEND_NON_BLOCKING is enabled)
+//!
+//!  @brief          This function is used to transmit a message to another
+//!                  socket
+//
+//*****************************************************************************
+int
+simple_link_send(long sd, const void *buf, long len, long flags,
+              const sockaddr *to, long tolen, long opcode)
+{    
+	unsigned char uArgSize,  addrlen;
+	unsigned char *ptr, *pDataPtr, *args;
+	unsigned long addr_offset;
+	int res;
+        tBsdReadReturnParams tSocketSendEvent;
+	
+	// Check the bsd_arguments
+	if (0 != (res = HostFlowControlConsumeBuff(sd)))
+	{
+		return res;
+	}
+	
+	//Update the number of sent packets
+	tSLInformation.NumberOfSentPackets++;
+	
+	// Allocate a buffer and construct a packet and send it over spi
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + HEADERS_SIZE_DATA);
+	
+	// Update the offset of data and parameters according to the command
+	switch(opcode)
+	{ 
+	case HCI_CMND_SENDTO:
+		{
+			addr_offset = len + sizeof(len) + sizeof(len);
+			addrlen = 8;
+			uArgSize = SOCKET_SENDTO_PARAMS_LEN;
+			pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN;
+			break;
+		}
+		
+	case HCI_CMND_SEND:
+		{
+			tolen = 0;
+			to = NULL;
+			uArgSize = HCI_CMND_SEND_ARG_LENGTH;
+			pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH;
+			break;
+		}
+		
+	default:
+		{
+			break;
+		}
+	}
+	
+	// Fill in temporary command buffer
+	args = UINT32_TO_STREAM(args, sd);
+	args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd));
+	args = UINT32_TO_STREAM(args, len);
+	args = UINT32_TO_STREAM(args, flags);
+	
+	if (opcode == HCI_CMND_SENDTO)
+	{
+		args = UINT32_TO_STREAM(args, addr_offset);
+		args = UINT32_TO_STREAM(args, addrlen);
+	}
+	
+	// Copy the data received from user into the TX Buffer
+	ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)buf), len);
+	
+	// In case we are using SendTo, copy the to parameters
+	if (opcode == HCI_CMND_SENDTO)
+	{	
+		ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)to), tolen);
+	}
+	
+	// Initiate a HCI command
+	hci_data_send(opcode, ptr, uArgSize, len,(unsigned char*)to, tolen);
+        
+         if (opcode == HCI_CMND_SENDTO)
+            SimpleLinkWaitEvent(HCI_EVNT_SENDTO, &tSocketSendEvent);
+         else
+            SimpleLinkWaitEvent(HCI_EVNT_SEND, &tSocketSendEvent);
+	
+	return	(len);
+}
+
+
+//*****************************************************************************
+//
+//!  send
+//!
+//!  @param sd       socket handle
+//!  @param buf      Points to a buffer containing the message to be sent
+//!  @param len      message size in bytes
+//!  @param flags    On this version, this parameter is not supported
+//!
+//!  @return         Return the number of bytes transmitted, or -1 if an
+//!                  error occurred
+//!
+//!  @brief          Write data to TCP socket
+//!                  This function is used to transmit a message to another 
+//!                  socket.
+//!
+//!  @Note           On this version, only blocking mode is supported.
+//!
+//!  @sa             sendto
+//
+//*****************************************************************************
+
+int
+send(long sd, const void *buf, long len, long flags)
+{
+	return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND));
+}
+
+//*****************************************************************************
+//
+//!  sendto
+//!
+//!  @param sd       socket handle
+//!  @param buf      Points to a buffer containing the message to be sent
+//!  @param len      message size in bytes
+//!  @param flags    On this version, this parameter is not supported
+//!  @param to       pointer to an address structure indicating the destination
+//!                  address: sockaddr. On this version only AF_INET is
+//!                  supported.
+//!  @param tolen    destination address structure size
+//!
+//!  @return         Return the number of bytes transmitted, or -1 if an
+//!                  error occurred
+//!
+//!  @brief          Write data to TCP socket
+//!                  This function is used to transmit a message to another 
+//!                  socket.
+//!
+//!  @Note           On this version, only blocking mode is supported.
+//!
+//!  @sa             send
+//
+//*****************************************************************************
+
+int
+sendto(long sd, const void *buf, long len, long flags, const sockaddr *to,
+       socklen_t tolen)
+{
+	return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO));
+}
+
+//*****************************************************************************
+//
+//!  mdnsAdvertiser
+//!
+//!  @param[in] mdnsEnabled         flag to enable/disable the mDNS feature
+//!  @param[in] deviceServiceName   Service name as part of the published
+//!                                 canonical domain name
+//!  @param[in] deviceServiceNameLength   Length of the service name
+//!  
+//!
+//!  @return   On success, zero is returned, return SOC_ERROR if socket was not 
+//!            opened successfully, or if an error occurred.
+//!
+//!  @brief    Set CC3000 in mDNS advertiser mode in order to advertise itself.
+//
+//*****************************************************************************
+
+int
+mdnsAdvertiser(unsigned short mdnsEnabled, char * deviceServiceName, unsigned short deviceServiceNameLength)
+{
+	int ret;
+ 	unsigned char *pTxBuffer, *pArgs;
+	
+	if (deviceServiceNameLength > MDNS_DEVICE_SERVICE_MAX_LENGTH)
+	{
+		return EFAIL;
+	}
+	
+	pTxBuffer = tSLInformation.pucTxCommandBuffer;
+	pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
+	
+	// Fill in HCI packet structure
+	pArgs = UINT32_TO_STREAM(pArgs, mdnsEnabled);
+	pArgs = UINT32_TO_STREAM(pArgs, 8);
+	pArgs = UINT32_TO_STREAM(pArgs, deviceServiceNameLength);
+	ARRAY_TO_STREAM(pArgs, deviceServiceName, deviceServiceNameLength);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + deviceServiceNameLength);
+	
+	// Since we are in blocking state - wait for event complete
+	SimpleLinkWaitEvent(HCI_EVNT_MDNS_ADVERTISE, &ret);
+	
+	return ret;
+	
+}
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/socket.h b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/socket.h
new file mode 100644
index 0000000000000000000000000000000000000000..3c386b5103e4dc5f148c77ea2641ecdf63b6f3aa
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/socket.h
@@ -0,0 +1,665 @@
+/*****************************************************************************
+*
+*  socket.h  - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the   
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#ifndef __SOCKET_H__
+#define __SOCKET_H__
+
+/* fd_set renamed to cc3000_fd_set to avoid conflicts - KTOWN/02-JUN-13 */
+
+//*****************************************************************************
+//
+//! \addtogroup socket_api
+//! @{
+//
+//*****************************************************************************
+
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define HOSTNAME_MAX_LENGTH (230)  // 230 bytes + header shouldn't exceed 8 bit value
+
+//--------- Address Families --------
+
+#define  AF_INET                2
+#define  AF_INET6               23
+
+//------------ Socket Types ------------
+
+#define  SOCK_STREAM            1
+#define  SOCK_DGRAM             2
+#define  SOCK_RAW               3           // Raw sockets allow new IPv4 protocols to be implemented in user space. A raw socket receives or sends the raw datagram not including link level headers
+#define  SOCK_RDM               4
+#define  SOCK_SEQPACKET         5
+
+//----------- Socket Protocol ----------
+
+#define IPPROTO_IP              0           // dummy for IP
+#define IPPROTO_ICMP            1           // control message protocol
+#define IPPROTO_IPV4            IPPROTO_IP  // IP inside IP
+#define IPPROTO_TCP             6           // tcp
+#define IPPROTO_UDP             17          // user datagram protocol
+#define IPPROTO_IPV6            41          // IPv6 in IPv6
+#define IPPROTO_NONE            59          // No next header
+#define IPPROTO_RAW             255         // raw IP packet
+#define IPPROTO_MAX             256
+
+//----------- Socket retunr codes  -----------
+
+#define SOC_ERROR				(-1)		// error 
+#define SOC_IN_PROGRESS			(-2)		// socket in progress
+
+//----------- Socket Options -----------
+#define  SOL_SOCKET             0xffff		//  socket level
+#define  SOCKOPT_RECV_NONBLOCK         	0	// recv non block mode, set SOCK_ON or SOCK_OFF (default block mode)
+#define  SOCKOPT_RECV_TIMEOUT			1	// optname to configure recv and recvfromtimeout
+#define  SOCKOPT_ACCEPT_NONBLOCK		2	// accept non block mode, set SOCK_ON or SOCK_OFF (default block mode)
+#define  SOCK_ON                0			// socket non-blocking mode	is enabled		
+#define  SOCK_OFF               1			// socket blocking mode is enabled
+
+#define  TCP_NODELAY            0x0001
+#define  TCP_BSDURGENT          0x7000
+
+#define  MAX_PACKET_SIZE        1500
+#define  MAX_LISTEN_QUEUE       4
+
+#define  IOCTL_SOCKET_EVENTMASK
+
+#define CC3000_ENOBUFS          55          // No buffer space available
+
+#define __FD_SETSIZE            32
+
+#define  ASIC_ADDR_LEN          8
+	
+#define NO_QUERY_RECIVED        -3
+	
+	
+typedef struct _in_addr_t
+{
+    unsigned long s_addr;                   // load with inet_aton()
+} in_addr;
+
+typedef struct _sockaddr_t
+{
+    unsigned short int    sa_family;
+    unsigned char     sa_data[14];
+} sockaddr;
+
+typedef struct _sockaddr_in_t
+{
+    short            sin_family;            // e.g. AF_INET
+    unsigned short   sin_port;              // e.g. htons(3490)
+    in_addr          sin_addr;              // see struct in_addr, below
+    char             sin_zero[8];           // zero this if you want to
+} sockaddr_in;
+
+typedef unsigned long socklen_t;
+
+// The fd_set member is required to be an array of longs.
+typedef long int __fd_mask;
+
+// It's easier to assume 8-bit bytes than to get CHAR_BIT.
+#define __NFDBITS               (8 * sizeof (__fd_mask))
+#define __FDELT(d)              ((d) / __NFDBITS)
+#define __FDMASK(d)             ((__fd_mask) 1 << ((d) % __NFDBITS))
+
+// fd_set for select and pselect.
+typedef struct
+{
+    __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
+#define __FDS_BITS(set)        ((set)->fds_bits)
+} cc3000_fd_set;
+
+// We don't use `memset' because this would require a prototype and
+//   the array isn't too big.
+#define __FD_ZERO(set)                               \
+  do {                                                \
+    unsigned int __i;                                 \
+    cc3000_fd_set *__arr = (set);                            \
+    for (__i = 0; __i < sizeof (cc3000_fd_set) / sizeof (__fd_mask); ++__i) \
+      __FDS_BITS (__arr)[__i] = 0;                    \
+  } while (0)
+#define __FD_SET(d, set)       (__FDS_BITS (set)[__FDELT (d)] |= __FDMASK (d))
+#define __FD_CLR(d, set)       (__FDS_BITS (set)[__FDELT (d)] &= ~__FDMASK (d))
+#define __FD_ISSET(d, set)     (__FDS_BITS (set)[__FDELT (d)] & __FDMASK (d))
+
+// Access macros for 'fd_set'.
+#define CC3000_FD_SET(fd, fdsetp)      __FD_SET (fd, fdsetp)
+#define CC3000_FD_CLR(fd, fdsetp)      __FD_CLR (fd, fdsetp)
+#define CC3000_FD_ISSET(fd, fdsetp)    __FD_ISSET (fd, fdsetp)
+#define CC3000_FD_ZERO(fdsetp)         __FD_ZERO (fdsetp)
+
+//Use in case of Big Endian only
+  
+#define htonl(A)    ((((unsigned long)(A) & 0xff000000) >> 24) | \
+                     (((unsigned long)(A) & 0x00ff0000) >> 8) | \
+                     (((unsigned long)(A) & 0x0000ff00) << 8) | \
+                     (((unsigned long)(A) & 0x000000ff) << 24))
+
+#define ntohl                   htonl
+
+//Use in case of Big Endian only
+#define htons(A)     ((((unsigned long)(A) & 0xff00) >> 8) | \
+                      (((unsigned long)(A) & 0x00ff) << 8))
+
+
+#define ntohs                   htons
+
+// mDNS port - 5353    mDNS multicast address - 224.0.0.251 
+#define SET_mDNS_ADD(sockaddr)     	   	sockaddr.sa_data[0] = 0x14; \
+																								sockaddr.sa_data[1] = 0xe9; \
+																								sockaddr.sa_data[2] = 0xe0; \
+																								sockaddr.sa_data[3] = 0x0; \
+																								sockaddr.sa_data[4] = 0x0; \
+																								sockaddr.sa_data[5] = 0xfb; 
+
+
+//*****************************************************************************
+//
+// Prototypes for the APIs.
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+//! socket
+//!
+//!  @param  domain    selects the protocol family which will be used for 
+//!                    communication. On this version only AF_INET is supported
+//!  @param  type      specifies the communication semantics. On this version 
+//!                    only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported
+//!  @param  protocol  specifies a particular protocol to be used with the 
+//!                    socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are 
+//!                    supported.
+//!
+//!  @return  On success, socket handle that is used for consequent socket 
+//!           operations. On error, -1 is returned.
+//!
+//!  @brief  create an endpoint for communication
+//!          The socket function creates a socket that is bound to a specific 
+//!          transport service provider. This function is called by the 
+//!          application layer to obtain a socket handle.
+//
+//*****************************************************************************
+extern int socket(long domain, long type, long protocol);
+
+//*****************************************************************************
+//
+//! closesocket
+//!
+//!  @param  sd    socket handle.
+//!
+//!  @return  On success, zero is returned. On error, -1 is returned.
+//!
+//!  @brief  The socket function closes a created socket.
+//
+//*****************************************************************************
+extern long closesocket(long sd);
+
+//*****************************************************************************
+//
+//! accept
+//!
+//!  @param[in]   sd      socket descriptor (handle)              
+//!  @param[out]  addr    the argument addr is a pointer to a sockaddr structure
+//!                       This structure is filled in with the address of the  
+//!                       peer socket, as known to the communications layer.        
+//!                       determined. The exact format of the address returned             
+//!                       addr is by the socket's address sockaddr. 
+//!                       On this version only AF_INET is supported.
+//!                       This argument returns in network order.
+//!  @param[out] addrlen  the addrlen argument is a value-result argument: 
+//!                       it should initially contain the size of the structure
+//!                       pointed to by addr.
+//!
+//!  @return  For socket in blocking mode:
+//!				      On success, socket handle. on failure negative
+//!			      For socket in non-blocking mode:
+//!				     - On connection establishment, socket handle
+//!				     - On connection pending, SOC_IN_PROGRESS (-2)
+//!			       - On failure, SOC_ERROR	(-1)
+//!
+//!  @brief  accept a connection on a socket:
+//!          This function is used with connection-based socket types 
+//!          (SOCK_STREAM). It extracts the first connection request on the 
+//!          queue of pending connections, creates a new connected socket, and
+//!          returns a new file descriptor referring to that socket.
+//!          The newly created socket is not in the listening state. 
+//!          The original socket sd is unaffected by this call. 
+//!          The argument sd is a socket that has been created with socket(),
+//!          bound to a local address with bind(), and is  listening for 
+//!          connections after a listen(). The argument addr is a pointer 
+//!          to a sockaddr structure. This structure is filled in with the 
+//!          address of the peer socket, as known to the communications layer.
+//!          The exact format of the address returned addr is determined by the 
+//!          socket's address family. The addrlen argument is a value-result
+//!          argument: it should initially contain the size of the structure
+//!          pointed to by addr, on return it will contain the actual 
+//!          length (in bytes) of the address returned.
+//!
+//! @sa     socket ; bind ; listen
+//
+//*****************************************************************************
+extern long accept(long sd, sockaddr *addr, socklen_t *addrlen);
+
+//*****************************************************************************
+//
+//! bind
+//!
+//!  @param[in]   sd      socket descriptor (handle)              
+//!  @param[out]  addr    specifies the destination address. On this version 
+//!                       only AF_INET is supported.
+//!  @param[out] addrlen  contains the size of the structure pointed to by addr.
+//!
+//!  @return  	On success, zero is returned. On error, -1 is returned.
+//!
+//!  @brief  assign a name to a socket
+//!          This function gives the socket the local address addr.
+//!          addr is addrlen bytes long. Traditionally, this is called when a 
+//!          socket is created with socket, it exists in a name space (address 
+//!          family) but has no name assigned.
+//!          It is necessary to assign a local address before a SOCK_STREAM
+//!          socket may receive connections.
+//!
+//! @sa     socket ; accept ; listen
+//
+//*****************************************************************************
+extern long bind(long sd, const sockaddr *addr, long addrlen);
+
+//*****************************************************************************
+//
+//! listen
+//!
+//!  @param[in]   sd      socket descriptor (handle)              
+//!  @param[in]  backlog  specifies the listen queue depth. On this version
+//!                       backlog is not supported.
+//!  @return  	On success, zero is returned. On error, -1 is returned.
+//!
+//!  @brief  listen for connections on a socket
+//!          The willingness to accept incoming connections and a queue
+//!          limit for incoming connections are specified with listen(),
+//!          and then the connections are accepted with accept.
+//!          The listen() call applies only to sockets of type SOCK_STREAM
+//!          The backlog parameter defines the maximum length the queue of
+//!          pending connections may grow to. 
+//!
+//! @sa     socket ; accept ; bind
+//!
+//! @note   On this version, backlog is not supported
+//
+//*****************************************************************************
+extern long listen(long sd, long backlog);
+
+//*****************************************************************************
+//
+//! gethostbyname
+//!
+//!  @param[in]   hostname     host name              
+//!  @param[in]   usNameLen    name length 
+//!  @param[out]  out_ip_addr  This parameter is filled in with host IP address. 
+//!                            In case that host name is not resolved, 
+//!                            out_ip_addr is zero.                  
+//!  @return  	On success, positive is returned. On error, negative is returned
+//!
+//!  @brief  Get host IP by name. Obtain the IP Address of machine on network, 
+//!          by its name.
+//!
+//!  @note  On this version, only blocking mode is supported. Also note that
+//!		     the function requires DNS server to be configured prior to its usage.
+//
+//*****************************************************************************
+#ifndef CC3000_TINY_DRIVER 
+extern int gethostbyname(char * hostname, unsigned short usNameLen, unsigned long* out_ip_addr);
+#endif
+
+
+//*****************************************************************************
+//
+//! connect
+//!
+//!  @param[in]   sd       socket descriptor (handle)         
+//!  @param[in]   addr     specifies the destination addr. On this version
+//!                        only AF_INET is supported.
+//!  @param[out]  addrlen  contains the size of the structure pointed to by addr    
+//!  @return  	On success, zero is returned. On error, -1 is returned
+//!
+//!  @brief  initiate a connection on a socket 
+//!          Function connects the socket referred to by the socket descriptor 
+//!          sd, to the address specified by addr. The addrlen argument 
+//!          specifies the size of addr. The format of the address in addr is 
+//!          determined by the address space of the socket. If it is of type 
+//!          SOCK_DGRAM, this call specifies the peer with which the socket is 
+//!          to be associated; this address is that to which datagrams are to be
+//!          sent, and the only address from which datagrams are to be received.  
+//!          If the socket is of type SOCK_STREAM, this call attempts to make a 
+//!          connection to another socket. The other socket is specified  by 
+//!          address, which is an address in the communications space of the
+//!          socket. Note that the function implements only blocking behavior 
+//!          thus the caller will be waiting either for the connection 
+//!          establishment or for the connection establishment failure.
+//!
+//!  @sa socket
+//
+//*****************************************************************************
+extern long connect(long sd, const sockaddr *addr, long addrlen);
+
+//*****************************************************************************
+//
+//! select
+//!
+//!  @param[in]   nfds       the highest-numbered file descriptor in any of the
+//!                           three sets, plus 1.     
+//!  @param[out]   writesds   socket descriptors list for write monitoring
+//!  @param[out]   readsds    socket descriptors list for read monitoring  
+//!  @param[out]   exceptsds  socket descriptors list for exception monitoring
+//!  @param[in]   timeout     is an upper bound on the amount of time elapsed
+//!                           before select() returns. Null means infinity 
+//!                           timeout. The minimum timeout is 5 milliseconds,
+//!                          less than 5 milliseconds will be set
+//!                           automatically to 5 milliseconds.
+//!  @return  	On success, select() returns the number of file descriptors
+//!             contained in the three returned descriptor sets (that is, the
+//!             total number of bits that are set in readfds, writefds,
+//!             exceptfds) which may be zero if the timeout expires before
+//!             anything interesting  happens.
+//!             On error, -1 is returned.
+//!                   *readsds - return the sockets on which Read request will
+//!                              return without delay with valid data.
+//!                   *writesds - return the sockets on which Write request 
+//!                                 will return without delay.
+//!                   *exceptsds - return the sockets which closed recently.
+//!
+//!  @brief  Monitor socket activity  
+//!          Select allow a program to monitor multiple file descriptors,
+//!          waiting until one or more of the file descriptors become 
+//!         "ready" for some class of I/O operation 
+//!
+//!  @Note   If the timeout value set to less than 5ms it will automatically set
+//!          to 5ms to prevent overload of the system
+//!
+//!  @sa socket
+//
+//*****************************************************************************
+extern int select(long nfds, cc3000_fd_set *readsds, cc3000_fd_set *writesds,
+                  cc3000_fd_set *exceptsds, struct timeval *timeout);
+
+//*****************************************************************************
+//
+//! setsockopt
+//!
+//!  @param[in]   sd          socket handle
+//!  @param[in]   level       defines the protocol level for this option
+//!  @param[in]   optname     defines the option name to Interrogate
+//!  @param[in]   optval      specifies a value for the option
+//!  @param[in]   optlen      specifies the length of the option value
+//!  @return  	On success, zero is returned. On error, -1 is returned
+//!
+//!  @brief  set socket options
+//!          This function manipulate the options associated with a socket.
+//!          Options may exist at multiple protocol levels; they are always
+//!          present at the uppermost socket level.
+//!          When manipulating socket options the level at which the option 
+//!          resides and the name of the option must be specified.  
+//!          To manipulate options at the socket level, level is specified as 
+//!          SOL_SOCKET. To manipulate options at any other level the protocol 
+//!          number of the appropriate protocol controlling the option is 
+//!          supplied. For example, to indicate that an option is to be 
+//!          interpreted by the TCP protocol, level should be set to the 
+//!          protocol number of TCP; 
+//!          The parameters optval and optlen are used to access optval - 
+//!          use for setsockopt(). For getsockopt() they identify a buffer
+//!          in which the value for the requested option(s) are to 
+//!          be returned. For getsockopt(), optlen is a value-result 
+//!          parameter, initially containing the size of the buffer 
+//!          pointed to by option_value, and modified on return to 
+//!          indicate the actual size of the value returned. If no option 
+//!          value is to be supplied or returned, option_value may be NULL.
+//!
+//!  @Note   On this version the following two socket options are enabled:
+//!    			 The only protocol level supported in this version
+//!          is SOL_SOCKET (level).
+//!		       1. SOCKOPT_RECV_TIMEOUT (optname)
+//!			      SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout 
+//!           in milliseconds.
+//!		        In that case optval should be pointer to unsigned long.
+//!		       2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on 
+//!           or off.
+//!		        In that case optval should be SOCK_ON or SOCK_OFF (optval).
+//!
+//!  @sa getsockopt
+//
+//*****************************************************************************
+#ifndef CC3000_TINY_DRIVER 
+extern int setsockopt(long sd, long level, long optname, const void *optval,
+                      socklen_t optlen);
+#endif
+//*****************************************************************************
+//
+//! getsockopt
+//!
+//!  @param[in]   sd          socket handle
+//!  @param[in]   level       defines the protocol level for this option
+//!  @param[in]   optname     defines the option name to Interrogate
+//!  @param[out]   optval      specifies a value for the option
+//!  @param[out]   optlen      specifies the length of the option value
+//!  @return  	On success, zero is returned. On error, -1 is returned
+//!
+//!  @brief  set socket options
+//!          This function manipulate the options associated with a socket.
+//!          Options may exist at multiple protocol levels; they are always
+//!          present at the uppermost socket level.
+//!          When manipulating socket options the level at which the option 
+//!          resides and the name of the option must be specified.  
+//!          To manipulate options at the socket level, level is specified as 
+//!          SOL_SOCKET. To manipulate options at any other level the protocol 
+//!          number of the appropriate protocol controlling the option is 
+//!          supplied. For example, to indicate that an option is to be 
+//!          interpreted by the TCP protocol, level should be set to the 
+//!          protocol number of TCP; 
+//!          The parameters optval and optlen are used to access optval - 
+//!          use for setsockopt(). For getsockopt() they identify a buffer
+//!          in which the value for the requested option(s) are to 
+//!          be returned. For getsockopt(), optlen is a value-result 
+//!          parameter, initially containing the size of the buffer 
+//!          pointed to by option_value, and modified on return to 
+//!          indicate the actual size of the value returned. If no option 
+//!          value is to be supplied or returned, option_value may be NULL.
+//!
+//!  @Note   On this version the following two socket options are enabled:
+//!    			 The only protocol level supported in this version
+//!          is SOL_SOCKET (level).
+//!		       1. SOCKOPT_RECV_TIMEOUT (optname)
+//!			      SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout 
+//!           in milliseconds.
+//!		        In that case optval should be pointer to unsigned long.
+//!		       2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on 
+//!           or off.
+//!		        In that case optval should be SOCK_ON or SOCK_OFF (optval).
+//!
+//!  @sa setsockopt
+//
+//*****************************************************************************
+extern int getsockopt(long sd, long level, long optname, void *optval,
+                      socklen_t *optlen);
+
+//*****************************************************************************
+//
+//!  recv
+//!
+//!  @param[in]  sd     socket handle
+//!  @param[out] buf    Points to the buffer where the message should be stored
+//!  @param[in]  len    Specifies the length in bytes of the buffer pointed to 
+//!                     by the buffer argument.
+//!  @param[in] flags   Specifies the type of message reception. 
+//!                     On this version, this parameter is not supported.
+//!
+//!  @return         Return the number of bytes received, or -1 if an error
+//!                  occurred
+//!
+//!  @brief          function receives a message from a connection-mode socket
+//!
+//!  @sa recvfrom
+//!
+//!  @Note On this version, only blocking mode is supported.
+//
+//*****************************************************************************
+extern int recv(long sd, void *buf, long len, long flags);
+
+//*****************************************************************************
+//
+//!  recvfrom
+//!
+//!  @param[in]  sd     socket handle
+//!  @param[out] buf    Points to the buffer where the message should be stored
+//!  @param[in]  len    Specifies the length in bytes of the buffer pointed to 
+//!                     by the buffer argument.
+//!  @param[in] flags   Specifies the type of message reception. 
+//!                     On this version, this parameter is not supported.
+//!  @param[in] from   pointer to an address structure indicating the source
+//!                    address: sockaddr. On this version only AF_INET is
+//!                    supported.
+//!  @param[in] fromlen   source address structure size
+//!
+//!  @return         Return the number of bytes received, or -1 if an error
+//!                  occurred
+//!
+//!  @brief         read data from socket
+//!                 function receives a message from a connection-mode or
+//!                 connectionless-mode socket. Note that raw sockets are not
+//!                 supported.
+//!
+//!  @sa recv
+//!
+//!  @Note On this version, only blocking mode is supported.
+//
+//*****************************************************************************
+extern int recvfrom(long sd, void *buf, long len, long flags, sockaddr *from, 
+                    socklen_t *fromlen);
+
+//*****************************************************************************
+//
+//!  send
+//!
+//!  @param sd       socket handle
+//!  @param buf      Points to a buffer containing the message to be sent
+//!  @param len      message size in bytes
+//!  @param flags    On this version, this parameter is not supported
+//!
+//!  @return         Return the number of bytes transmitted, or -1 if an
+//!                  error occurred
+//!
+//!  @brief          Write data to TCP socket
+//!                  This function is used to transmit a message to another 
+//!                  socket.
+//!
+//!  @Note           On this version, only blocking mode is supported.
+//!
+//!  @sa             sendto
+//
+//*****************************************************************************
+
+extern int send(long sd, const void *buf, long len, long flags);
+
+//*****************************************************************************
+//
+//!  sendto
+//!
+//!  @param sd       socket handle
+//!  @param buf      Points to a buffer containing the message to be sent
+//!  @param len      message size in bytes
+//!  @param flags    On this version, this parameter is not supported
+//!  @param to       pointer to an address structure indicating the destination
+//!                  address: sockaddr. On this version only AF_INET is
+//!                  supported.
+//!  @param tolen    destination address structure size
+//!
+//!  @return         Return the number of bytes transmitted, or -1 if an
+//!                  error occurred
+//!
+//!  @brief          Write data to TCP socket
+//!                  This function is used to transmit a message to another 
+//!                  socket.
+//!
+//!  @Note           On this version, only blocking mode is supported.
+//!
+//!  @sa             send
+//
+//*****************************************************************************
+
+extern int sendto(long sd, const void *buf, long len, long flags, 
+                  const sockaddr *to, socklen_t tolen);
+
+//*****************************************************************************
+//
+//!  mdnsAdvertiser
+//!
+//!  @param[in] mdnsEnabled         flag to enable/disable the mDNS feature
+//!  @param[in] deviceServiceName   Service name as part of the published
+//!                                 canonical domain name
+//!  @param[in] deviceServiceNameLength   Length of the service name
+//!  
+//!
+//!  @return   On success, zero is returned, return SOC_ERROR if socket was not 
+//!            opened successfully, or if an error occurred.
+//!
+//!  @brief    Set CC3000 in mDNS advertiser mode in order to advertise itself.
+//
+//*****************************************************************************
+extern int mdnsAdvertiser(unsigned short mdnsEnabled, char * deviceServiceName, unsigned short deviceServiceNameLength);
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef  __cplusplus
+}
+#endif // __cplusplus
+
+#endif // __SOCKET_H__
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/wlan.c b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/wlan.c
new file mode 100644
index 0000000000000000000000000000000000000000..a6401e88fb8798a77ffe8ab62f16cebf2b4d95b0
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/wlan.c
@@ -0,0 +1,1255 @@
+/*****************************************************************************
+*
+*  wlan.c  - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the   
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_CC3000
+
+//*****************************************************************************
+//
+//! \addtogroup wlan_api
+//! @{
+//
+//*****************************************************************************
+#include <string.h>
+#include "wlan.h"
+#include "hci.h"
+#include "../spi.h"
+#include "socket.h"
+#include "nvmem.h"
+#include "security.h"
+#include "evnt_handler.h"
+
+
+volatile sSimplLinkInformation tSLInformation;
+
+#define SMART_CONFIG_PROFILE_SIZE		67		// 67 = 32 (max ssid) + 32 (max key) + 1 (SSID length) + 1 (security type) + 1 (key length)
+
+#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
+unsigned char key[AES128_KEY_SIZE];	
+unsigned char profileArray[SMART_CONFIG_PROFILE_SIZE];
+#endif //CC3000_UNENCRYPTED_SMART_CONFIG
+
+/* patches type */
+#define PATCHES_HOST_TYPE_WLAN_DRIVER   0x01
+#define PATCHES_HOST_TYPE_WLAN_FW       0x02
+#define PATCHES_HOST_TYPE_BOOTLOADER    0x03
+
+#define SL_SET_SCAN_PARAMS_INTERVAL_LIST_SIZE	(16)
+#define SL_SIMPLE_CONFIG_PREFIX_LENGTH (3)
+#define ETH_ALEN								(6)
+#define MAXIMAL_SSID_LENGTH						(32)
+
+#define SL_PATCHES_REQUEST_DEFAULT		(0)
+#define SL_PATCHES_REQUEST_FORCE_HOST	(1)
+#define SL_PATCHES_REQUEST_FORCE_NONE	(2)
+
+
+#define      WLAN_SEC_UNSEC (0)
+#define      WLAN_SEC_WEP	(1)
+#define      WLAN_SEC_WPA	(2)
+#define      WLAN_SEC_WPA2	(3)
+
+
+#define WLAN_SL_INIT_START_PARAMS_LEN			(1)
+#define WLAN_PATCH_PARAMS_LENGTH				(8)
+#define WLAN_SET_CONNECTION_POLICY_PARAMS_LEN	(12)
+#define WLAN_DEL_PROFILE_PARAMS_LEN				(4)
+#define WLAN_SET_MASK_PARAMS_LEN				(4)
+#define WLAN_SET_SCAN_PARAMS_LEN				(100)
+#define WLAN_GET_SCAN_RESULTS_PARAMS_LEN		(4)
+#define WLAN_ADD_PROFILE_NOSEC_PARAM_LEN		(24)			
+#define WLAN_ADD_PROFILE_WEP_PARAM_LEN			(36)
+#define WLAN_ADD_PROFILE_WPA_PARAM_LEN			(44)
+#define WLAN_CONNECT_PARAM_LEN					(29)
+#define WLAN_SMART_CONFIG_START_PARAMS_LEN		(4)
+
+
+
+
+//*****************************************************************************
+//
+//!  SimpleLink_Init_Start
+//!
+//!  @param  usPatchesAvailableAtHost  flag to indicate if patches available
+//!                                    from host or from EEPROM. Due to the 
+//!                                    fact the patches are burn to the EEPROM
+//!                                    using the patch programmer utility, the 
+//!                                    patches will be available from the EEPROM
+//!                                    and not from the host.
+//!
+//!  @return   none
+//!
+//!  @brief    Send HCI_CMND_SIMPLE_LINK_START to CC3000
+//
+//*****************************************************************************
+static void SimpleLink_Init_Start(unsigned short usPatchesAvailableAtHost)
+{
+	unsigned char *ptr;
+	unsigned char *args;
+	
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (unsigned char *)(ptr + HEADERS_SIZE_CMD);
+	
+	UINT8_TO_STREAM(args, ((usPatchesAvailableAtHost) ? SL_PATCHES_REQUEST_FORCE_HOST : SL_PATCHES_REQUEST_DEFAULT));
+	
+	// IRQ Line asserted - send HCI_CMND_SIMPLE_LINK_START to CC3000
+	hci_command_send(HCI_CMND_SIMPLE_LINK_START, ptr, WLAN_SL_INIT_START_PARAMS_LEN);
+	
+	SimpleLinkWaitEvent(HCI_CMND_SIMPLE_LINK_START, 0);
+}
+
+
+
+//*****************************************************************************
+//
+//!  wlan_init
+//!
+//!  @param  sWlanCB   Asynchronous events callback.  
+//!                    0 no event call back.
+//!                  -call back parameters:
+//!                   1) event_type: HCI_EVNT_WLAN_UNSOL_CONNECT connect event,
+//!                     HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event,
+//!                     HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE config done,
+//!                     HCI_EVNT_WLAN_UNSOL_DHCP dhcp report, 
+//!                     HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report OR 
+//!                     HCI_EVNT_WLAN_KEEPALIVE keepalive.
+//!                   2) data: pointer to extra data that received by the event
+//!                     (NULL no data).
+//!                   3) length: data length.
+//!                  -Events with extra data:
+//!                     HCI_EVNT_WLAN_UNSOL_DHCP: 4 bytes IP, 4 bytes Mask, 
+//!                     4 bytes default gateway, 4 bytes DHCP server and 4 bytes
+//!                     for DNS server.
+//!                     HCI_EVNT_WLAN_ASYNC_PING_REPORT: 4 bytes Packets sent, 
+//!                     4 bytes Packets received, 4 bytes Min round time, 
+//!                     4 bytes Max round time and 4 bytes for Avg round time.
+//!
+//!  @param    sFWPatches  0 no patch or pointer to FW patches 
+//!  @param    sDriverPatches  0 no patch or pointer to driver patches
+//!  @param    sBootLoaderPatches  0 no patch or pointer to bootloader patches
+//!  @param    sReadWlanInterruptPin    init callback. the callback read wlan 
+//!            interrupt status.
+//!  @param    sWlanInterruptEnable   init callback. the callback enable wlan 
+//!            interrupt.
+//!  @param    sWlanInterruptDisable   init callback. the callback disable wlan
+//!            interrupt.
+//!  @param    sWriteWlanPin      init callback. the callback write value 
+//!            to device pin.  
+//!
+//!  @return   none
+//!
+//!  @sa       wlan_set_event_mask , wlan_start , wlan_stop 
+//!
+//!  @brief    Initialize wlan driver
+//!
+//!  @warning This function must be called before ANY other wlan driver function
+//
+//*****************************************************************************
+
+void wlan_init(		tWlanCB	 	sWlanCB,
+							 tFWPatches sFWPatches,
+							 tDriverPatches sDriverPatches,
+							 tBootLoaderPatches sBootLoaderPatches,
+							 tWlanReadInteruptPin  sReadWlanInterruptPin,
+							 tWlanInterruptEnable  sWlanInterruptEnable,
+							 tWlanInterruptDisable sWlanInterruptDisable,
+							 tWriteWlanPin         sWriteWlanPin)
+{
+	
+	tSLInformation.sFWPatches = sFWPatches;
+	tSLInformation.sDriverPatches = sDriverPatches;
+	tSLInformation.sBootLoaderPatches = sBootLoaderPatches;
+	
+	// init io callback
+	tSLInformation.ReadWlanInterruptPin = sReadWlanInterruptPin;
+	tSLInformation.WlanInterruptEnable  = sWlanInterruptEnable;
+	tSLInformation.WlanInterruptDisable = sWlanInterruptDisable;
+	tSLInformation.WriteWlanPin = sWriteWlanPin;
+	
+	//init asynchronous events callback
+	tSLInformation.sWlanCB= sWlanCB;
+	
+	// By default TX Complete events are routed to host too
+	tSLInformation.InformHostOnTxComplete = 1;
+}
+
+//*****************************************************************************
+//
+//!  SpiReceiveHandler
+//!
+//!  @param         pvBuffer - pointer to the received data buffer
+//!                      The function triggers Received event/data processing
+//!                 
+//!  @param         Pointer to the received data
+//!  @return        none
+//!
+//!  @brief         The function triggers Received event/data processing. It is 
+//! 			          called from the SPI library to receive the data
+//
+//*****************************************************************************
+void SpiReceiveHandler(void *pvBuffer)
+{	
+	tSLInformation.usEventOrDataReceived = 1;
+	tSLInformation.pucReceivedData = (unsigned char 	*)pvBuffer;
+	
+	hci_unsolicited_event_handler();
+}
+
+
+//*****************************************************************************
+//
+//!  wlan_start
+//!
+//!  @param   usPatchesAvailableAtHost -  flag to indicate if patches available
+//!                                    from host or from EEPROM. Due to the 
+//!                                    fact the patches are burn to the EEPROM
+//!                                    using the patch programmer utility, the 
+//!                                    patches will be available from the EEPROM
+//!                                    and not from the host.
+//!
+//!  @return        none
+//!
+//!  @brief        Start WLAN device. This function asserts the enable pin of 
+//!                the device (WLAN_EN), starting the HW initialization process.
+//!                The function blocked until device Initialization is completed.
+//!                Function also configure patches (FW, driver or bootloader) 
+//!                and calls appropriate device callbacks.
+//!
+//!  @Note          Prior calling the function wlan_init shall be called.
+//!  @Warning       This function must be called after wlan_init and before any 
+//!                 other wlan API
+//!  @sa            wlan_init , wlan_stop
+//!
+//
+//*****************************************************************************
+
+void
+wlan_start(unsigned short usPatchesAvailableAtHost)
+{
+	
+	unsigned long ulSpiIRQState;
+	
+	tSLInformation.NumberOfSentPackets = 0;
+	tSLInformation.NumberOfReleasedPackets = 0;
+	tSLInformation.usRxEventOpcode = 0;
+	tSLInformation.usNumberOfFreeBuffers = 0;
+	tSLInformation.usSlBufferLength = 0;
+	tSLInformation.usBufferSize = 0;
+	tSLInformation.usRxDataPending = 0;
+	tSLInformation.slTransmitDataError = 0;
+	tSLInformation.usEventOrDataReceived = 0;
+	tSLInformation.pucReceivedData = 0;
+	
+	// Allocate the memory for the RX/TX data transactions
+	tSLInformation.pucTxCommandBuffer = (unsigned char *)wlan_tx_buffer;
+	
+	// init spi
+	SpiOpen(SpiReceiveHandler);
+	
+	// Check the IRQ line
+	ulSpiIRQState = tSLInformation.ReadWlanInterruptPin();
+	
+	// ASIC 1273 chip enable: toggle WLAN EN line
+	tSLInformation.WriteWlanPin( WLAN_ENABLE );
+	
+	if (ulSpiIRQState)
+	{
+		// wait till the IRQ line goes low
+		while(tSLInformation.ReadWlanInterruptPin() != 0)
+		{
+		}
+	}
+	else
+	{
+		// wait till the IRQ line goes high and than low
+		while(tSLInformation.ReadWlanInterruptPin() == 0)
+		{
+		}
+		
+		while(tSLInformation.ReadWlanInterruptPin() != 0)
+		{
+		}
+	}
+	
+	SimpleLink_Init_Start(usPatchesAvailableAtHost);
+	
+	// Read Buffer's size and finish
+	hci_command_send(HCI_CMND_READ_BUFFER_SIZE, tSLInformation.pucTxCommandBuffer, 0);
+	SimpleLinkWaitEvent(HCI_CMND_READ_BUFFER_SIZE, 0);
+}
+
+
+//*****************************************************************************
+//
+//!  wlan_stop
+//!
+//!  @param         none
+//!
+//!  @return        none
+//!
+//!  @brief         Stop WLAN device by putting it into reset state.
+//!
+//!  @sa            wlan_start
+//
+//*****************************************************************************
+
+void
+wlan_stop(void)
+{
+	// ASIC 1273 chip disable
+	tSLInformation.WriteWlanPin( WLAN_DISABLE );
+	
+	// Wait till IRQ line goes high...
+	while(tSLInformation.ReadWlanInterruptPin() == 0)
+	{
+	}
+	
+	// Free the used by WLAN Driver memory
+	if (tSLInformation.pucTxCommandBuffer)
+	{
+		tSLInformation.pucTxCommandBuffer = 0;
+	}
+	
+	SpiClose();
+}
+
+
+//*****************************************************************************
+//
+//!  wlan_connect
+//!
+//!  @param    sec_type   security options:
+//!               WLAN_SEC_UNSEC, 
+//!               WLAN_SEC_WEP (ASCII support only),
+//!               WLAN_SEC_WPA or WLAN_SEC_WPA2
+//!  @param    ssid       up to 32 bytes and is ASCII SSID of the AP
+//!  @param    ssid_len   length of the SSID
+//!  @param    bssid      6 bytes specified the AP bssid
+//!  @param    key        up to 16 bytes specified the AP security key
+//!  @param    key_len    key length 
+//!
+//!  @return     On success, zero is returned. On error, negative is returned. 
+//!              Note that even though a zero is returned on success to trigger
+//!              connection operation, it does not mean that CCC3000 is already
+//!              connected. An asynchronous "Connected" event is generated when 
+//!              actual association process finishes and CC3000 is connected to
+//!              the AP. If DHCP is set, An asynchronous "DHCP" event is 
+//!              generated when DHCP process is finish.
+//!              
+//!
+//!  @brief      Connect to AP
+//!  @warning    Please Note that when connection to AP configured with security
+//!              type WEP, please confirm that the key is set as ASCII and not
+//!              as HEX.
+//!  @sa         wlan_disconnect
+//
+//*****************************************************************************
+  
+#ifndef CC3000_TINY_DRIVER
+long
+wlan_connect(unsigned long ulSecType, char *ssid, long ssid_len,
+             unsigned char *bssid, unsigned char *key, long key_len)
+{
+	long ret;
+	unsigned char *ptr;
+	unsigned char *args;
+	unsigned char bssid_zero[] = {0, 0, 0, 0, 0, 0};
+	
+	ret  	= EFAIL;
+	ptr  	= tSLInformation.pucTxCommandBuffer;
+	args 	= (ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in command buffer
+	args = UINT32_TO_STREAM(args, 0x0000001c);
+	args = UINT32_TO_STREAM(args, ssid_len);
+	args = UINT32_TO_STREAM(args, ulSecType);
+	args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len);
+	args = UINT32_TO_STREAM(args, key_len);
+	args = UINT16_TO_STREAM(args, 0);
+	
+	// padding shall be zeroed
+	if(bssid)
+	{
+		ARRAY_TO_STREAM(args, bssid, ETH_ALEN);
+	}
+	else
+	{
+		ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
+	}
+	
+	ARRAY_TO_STREAM(args, ssid, ssid_len);
+	
+	if(key_len && key)
+	{
+		ARRAY_TO_STREAM(args, key, key_len);
+	}
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + 
+									 ssid_len + key_len - 1);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_CMND_WLAN_CONNECT, &ret);
+	errno = ret;
+	
+	return(ret);
+}
+#else
+long
+wlan_connect(char *ssid, long ssid_len)
+{
+	long ret;
+	unsigned char *ptr;
+	unsigned char *args;
+	unsigned char bssid_zero[] = {0, 0, 0, 0, 0, 0};
+	
+	ret  	= EFAIL;
+	ptr  	= tSLInformation.pucTxCommandBuffer;
+	args 	= (ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in command buffer
+	args = UINT32_TO_STREAM(args, 0x0000001c);
+	args = UINT32_TO_STREAM(args, ssid_len);
+	args = UINT32_TO_STREAM(args, 0);
+	args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len);
+	args = UINT32_TO_STREAM(args, 0);
+	args = UINT16_TO_STREAM(args, 0);
+	
+	// padding shall be zeroed
+	ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
+	ARRAY_TO_STREAM(args, ssid, ssid_len);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + 
+									 ssid_len  - 1);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_CMND_WLAN_CONNECT, &ret);
+	errno = ret;
+	
+	return(ret);
+}
+#endif
+
+//*****************************************************************************
+//
+//!  wlan_disconnect
+//!
+//!  @return    0 disconnected done, other CC3000 already disconnected            
+//!
+//!  @brief      Disconnect connection from AP. 
+//!
+//!  @sa         wlan_connect
+//
+//*****************************************************************************
+
+long
+wlan_disconnect()
+{
+	long ret;
+	unsigned char *ptr;
+	
+	ret = EFAIL;
+	ptr = tSLInformation.pucTxCommandBuffer;
+	
+	hci_command_send(HCI_CMND_WLAN_DISCONNECT, ptr, 0);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_CMND_WLAN_DISCONNECT, &ret);
+	errno = ret;
+	
+	return(ret);
+}
+
+//*****************************************************************************
+//
+//!  wlan_ioctl_set_connection_policy
+//!
+//!  @param    should_connect_to_open_ap  enable(1), disable(0) connect to any 
+//!            available AP. This parameter corresponds to the configuration of 
+//!            item # 3 in the brief description.
+//!  @param    should_use_fast_connect enable(1), disable(0). if enabled, tries 
+//!            to connect to the last connected AP. This parameter corresponds 
+//!            to the configuration of item # 1 in the brief description.
+//!  @param    auto_start enable(1), disable(0) auto connect 
+//!            after reset and periodically reconnect if needed. This 
+//!       	   configuration configures option 2 in the above description.
+//!
+//!  @return     On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief      When auto is enabled, the device tries to connect according 
+//!              the following policy:
+//!              1) If fast connect is enabled and last connection is valid, 
+//!                 the device will try to connect to it without the scanning 
+//!                 procedure (fast). The last connection will be marked as
+//!                 invalid, due to adding/removing profile. 
+//!              2) If profile exists, the device will try to connect it 
+//!                 (Up to seven profiles).
+//!              3) If fast and profiles are not found, and open mode is
+//!                 enabled, the device will try to connect to any AP.
+//!              * Note that the policy settings are stored in the CC3000 NVMEM.
+//!
+//!  @sa         wlan_add_profile , wlan_ioctl_del_profile 
+//
+//*****************************************************************************
+
+long
+wlan_ioctl_set_connection_policy(unsigned long should_connect_to_open_ap, 
+                                 unsigned long ulShouldUseFastConnect,
+                                 unsigned long ulUseProfiles)
+{
+	long ret;
+	unsigned char *ptr;
+	unsigned char *args;
+	
+	ret = EFAIL;
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (unsigned char *)(ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in HCI packet structure
+	args = UINT32_TO_STREAM(args, should_connect_to_open_ap);
+	args = UINT32_TO_STREAM(args, ulShouldUseFastConnect);
+	args = UINT32_TO_STREAM(args, ulUseProfiles);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY,
+									 ptr, WLAN_SET_CONNECTION_POLICY_PARAMS_LEN);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, &ret);
+	
+	return(ret);
+}
+
+//*****************************************************************************
+//
+//!  wlan_add_profile
+//!
+//!  @param    ulSecType  WLAN_SEC_UNSEC,WLAN_SEC_WEP,WLAN_SEC_WPA,WLAN_SEC_WPA2
+//!  @param    ucSsid    ssid  SSID up to 32 bytes
+//!  @param    ulSsidLen ssid length
+//!  @param    ucBssid   bssid  6 bytes
+//!  @param    ulPriority ulPriority profile priority. Lowest priority:0.
+//!  @param    ulPairwiseCipher_Or_TxKeyLen  key length for WEP security
+//!  @param    ulGroupCipher_TxKeyIndex  key index
+//!  @param    ulKeyMgmt        KEY management 
+//!  @param    ucPf_OrKey       security key
+//!  @param    ulPassPhraseLen  security key length for WPA\WPA2
+//!
+//!  @return    On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief     When auto start is enabled, the device connects to
+//!             station from the profiles table. Up to 7 profiles are supported. 
+//!             If several profiles configured the device choose the highest 
+//!             priority profile, within each priority group, device will choose 
+//!             profile based on security policy, signal strength, etc 
+//!             parameters. All the profiles are stored in CC3000 NVMEM.
+//!
+//!  @sa        wlan_ioctl_del_profile 
+//
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+long
+wlan_add_profile(unsigned long ulSecType, 
+								 unsigned char* ucSsid,
+								 unsigned long ulSsidLen, 
+								 unsigned char *ucBssid,
+								 unsigned long ulPriority,
+								 unsigned long ulPairwiseCipher_Or_TxKeyLen,
+								 unsigned long ulGroupCipher_TxKeyIndex,
+								 unsigned long ulKeyMgmt,
+								 unsigned char* ucPf_OrKey,
+								 unsigned long ulPassPhraseLen)
+{
+	unsigned short arg_len;
+	long ret;
+	unsigned char *ptr;
+	long i = 0;
+	unsigned char *args;
+	unsigned char bssid_zero[] = {0, 0, 0, 0, 0, 0};
+	
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + HEADERS_SIZE_CMD);
+	
+	args = UINT32_TO_STREAM(args, ulSecType);
+	
+	// Setup arguments in accordance with the security type
+	switch (ulSecType)
+	{
+		//OPEN
+	case WLAN_SEC_UNSEC:
+		{
+			args = UINT32_TO_STREAM(args, 0x00000014);
+			args = UINT32_TO_STREAM(args, ulSsidLen);
+			args = UINT16_TO_STREAM(args, 0);
+			if(ucBssid)
+			{
+				ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN);
+			}
+			else
+			{
+				ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
+			}
+			args = UINT32_TO_STREAM(args, ulPriority);
+			ARRAY_TO_STREAM(args, ucSsid, ulSsidLen);
+			
+			arg_len = WLAN_ADD_PROFILE_NOSEC_PARAM_LEN + ulSsidLen;
+		}
+		break;
+		
+		//WEP
+	case WLAN_SEC_WEP:
+		{
+			args = UINT32_TO_STREAM(args, 0x00000020);
+			args = UINT32_TO_STREAM(args, ulSsidLen);
+			args = UINT16_TO_STREAM(args, 0);
+			if(ucBssid)
+			{
+				ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN);
+			}
+			else
+			{
+				ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
+			}
+			args = UINT32_TO_STREAM(args, ulPriority);
+			args = UINT32_TO_STREAM(args, 0x0000000C + ulSsidLen);
+			args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen);
+			args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex);
+			ARRAY_TO_STREAM(args, ucSsid, ulSsidLen);
+			
+			for(i = 0; i < 4; i++)
+			{
+				unsigned char *p = &ucPf_OrKey[i * ulPairwiseCipher_Or_TxKeyLen];
+				
+				ARRAY_TO_STREAM(args, p, ulPairwiseCipher_Or_TxKeyLen);
+			}		
+			
+			arg_len = WLAN_ADD_PROFILE_WEP_PARAM_LEN + ulSsidLen + 
+				ulPairwiseCipher_Or_TxKeyLen * 4;
+			
+		}
+		break;
+		
+		//WPA
+		//WPA2
+	case WLAN_SEC_WPA:
+	case WLAN_SEC_WPA2:
+		{
+			args = UINT32_TO_STREAM(args, 0x00000028);
+			args = UINT32_TO_STREAM(args, ulSsidLen);
+			args = UINT16_TO_STREAM(args, 0);
+			if(ucBssid)
+			{
+				ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN);
+			}
+			else
+			{
+				ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
+			}
+			args = UINT32_TO_STREAM(args, ulPriority);
+			args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen);
+			args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex);
+			args = UINT32_TO_STREAM(args, ulKeyMgmt);
+			args = UINT32_TO_STREAM(args, 0x00000008 + ulSsidLen);
+			args = UINT32_TO_STREAM(args, ulPassPhraseLen);
+			ARRAY_TO_STREAM(args, ucSsid, ulSsidLen);
+			ARRAY_TO_STREAM(args, ucPf_OrKey, ulPassPhraseLen);
+			
+			arg_len = WLAN_ADD_PROFILE_WPA_PARAM_LEN + ulSsidLen + ulPassPhraseLen;
+		}
+		
+		break;
+	}    
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_WLAN_IOCTL_ADD_PROFILE,
+									 ptr, arg_len);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, &ret);
+	
+	return(ret);
+}
+#else
+long
+wlan_add_profile(unsigned long ulSecType, 
+								 unsigned char* ucSsid,
+								 unsigned long ulSsidLen, 
+								 unsigned char *ucBssid,
+								 unsigned long ulPriority,
+								 unsigned long ulPairwiseCipher_Or_TxKeyLen,
+								 unsigned long ulGroupCipher_TxKeyIndex,
+								 unsigned long ulKeyMgmt,
+								 unsigned char* ucPf_OrKey,
+								 unsigned long ulPassPhraseLen)
+{
+	return -1;
+}
+#endif
+
+//*****************************************************************************
+//
+//!  wlan_ioctl_del_profile
+//!
+//!  @param    index   number of profile to delete
+//!
+//!  @return    On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief     Delete WLAN profile 
+//!
+//!  @Note      In order to delete all stored profile, set index to 255.
+//!
+//!  @sa        wlan_add_profile 
+//
+//*****************************************************************************
+
+long
+wlan_ioctl_del_profile(unsigned long ulIndex)
+{
+	long ret;
+	unsigned char *ptr;
+	unsigned char *args;
+	
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (unsigned char *)(ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in HCI packet structure
+	args = UINT32_TO_STREAM(args, ulIndex);
+	ret = EFAIL;
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_WLAN_IOCTL_DEL_PROFILE,
+									 ptr, WLAN_DEL_PROFILE_PARAMS_LEN);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, &ret);
+	
+	return(ret);
+}
+
+//*****************************************************************************
+//
+//!  wlan_ioctl_get_scan_results
+//!
+//!  @param[in]    scan_timeout   parameter not supported
+//!  @param[out]   ucResults  scan results (_wlan_full_scan_results_args_t)
+//!
+//!  @return    On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief    Gets entry from scan result table.
+//!            The scan results are returned one by one, and each entry 
+//!            represents a single AP found in the area. The following is a 
+//!            format of the scan result: 
+//!        	 - 4 Bytes: number of networks found
+//!          - 4 Bytes: The status of the scan: 0 - aged results,
+//!                     1 - results valid, 2 - no results
+//!          - 42 bytes: Result entry, where the bytes are arranged as  follows:
+//!              
+//!          				- 1 bit isValid - is result valid or not
+//!         				- 7 bits rssi - RSSI value;	 
+//!                 - 2 bits: securityMode - security mode of the AP:
+//!                           0 - Open, 1 - WEP, 2 WPA, 3 WPA2
+//!         				- 6 bits: SSID name length
+//!         				- 2 bytes: the time at which the entry has entered into 
+//!                            scans result table
+//!         				- 32 bytes: SSID name
+//!                 - 6 bytes:	BSSID 
+//!
+//!  @Note      scan_timeout, is not supported on this version.
+//!
+//!  @sa        wlan_ioctl_set_scan_params 
+//
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+long
+wlan_ioctl_get_scan_results(unsigned long ulScanTimeout,
+                            unsigned char *ucResults)
+{
+	unsigned char *ptr;
+	unsigned char *args;
+	
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in temporary command buffer
+	args = UINT32_TO_STREAM(args, ulScanTimeout);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS,
+									 ptr, WLAN_GET_SCAN_RESULTS_PARAMS_LEN);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, ucResults);
+	
+	return(0);
+}
+#endif
+
+//*****************************************************************************
+//
+//!  wlan_ioctl_set_scan_params
+//!
+//!  @param    uiEnable - start/stop application scan: 
+//!            1 = start scan with default interval value of 10 min. 
+//!            in order to set a different scan interval value apply the value 
+//!            in milliseconds. minimum 1 second. 0=stop). Wlan reset
+//!           (wlan_stop() wlan_start()) is needed when changing scan interval
+//!            value. Saved: No
+//!  @param   uiMinDwellTime   minimum dwell time value to be used for each 
+//!           channel, in milliseconds. Saved: yes
+//!           Recommended Value: 100 (Default: 20)
+//!  @param   uiMaxDwellTime    maximum dwell time value to be used for each
+//!           channel, in milliseconds. Saved: yes
+//!           Recommended Value: 100 (Default: 30)
+//!  @param   uiNumOfProbeRequests  max probe request between dwell time. 
+//!           Saved: yes. Recommended Value: 5 (Default:2)
+//!  @param   uiChannelMask  bitwise, up to 13 channels (0x1fff). 
+//!           Saved: yes. Default: 0x7ff
+//!  @param   uiRSSIThreshold   RSSI threshold. Saved: yes (Default: -80)
+//!  @param   uiSNRThreshold    NSR threshold. Saved: yes (Default: 0)
+//!  @param   uiDefaultTxPower  probe Tx power. Saved: yes (Default: 205)
+//!  @param   aiIntervalList    pointer to array with 16 entries (16 channels) 
+//!           each entry (unsigned long) holds timeout between periodic scan 
+//!           (connection scan) - in millisecond. Saved: yes. Default 2000ms.
+//!
+//!  @return    On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief    start and stop scan procedure. Set scan parameters. 
+//!
+//!  @Note     uiDefaultTxPower, is not supported on this version.
+//!
+//!  @sa        wlan_ioctl_get_scan_results 
+//
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+long
+wlan_ioctl_set_scan_params(unsigned long uiEnable, unsigned long uiMinDwellTime,
+													 unsigned long uiMaxDwellTime,
+													 unsigned long uiNumOfProbeRequests,
+													 unsigned long uiChannelMask,long iRSSIThreshold,
+													 unsigned long uiSNRThreshold,
+													 unsigned long uiDefaultTxPower,
+													 unsigned long *aiIntervalList)
+{
+	unsigned long  uiRes;
+	unsigned char *ptr;
+	unsigned char *args;
+	
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in temporary command buffer
+	args = UINT32_TO_STREAM(args, 36);
+	args = UINT32_TO_STREAM(args, uiEnable);
+	args = UINT32_TO_STREAM(args, uiMinDwellTime);
+	args = UINT32_TO_STREAM(args, uiMaxDwellTime);
+	args = UINT32_TO_STREAM(args, uiNumOfProbeRequests);
+	args = UINT32_TO_STREAM(args, uiChannelMask);
+	args = UINT32_TO_STREAM(args, iRSSIThreshold);
+	args = UINT32_TO_STREAM(args, uiSNRThreshold);
+	args = UINT32_TO_STREAM(args, uiDefaultTxPower);
+	ARRAY_TO_STREAM(args, aiIntervalList, sizeof(unsigned long) * 
+									SL_SET_SCAN_PARAMS_INTERVAL_LIST_SIZE);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM,
+									 ptr, WLAN_SET_SCAN_PARAMS_LEN);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, &uiRes);
+	
+	return(uiRes);
+}
+#endif
+
+//*****************************************************************************
+//
+//!  wlan_set_event_mask
+//!
+//!  @param    mask   mask option:
+//!       HCI_EVNT_WLAN_UNSOL_CONNECT connect event
+//!       HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event
+//!       HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE  smart config done
+//!       HCI_EVNT_WLAN_UNSOL_INIT init done
+//!       HCI_EVNT_WLAN_UNSOL_DHCP dhcp event report
+//!       HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report
+//!       HCI_EVNT_WLAN_KEEPALIVE keepalive
+//!       HCI_EVNT_WLAN_TX_COMPLETE - disable information on end of transmission
+//!   	  Saved: no.
+//!
+//!  @return    On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief    Mask event according to bit mask. In case that event is 
+//!            masked (1), the device will not send the masked event to host. 
+//
+//*****************************************************************************
+
+long
+wlan_set_event_mask(unsigned long ulMask)
+{
+	long ret;
+	unsigned char *ptr;
+	unsigned char *args;
+	
+	
+	if ((ulMask & HCI_EVNT_WLAN_TX_COMPLETE) == HCI_EVNT_WLAN_TX_COMPLETE)
+	{
+		tSLInformation.InformHostOnTxComplete = 0;
+		
+		// Since an event is a virtual event - i.e. it is not coming from CC3000
+		// there is no need to send anything to the device if it was an only event
+		if (ulMask == HCI_EVNT_WLAN_TX_COMPLETE)
+		{
+			return 0;
+		}
+		
+		ulMask &= ~HCI_EVNT_WLAN_TX_COMPLETE;
+		ulMask |= HCI_EVNT_WLAN_UNSOL_BASE;
+	}
+	else
+	{
+		tSLInformation.InformHostOnTxComplete = 1;
+	}
+	
+	ret = EFAIL;
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (unsigned char *)(ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in HCI packet structure
+	args = UINT32_TO_STREAM(args, ulMask);
+	
+	// Initiate a HCI command
+	hci_command_send(HCI_CMND_EVENT_MASK,
+									 ptr, WLAN_SET_MASK_PARAMS_LEN);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_CMND_EVENT_MASK, &ret);
+	
+	return(ret);
+}
+
+//*****************************************************************************
+//
+//!  wlan_ioctl_statusget
+//!
+//!  @param none 
+//!
+//!  @return    WLAN_STATUS_DISCONNECTED, WLAN_STATUS_SCANING, 
+//!             STATUS_CONNECTING or WLAN_STATUS_CONNECTED      
+//!
+//!  @brief    get wlan status: disconnected, scanning, connecting or connected
+//
+//*****************************************************************************
+
+#ifndef CC3000_TINY_DRIVER
+long
+wlan_ioctl_statusget(void)
+{
+	long ret;
+	unsigned char *ptr;
+	
+	ret = EFAIL;
+	ptr = tSLInformation.pucTxCommandBuffer;
+	
+	hci_command_send(HCI_CMND_WLAN_IOCTL_STATUSGET,
+									 ptr, 0);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_STATUSGET, &ret);
+	
+	return(ret);    
+}
+#endif
+
+//*****************************************************************************
+//
+//!  wlan_smart_config_start
+//!
+//!  @param    algoEncryptedFlag indicates whether the information is encrypted
+//!
+//!  @return   On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief   Start to acquire device profile. The device acquire its own 
+//!           profile, if profile message is found. The acquired AP information
+//!           is stored in CC3000 EEPROM only in case AES128 encryption is used.
+//!           In case AES128 encryption is not used, a profile is created by 
+//!           CC3000 internally.
+//!
+//!  @Note    An asynchronous event - Smart Config Done will be generated as soon
+//!           as the process finishes successfully.
+//!
+//!  @sa      wlan_smart_config_set_prefix , wlan_smart_config_stop
+//
+//*****************************************************************************
+
+long
+wlan_smart_config_start(unsigned long algoEncryptedFlag)
+{
+	long ret;
+	unsigned char *ptr;
+	unsigned char *args;
+	
+	ret = EFAIL;
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (unsigned char *)(ptr + HEADERS_SIZE_CMD);
+	
+	// Fill in HCI packet structure
+	args = UINT32_TO_STREAM(args, algoEncryptedFlag);
+	ret = EFAIL;
+	
+	hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, ptr, 
+									 WLAN_SMART_CONFIG_START_PARAMS_LEN);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, &ret);
+	
+	return(ret);    
+}
+
+//*****************************************************************************
+//
+//!  wlan_smart_config_stop
+//!
+//!  @param    algoEncryptedFlag indicates whether the information is encrypted
+//!
+//!  @return   On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief   Stop the acquire profile procedure 
+//!
+//!  @sa      wlan_smart_config_start , wlan_smart_config_set_prefix
+//
+//*****************************************************************************
+
+long
+wlan_smart_config_stop(void)
+{
+	long ret;
+	unsigned char *ptr;
+	
+	ret = EFAIL;
+	ptr = tSLInformation.pucTxCommandBuffer;
+	
+	hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, ptr, 0);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, &ret);
+	
+	return(ret);    
+}
+
+//*****************************************************************************
+//
+//!  wlan_smart_config_set_prefix
+//!
+//!  @param   newPrefix  3 bytes identify the SSID prefix for the Smart Config. 
+//!
+//!  @return   On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief   Configure station ssid prefix. The prefix is used internally 
+//!           in CC3000. It should always be TTT.
+//!
+//!  @Note    The prefix is stored in CC3000 NVMEM
+//!
+//!  @sa      wlan_smart_config_start , wlan_smart_config_stop
+//
+//*****************************************************************************
+
+long
+wlan_smart_config_set_prefix(char* cNewPrefix)
+{
+	long ret;
+	unsigned char *ptr;
+	unsigned char *args;
+	
+	ret = EFAIL;
+	ptr = tSLInformation.pucTxCommandBuffer;
+	args = (ptr + HEADERS_SIZE_CMD);
+	
+	if (cNewPrefix == NULL)
+		return ret;
+	else	// with the new Smart Config, prefix must be TTT
+	{
+		*cNewPrefix = 'T';
+		*(cNewPrefix + 1) = 'T';
+		*(cNewPrefix + 2) = 'T';
+	}
+	
+	ARRAY_TO_STREAM(args, cNewPrefix, SL_SIMPLE_CONFIG_PREFIX_LENGTH);
+	
+	hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, ptr, 
+									 SL_SIMPLE_CONFIG_PREFIX_LENGTH);
+	
+	// Wait for command complete event
+	SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, &ret);
+	
+	return(ret);    
+}
+
+//*****************************************************************************
+//
+//!  wlan_smart_config_process
+//!
+//!  @param   none 
+//!
+//!  @return   On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief   process the acquired data and store it as a profile. The acquired 
+//!           AP information is stored in CC3000 EEPROM encrypted.
+//!           The encrypted data is decrypted and stored as a profile.
+//!           behavior is as defined by connection policy.
+//
+//*****************************************************************************
+
+
+#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
+long
+wlan_smart_config_process()
+{
+	signed long	returnValue;
+	unsigned long ssidLen, keyLen;
+	unsigned char *decKeyPtr;
+	unsigned char *ssidPtr;
+	
+	// read the key from EEPROM - fileID 12
+	returnValue = aes_read_key(key);
+	
+	if (returnValue != 0)
+		return returnValue;
+	
+	// read the received data from fileID #13 and parse it according to the followings:
+	// 1) SSID LEN - not encrypted
+	// 2) SSID - not encrypted
+	// 3) KEY LEN - not encrypted. always 32 bytes long
+	// 4) Security type - not encrypted
+	// 5) KEY - encrypted together with true key length as the first byte in KEY
+	//	 to elaborate, there are two corner cases:
+	//		1) the KEY is 32 bytes long. In this case, the first byte does not represent KEY length
+	//		2) the KEY is 31 bytes long. In this case, the first byte represent KEY length and equals 31
+	returnValue = nvmem_read(NVMEM_SHARED_MEM_FILEID, SMART_CONFIG_PROFILE_SIZE, 0, profileArray);
+	
+	if (returnValue != 0)
+		return returnValue;
+	
+	ssidPtr = &profileArray[1];
+	
+	ssidLen = profileArray[0];
+	
+	decKeyPtr = &profileArray[profileArray[0] + 3];
+	
+	aes_decrypt(decKeyPtr, key);
+	if (profileArray[profileArray[0] + 1] > 16)
+		aes_decrypt((unsigned char *)(decKeyPtr + 16), key);
+	
+	if (*(unsigned char *)(decKeyPtr +31) != 0)
+	{
+		if (*decKeyPtr == 31)
+		{
+			keyLen = 31;
+			decKeyPtr++;
+		}
+		else
+		{
+			keyLen = 32;
+		}
+	}
+	else
+	{
+		keyLen = *decKeyPtr;
+		decKeyPtr++;
+	}
+	
+	// add a profile
+	switch (profileArray[profileArray[0] + 2])
+	{
+	case WLAN_SEC_UNSEC://None
+	 	{
+			returnValue = wlan_add_profile(profileArray[profileArray[0] + 2], 	// security type
+																		 ssidPtr,		 					// SSID
+																		 ssidLen, 							// SSID length
+																		 NULL, 							// BSSID
+																		 1,								// Priority
+																		 0, 0, 0, 0, 0);
+			
+			break;
+	 	}
+		
+	case WLAN_SEC_WEP://WEP
+		{
+			returnValue = wlan_add_profile(profileArray[profileArray[0] + 2], 	// security type
+																		 ssidPtr, 							// SSID
+																		 ssidLen, 							// SSID length
+																		 NULL, 							// BSSID
+																		 1,								// Priority
+																		 keyLen,							// KEY length
+																		 0, 								// KEY index
+																		 0,
+																		 decKeyPtr,						// KEY
+																		 0);
+			
+			break;
+		}
+		
+	case WLAN_SEC_WPA://WPA
+	case WLAN_SEC_WPA2://WPA2
+		{
+			returnValue = wlan_add_profile(WLAN_SEC_WPA2, 	// security type
+																		 ssidPtr,
+																		 ssidLen,
+																		 NULL, 							// BSSID
+																		 1,								// Priority
+																		 0x18,							// PairwiseCipher
+																		 0x1e, 							// GroupCipher
+																		 2,								// KEY management
+																		 decKeyPtr,						// KEY
+																		 keyLen);							// KEY length
+			
+			break;
+		}
+	}
+	
+	return returnValue;
+}
+#endif //CC3000_UNENCRYPTED_SMART_CONFIG		
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/wlan.h b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/wlan.h
new file mode 100644
index 0000000000000000000000000000000000000000..ec5f7674e2f17665a157b728a211cb1f7af099d8
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/hostdriver/wlan.h
@@ -0,0 +1,517 @@
+/*****************************************************************************
+*
+*  wlan.h  - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the   
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#ifndef __WLAN_H__
+#define	__WLAN_H__
+
+#include "cc3000_common.h"
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#define      WLAN_SEC_UNSEC (0)
+#define      WLAN_SEC_WEP	(1)
+#define      WLAN_SEC_WPA	(2)
+#define      WLAN_SEC_WPA2	(3)
+//*****************************************************************************
+//
+//! \addtogroup wlan_api
+//! @{
+//
+//*****************************************************************************
+
+
+//*****************************************************************************
+//
+//!  wlan_init
+//!
+//!  @param  sWlanCB   Asynchronous events callback.  
+//!                    0 no event call back.
+//!                  -call back parameters:
+//!                   1) event_type: HCI_EVNT_WLAN_UNSOL_CONNECT connect event,
+//!                     HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event,
+//!                     HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE config done,
+//!                     HCI_EVNT_WLAN_UNSOL_DHCP dhcp report, 
+//!                     HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report OR 
+//!                     HCI_EVNT_WLAN_KEEPALIVE keepalive.
+//!                   2) data: pointer to extra data that received by the event
+//!                     (NULL no data).
+//!                   3) length: data length.
+//!                  -Events with extra data:
+//!                     HCI_EVNT_WLAN_UNSOL_DHCP: 4 bytes IP, 4 bytes Mask, 
+//!                     4 bytes default gateway, 4 bytes DHCP server and 4 bytes
+//!                     for DNS server.
+//!                     HCI_EVNT_WLAN_ASYNC_PING_REPORT: 4 bytes Packets sent, 
+//!                     4 bytes Packets received, 4 bytes Min round time, 
+//!                     4 bytes Max round time and 4 bytes for Avg round time.
+//!
+//!  @param    sFWPatches  0 no patch or pointer to FW patches 
+//!  @param    sDriverPatches  0 no patch or pointer to driver patches
+//!  @param    sBootLoaderPatches  0 no patch or pointer to bootloader patches
+//!  @param    sReadWlanInterruptPin    init callback. the callback read wlan 
+//!            interrupt status.
+//!  @param    sWlanInterruptEnable   init callback. the callback enable wlan 
+//!            interrupt.
+//!  @param    sWlanInterruptDisable   init callback. the callback disable wlan
+//!            interrupt.
+//!  @param    sWriteWlanPin      init callback. the callback write value 
+//!            to device pin.  
+//!
+//!  @return   none
+//!
+//!  @sa       wlan_set_event_mask , wlan_start , wlan_stop 
+//!
+//!  @brief    Initialize wlan driver
+//!
+//!  @warning This function must be called before ANY other wlan driver function
+//
+//*****************************************************************************
+extern void wlan_init(		tWlanCB	 	sWlanCB,
+	   			tFWPatches sFWPatches,
+	   			tDriverPatches sDriverPatches,
+	   			tBootLoaderPatches sBootLoaderPatches,
+                tWlanReadInteruptPin  sReadWlanInterruptPin,
+                tWlanInterruptEnable  sWlanInterruptEnable,
+                tWlanInterruptDisable sWlanInterruptDisable,
+                tWriteWlanPin         sWriteWlanPin);
+
+
+
+//*****************************************************************************
+//
+//!  wlan_start
+//!
+//!  @param   usPatchesAvailableAtHost -  flag to indicate if patches available
+//!                                    from host or from EEPROM. Due to the 
+//!                                    fact the patches are burn to the EEPROM
+//!                                    using the patch programmer utility, the 
+//!                                    patches will be available from the EEPROM
+//!                                    and not from the host.
+//!
+//!  @return        none
+//!
+//!  @brief        Start WLAN device. This function asserts the enable pin of 
+//!                the device (WLAN_EN), starting the HW initialization process.
+//!                The function blocked until device Initialization is completed.
+//!                Function also configure patches (FW, driver or bootloader) 
+//!                and calls appropriate device callbacks.
+//!
+//!  @Note          Prior calling the function wlan_init shall be called.
+//!  @Warning       This function must be called after wlan_init and before any 
+//!                 other wlan API
+//!  @sa            wlan_init , wlan_stop
+//!
+//
+//*****************************************************************************
+extern void wlan_start(unsigned short usPatchesAvailableAtHost);
+
+//*****************************************************************************
+//
+//!  wlan_stop
+//!
+//!  @param         none
+//!
+//!  @return        none
+//!
+//!  @brief         Stop WLAN device by putting it into reset state.
+//!
+//!  @sa            wlan_start
+//
+//*****************************************************************************
+extern void wlan_stop(void);
+
+//*****************************************************************************
+//
+//!  wlan_connect
+//!
+//!  @param    sec_type   security options:
+//!               WLAN_SEC_UNSEC, 
+//!               WLAN_SEC_WEP (ASCII support only),
+//!               WLAN_SEC_WPA or WLAN_SEC_WPA2
+//!  @param    ssid       up to 32 bytes and is ASCII SSID of the AP
+//!  @param    ssid_len   length of the SSID
+//!  @param    bssid      6 bytes specified the AP bssid
+//!  @param    key        up to 16 bytes specified the AP security key
+//!  @param    key_len    key length 
+//!
+//!  @return     On success, zero is returned. On error, negative is returned. 
+//!              Note that even though a zero is returned on success to trigger
+//!              connection operation, it does not mean that CCC3000 is already
+//!              connected. An asynchronous "Connected" event is generated when 
+//!              actual association process finishes and CC3000 is connected to
+//!              the AP. If DHCP is set, An asynchronous "DHCP" event is 
+//!              generated when DHCP process is finish.
+//!              
+//!
+//!  @brief      Connect to AP
+//!  @warning    Please Note that when connection to AP configured with security
+//!              type WEP, please confirm that the key is set as ASCII and not
+//!              as HEX.
+//!  @sa         wlan_disconnect
+//
+//*****************************************************************************
+#ifndef CC3000_TINY_DRIVER
+extern long wlan_connect(unsigned long ulSecType, char *ssid, long ssid_len,
+                        unsigned char *bssid, unsigned char *key, long key_len);
+#else
+extern long wlan_connect(char *ssid, long ssid_len);
+
+#endif
+
+//*****************************************************************************
+//
+//!  wlan_disconnect
+//!
+//!  @return    0 disconnected done, other CC3000 already disconnected            
+//!
+//!  @brief      Disconnect connection from AP. 
+//!
+//!  @sa         wlan_connect
+//
+//*****************************************************************************
+
+extern long wlan_disconnect(void);
+
+//*****************************************************************************
+//
+//!  wlan_add_profile
+//!
+//!  @param    ulSecType  WLAN_SEC_UNSEC,WLAN_SEC_WEP,WLAN_SEC_WPA,WLAN_SEC_WPA2
+//!  @param    ucSsid    ssid  SSID up to 32 bytes
+//!  @param    ulSsidLen ssid length
+//!  @param    ucBssid   bssid  6 bytes
+//!  @param    ulPriority ulPriority profile priority. Lowest priority:0.
+//!  @param    ulPairwiseCipher_Or_TxKeyLen  key length for WEP security
+//!  @param    ulGroupCipher_TxKeyIndex  key index
+//!  @param    ulKeyMgmt        KEY management 
+//!  @param    ucPf_OrKey       security key
+//!  @param    ulPassPhraseLen  security key length for WPA\WPA2
+//!
+//!  @return    On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief     When auto start is enabled, the device connects to
+//!             station from the profiles table. Up to 7 profiles are supported. 
+//!             If several profiles configured the device choose the highest 
+//!             priority profile, within each priority group, device will choose 
+//!             profile based on security policy, signal strength, etc 
+//!             parameters. All the profiles are stored in CC3000 NVMEM.
+//!
+//!  @sa        wlan_ioctl_del_profile 
+//
+//*****************************************************************************
+
+extern long wlan_add_profile(unsigned long ulSecType, unsigned char* ucSsid,
+										 unsigned long ulSsidLen, 
+										 unsigned char *ucBssid,
+                                         unsigned long ulPriority,
+                                         unsigned long ulPairwiseCipher_Or_Key,
+                                         unsigned long ulGroupCipher_TxKeyLen,
+                                         unsigned long ulKeyMgmt,
+                                         unsigned char* ucPf_OrKey,
+                                         unsigned long ulPassPhraseLen);
+
+
+
+//*****************************************************************************
+//
+//!  wlan_ioctl_del_profile
+//!
+//!  @param    index   number of profile to delete
+//!
+//!  @return    On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief     Delete WLAN profile 
+//!
+//!  @Note      In order to delete all stored profile, set index to 255.
+//!
+//!  @sa        wlan_add_profile 
+//
+//*****************************************************************************
+extern long wlan_ioctl_del_profile(unsigned long ulIndex);
+
+//*****************************************************************************
+//
+//!  wlan_set_event_mask
+//!
+//!  @param    mask   mask option:
+//!       HCI_EVNT_WLAN_UNSOL_CONNECT connect event
+//!       HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event
+//!       HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE  smart config done
+//!       HCI_EVNT_WLAN_UNSOL_INIT init done
+//!       HCI_EVNT_WLAN_UNSOL_DHCP dhcp event report
+//!       HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report
+//!       HCI_EVNT_WLAN_KEEPALIVE keepalive
+//!       HCI_EVNT_WLAN_TX_COMPLETE - disable information on end of transmission
+//!   	  Saved: no.
+//!
+//!  @return    On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief    Mask event according to bit mask. In case that event is 
+//!            masked (1), the device will not send the masked event to host. 
+//
+//*****************************************************************************
+extern long wlan_set_event_mask(unsigned long ulMask);
+
+//*****************************************************************************
+//
+//!  wlan_ioctl_statusget
+//!
+//!  @param none 
+//!
+//!  @return    WLAN_STATUS_DISCONNECTED, WLAN_STATUS_SCANING, 
+//!             STATUS_CONNECTING or WLAN_STATUS_CONNECTED      
+//!
+//!  @brief    get wlan status: disconnected, scanning, connecting or connected
+//
+//*****************************************************************************
+extern long wlan_ioctl_statusget(void);
+
+
+//*****************************************************************************
+//
+//!  wlan_ioctl_set_connection_policy
+//!
+//!  @param    should_connect_to_open_ap  enable(1), disable(0) connect to any 
+//!            available AP. This parameter corresponds to the configuration of 
+//!            item # 3 in the brief description.
+//!  @param    should_use_fast_connect enable(1), disable(0). if enabled, tries 
+//!            to connect to the last connected AP. This parameter corresponds 
+//!            to the configuration of item # 1 in the brief description.
+//!  @param    auto_start enable(1), disable(0) auto connect 
+//!            after reset and periodically reconnect if needed. This 
+//!       	   configuration configures option 2 in the above description.
+//!
+//!  @return     On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief      When auto is enabled, the device tries to connect according 
+//!              the following policy:
+//!              1) If fast connect is enabled and last connection is valid, 
+//!                 the device will try to connect to it without the scanning 
+//!                 procedure (fast). The last connection will be marked as
+//!                 invalid, due to adding/removing profile. 
+//!              2) If profile exists, the device will try to connect it 
+//!                 (Up to seven profiles).
+//!              3) If fast and profiles are not found, and open mode is
+//!                 enabled, the device will try to connect to any AP.
+//!              * Note that the policy settings are stored in the CC3000 NVMEM.
+//!
+//!  @sa         wlan_add_profile , wlan_ioctl_del_profile 
+//
+//*****************************************************************************
+extern long wlan_ioctl_set_connection_policy(
+                                        unsigned long should_connect_to_open_ap,
+                                        unsigned long should_use_fast_connect,
+                                        unsigned long ulUseProfiles);
+
+//*****************************************************************************
+//
+//!  wlan_ioctl_get_scan_results
+//!
+//!  @param[in]    scan_timeout   parameter not supported
+//!  @param[out]   ucResults  scan result (_wlan_full_scan_results_args_t)
+//!
+//!  @return    On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief    Gets entry from scan result table.
+//!            The scan results are returned one by one, and each entry 
+//!            represents a single AP found in the area. The following is a 
+//!            format of the scan result: 
+//!        	 - 4 Bytes: number of networks found
+//!          - 4 Bytes: The status of the scan: 0 - aged results,
+//!                     1 - results valid, 2 - no results
+//!          - 42 bytes: Result entry, where the bytes are arranged as  follows:
+//!              
+//!          				- 1 bit isValid - is result valid or not
+//!         				- 7 bits rssi - RSSI value;	 
+//!                 - 2 bits: securityMode - security mode of the AP:
+//!                           0 - Open, 1 - WEP, 2 WPA, 3 WPA2
+//!         				- 6 bits: SSID name length
+//!         				- 2 bytes: the time at which the entry has entered into 
+//!                            scans result table
+//!         				- 32 bytes: SSID name
+//!                 - 6 bytes:	BSSID 
+//!
+//!  @Note      scan_timeout, is not supported on this version.
+//!
+//!  @sa        wlan_ioctl_set_scan_params 
+//
+//*****************************************************************************
+
+
+extern long wlan_ioctl_get_scan_results(unsigned long ulScanTimeout,
+                                       unsigned char *ucResults);
+
+//*****************************************************************************
+//
+//!  wlan_ioctl_set_scan_params
+//!
+//!  @param    uiEnable - start/stop application scan: 
+//!            1 = start scan with default interval value of 10 min. 
+//!            in order to set a different scan interval value apply the value 
+//!            in milliseconds. minimum 1 second. 0=stop). Wlan reset
+//!           (wlan_stop() wlan_start()) is needed when changing scan interval
+//!            value. Saved: No
+//!  @param   uiMinDwellTime   minimum dwell time value to be used for each 
+//!           channel, in milliseconds. Saved: yes
+//!           Recommended Value: 100 (Default: 20)
+//!  @param   uiMaxDwellTime    maximum dwell time value to be used for each
+//!           channel, in milliseconds. Saved: yes
+//!           Recommended Value: 100 (Default: 30)
+//!  @param   uiNumOfProbeRequests  max probe request between dwell time. 
+//!           Saved: yes. Recommended Value: 5 (Default:2)
+//!  @param   uiChannelMask  bitwise, up to 13 channels (0x1fff). 
+//!           Saved: yes. Default: 0x7ff
+//!  @param   uiRSSIThreshold   RSSI threshold. Saved: yes (Default: -80)
+//!  @param   uiSNRThreshold    NSR threshold. Saved: yes (Default: 0)
+//!  @param   uiDefaultTxPower  probe Tx power. Saved: yes (Default: 205)
+//!  @param   aiIntervalList    pointer to array with 16 entries (16 channels) 
+//!           each entry (unsigned long) holds timeout between periodic scan 
+//!           (connection scan) - in milliseconds. Saved: yes. Default 2000ms.
+//!
+//!  @return    On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief    start and stop scan procedure. Set scan parameters. 
+//!
+//!  @Note     uiDefaultTxPower, is not supported on this version.
+//!
+//!  @sa        wlan_ioctl_get_scan_results 
+//
+//*****************************************************************************
+extern long wlan_ioctl_set_scan_params(unsigned long uiEnable, unsigned long 
+											 uiMinDwellTime,unsigned long uiMaxDwellTime,
+										   unsigned long uiNumOfProbeRequests,
+											 unsigned long uiChannelMask,
+										   long iRSSIThreshold,unsigned long uiSNRThreshold,
+										   unsigned long uiDefaultTxPower, 
+											 unsigned long *aiIntervalList);
+
+                                           
+//*****************************************************************************
+//
+//!  wlan_smart_config_start
+//!
+//!  @param    algoEncryptedFlag indicates whether the information is encrypted
+//!
+//!  @return   On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief   Start to acquire device profile. The device acquire its own 
+//!           profile, if profile message is found. The acquired AP information
+//!           is stored in CC3000 EEPROM only in case AES128 encryption is used.
+//!           In case AES128 encryption is not used, a profile is created by 
+//!           CC3000 internally.
+//!
+//!  @Note    An asynchronous event - Smart Config Done will be generated as soon
+//!           as the process finishes successfully.
+//!
+//!  @sa      wlan_smart_config_set_prefix , wlan_smart_config_stop
+//
+//*****************************************************************************                                        
+extern long wlan_smart_config_start(unsigned long algoEncryptedFlag);
+
+
+//*****************************************************************************
+//
+//!  wlan_smart_config_stop
+//!
+//!  @param    algoEncryptedFlag indicates whether the information is encrypted
+//!
+//!  @return   On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief   Stop the acquire profile procedure 
+//!
+//!  @sa      wlan_smart_config_start , wlan_smart_config_set_prefix
+//
+//*****************************************************************************
+extern long wlan_smart_config_stop(void);
+
+//*****************************************************************************
+//
+//!  wlan_smart_config_set_prefix
+//!
+//!  @param   newPrefix  3 bytes identify the SSID prefix for the Smart Config. 
+//!
+//!  @return   On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief   Configure station ssid prefix. The prefix is used internally 
+//!           in CC3000. It should always be TTT.
+//!
+//!  @Note    The prefix is stored in CC3000 NVMEM
+//!
+//!  @sa      wlan_smart_config_start , wlan_smart_config_stop
+//
+//*****************************************************************************
+extern long wlan_smart_config_set_prefix(char* cNewPrefix);
+
+//*****************************************************************************
+//
+//!  wlan_smart_config_process
+//!
+//!  @param   none 
+//!
+//!  @return   On success, zero is returned. On error, -1 is returned        
+//!
+//!  @brief   process the acquired data and store it as a profile. The acquired 
+//!           AP information is stored in CC3000 EEPROM encrypted.
+//!           The encrypted data is decrypted and stored as a profile.
+//!           behavior is as defined by connection policy.
+//
+//*****************************************************************************
+extern long wlan_smart_config_process(void);
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef	__cplusplus
+}
+#endif // __cplusplus
+
+#endif	// __WLAN_H__
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/spi.c b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/spi.c
new file mode 100644
index 0000000000000000000000000000000000000000..26d9de82a4a8a3cf7f842e314dbe0636a16e2bd7
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/spi.c
@@ -0,0 +1,540 @@
+/*****************************************************************************
+*
+*  spi.c - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_CC3000
+
+#include "spi.h"
+#include "hostdriver/hci.h"
+#include "hostdriver/evnt_handler.h"
+#include "core/gpio/gpio.h"
+#include "core/delay/delay.h"
+
+#if CFG_CC3000_SPI_PORT == 1
+  #include "core/ssp1/ssp1.h"
+#else
+  #include "core/ssp0/ssp0.h"
+#endif
+
+#define READ                            (3)
+#define WRITE                           (1)
+#define HI(value)                       (((value) & 0xFF00) >> 8)
+#define LO(value)                       ((value) & 0x00FF)
+#define CC3000_ASSERT_CS                do { LPC_GPIO->CLR[CFG_CC3000_CS_PORT] = (1 << CFG_CC3000_CS_PIN); } while(0)
+#define CC3000_DEASSERT_CS              do { LPC_GPIO->SET[CFG_CC3000_CS_PORT] = (1 << CFG_CC3000_CS_PIN); } while(0)
+#define HEADERS_SIZE_EVNT               (SPI_HEADER_SIZE + 5)
+#define SPI_HEADER_SIZE                 (5)
+
+#define eSPI_STATE_POWERUP              (0)
+#define eSPI_STATE_INITIALIZED          (1)
+#define eSPI_STATE_IDLE                 (2)
+#define eSPI_STATE_WRITE_IRQ            (3)
+#define eSPI_STATE_WRITE_FIRST_PORTION  (4)
+#define eSPI_STATE_WRITE_EOT            (5)
+#define eSPI_STATE_READ_IRQ             (6)
+#define eSPI_STATE_READ_FIRST_PORTION   (7)
+#define eSPI_STATE_READ_EOT             (8)
+
+typedef struct
+{
+  gcSpiHandleRx  SPIRxHandler;
+
+  unsigned short usTxPacketLength;
+  unsigned short usRxPacketLength;
+  unsigned long  ulSpiState;
+  unsigned char *pTxPacket;
+  unsigned char *pRxPacket;
+
+} tSpiInformation;
+
+tSpiInformation sSpiInformation;
+
+/* Static buffer for 5 bytes of SPI HEADER */
+unsigned char tSpiReadHeader[] = {READ, 0, 0, 0, 0};
+
+/* Function prototypes for private functions */
+void SpiWriteDataSynchronous(unsigned char *data, unsigned short size);
+void SpiWriteAsync(const unsigned char *data, unsigned short size);
+void SpiPauseSpi(void);
+void SpiResumeSpi(void);
+void SSIContReadOperation(void);
+
+/* The magic number that resides at the end of the TX/RX buffer (1 byte after
+ * the allocated size) for the purpose of detection of the overrun. The
+ * location of the memory where the magic number resides shall never be
+ * written. In case it is written - an overrun occured and either receive
+ * function or send function will be stuck forever. */
+#define CC3000_BUFFER_MAGIC_NUMBER (0xDE)
+
+char          wlan_rx_buffer[CC3000_RX_BUFFER_SIZE];
+unsigned char wlan_tx_buffer[CC3000_TX_BUFFER_SIZE];
+
+/**************************************************************************/
+/*!
+
+ */
+/**************************************************************************/
+void SpiClose(void)
+{
+  if (sSpiInformation.pRxPacket)
+  {
+    sSpiInformation.pRxPacket = 0;
+  }
+
+  /*  Disable Interrupt in GPIOA module... */
+  tSLInformation.WlanInterruptDisable();
+}
+
+/**************************************************************************/
+/*!
+
+ */
+/**************************************************************************/
+void SpiOpen(gcSpiHandleRx pfRxHandler)
+{
+  sSpiInformation.ulSpiState = eSPI_STATE_POWERUP;
+
+  memset(wlan_rx_buffer, 0, sizeof(wlan_rx_buffer));
+  memset(wlan_tx_buffer, 0, sizeof(wlan_rx_buffer));
+
+  sSpiInformation.SPIRxHandler              = pfRxHandler;
+  sSpiInformation.usTxPacketLength          = 0;
+  sSpiInformation.pTxPacket                 = NULL;
+  sSpiInformation.pRxPacket                 = (unsigned char *)wlan_rx_buffer;
+  sSpiInformation.usRxPacketLength          = 0;
+  wlan_rx_buffer[CC3000_RX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER;
+  wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER;
+
+  /* Enable interrupt on the GPIO pin of WLAN IRQ */
+  tSLInformation.WlanInterruptEnable();
+}
+
+/**************************************************************************/
+/*!
+
+ */
+/**************************************************************************/
+int init_spi(void)
+{
+  #if CFG_CC3000_SPI_PORT == 1
+    ssp1Init();
+  #else
+    ssp0Init();
+  #endif
+
+  /* Set POWER_EN pin to output */
+  LPC_GPIO->DIR[CFG_CC3000_EN_PORT] |= (1 << CFG_CC3000_EN_PIN);
+  LPC_GPIO->CLR[CFG_CC3000_EN_PORT]  = (1 << CFG_CC3000_EN_PIN);
+  delay(100);
+
+  /* Set CS pin to output */
+  LPC_GPIO->DIR[CFG_CC3000_CS_PORT] |= (1 << CFG_CC3000_CS_PIN);
+  CC3000_DEASSERT_CS;
+
+  /* Setup the interrupt pin */
+  LPC_GPIO->DIR[CFG_CC3000_IRQ_PORT] &= ~(1 << CFG_CC3000_IRQ_PIN);
+  /* Channel 2, sense (0=edge, 1=level), polarity (0=low/falling, 1=high/rising) */
+  GPIOSetPinInterrupt( 2, CFG_CC3000_IRQ_PORT, CFG_CC3000_IRQ_PIN, 0, 0 );
+  /* Disable interrupt 2 on falling edge */
+  GPIOPinIntDisable(2, 0);
+
+  return(ESUCCESS);
+}
+
+/**************************************************************************/
+/*!
+
+ */
+/**************************************************************************/
+long SpiFirstWrite(unsigned char *ucBuf, unsigned short usLength)
+{
+  /* Workaround for the first transaction */
+  CC3000_ASSERT_CS;
+
+  /* SPI writes first 4 bytes of data */
+  delay(1);
+  SpiWriteDataSynchronous(ucBuf, 4);
+  delay(1);
+
+  SpiWriteDataSynchronous(ucBuf + 4, usLength - 4);
+
+  /* From this point on - operate in a regular manner */
+  sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
+
+  CC3000_DEASSERT_CS;
+
+  return(0);
+}
+
+/**************************************************************************/
+/*!
+
+ */
+/**************************************************************************/
+long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength)
+{
+  unsigned char ucPad = 0;
+
+  /* Figure out the total length of the packet in order to figure out if
+   * there is padding or not */
+  if(!(usLength & 0x0001))
+  {
+    ucPad++;
+  }
+
+  pUserBuffer[0] = WRITE;
+  pUserBuffer[1] = HI(usLength + ucPad);
+  pUserBuffer[2] = LO(usLength + ucPad);
+  pUserBuffer[3] = 0;
+  pUserBuffer[4] = 0;
+
+  usLength += (SPI_HEADER_SIZE + ucPad);
+
+/* The magic number that resides at the end of the TX/RX buffer (1 byte after
+ * the allocated size) for the purpose of detection of the overrun. The
+ * location of the memory where the magic number resides shall never be
+ * written. In case it is written - an overrun occured and either receive
+ * function or send function will be stuck forever. */
+  if (wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER)
+  {
+    while (1);
+  }
+
+  if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP)
+  {
+    while (sSpiInformation.ulSpiState != eSPI_STATE_INITIALIZED);
+  }
+
+  if (sSpiInformation.ulSpiState == eSPI_STATE_INITIALIZED)
+  {
+    /* This is time for first TX/RX transactions over SPI: the IRQ is down
+     * - so we need to send read buffer size command */
+    SpiFirstWrite(pUserBuffer, usLength);
+  }
+  else
+  {
+    /* We need to prevent a race condition here that can occur in case two
+     * back to back packets are senr to the device, so the state will move
+     * to IDLE and once again to not IDLE due to IRQ */
+    tSLInformation.WlanInterruptDisable();
+
+    while (sSpiInformation.ulSpiState != eSPI_STATE_IDLE);
+
+    sSpiInformation.ulSpiState = eSPI_STATE_WRITE_IRQ;
+    sSpiInformation.pTxPacket = pUserBuffer;
+    sSpiInformation.usTxPacketLength = usLength;
+
+    /* Assert the CS line and wait till SSI IRQ line is active and then
+     * initialize write operation */
+    CC3000_ASSERT_CS;
+
+    /* Re-enable IRQ - if it was not disabled - this is not a problem... */
+    tSLInformation.WlanInterruptEnable();
+
+    /* Check for a missing interrupt between the CS assertion and re-enabling
+     * the interrupts */
+    if (tSLInformation.ReadWlanInterruptPin() == 0)
+    {
+      SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength);
+
+      sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
+
+      CC3000_DEASSERT_CS;
+    }
+  }
+
+  /* Due to the fact that we are currently implementing a blocking situation
+   * here we will wait till end of transaction */
+  while (eSPI_STATE_IDLE != sSpiInformation.ulSpiState);
+
+  return(0);
+}
+
+/**************************************************************************/
+/*!
+
+ */
+/**************************************************************************/
+void SpiWriteDataSynchronous(unsigned char *data, unsigned short size)
+{
+  unsigned char dummy = dummy;
+  while (size)
+  {
+    /* TX */
+    #if CFG_CC3000_SPI_PORT == 1
+      while ((LPC_SSP1->SR & (SSP1_SR_TNF_NOTFULL | SSP1_SR_BSY_BUSY)) != SSP1_SR_TNF_NOTFULL);
+      LPC_SSP1->DR = *data;
+    #else
+      while ((LPC_SSP0->SR & (SSP0_SR_TNF_NOTFULL | SSP0_SR_BSY_BUSY)) != SSP0_SR_TNF_NOTFULL);
+      LPC_SSP0->DR = *data;
+    #endif
+
+    /* RX */
+    #if CFG_CC3000_SPI_PORT == 1
+      while ((LPC_SSP1->SR & (SSP1_SR_BSY_BUSY|SSP1_SR_RNE_NOTEMPTY)) != SSP1_SR_RNE_NOTEMPTY);
+      dummy = LPC_SSP1->DR;
+    #else
+      while ((LPC_SSP0->SR & (SSP0_SR_BSY_BUSY|SSP0_SR_RNE_NOTEMPTY)) != SSP0_SR_RNE_NOTEMPTY);
+      dummy = LPC_SSP0->DR;
+    #endif
+
+    size--;
+    data++;
+  }
+}
+
+/**************************************************************************/
+/*!
+
+ */
+/**************************************************************************/
+void SpiReadDataSynchronous(unsigned char *data, unsigned short size)
+{
+  long i = 0;
+  unsigned char *data_to_send = tSpiReadHeader;
+
+  for (i = 0; i < size; i ++)
+  {
+    /* Dummy write */
+    #if CFG_CC3000_SPI_PORT == 1
+      while ((LPC_SSP1->SR & (SSP1_SR_TNF_NOTFULL | SSP1_SR_BSY_BUSY)) != SSP1_SR_TNF_NOTFULL);
+      LPC_SSP1->DR = data_to_send[0];
+    #else
+      while ((LPC_SSP0->SR & (SSP0_SR_TNF_NOTFULL | SSP0_SR_BSY_BUSY)) != SSP0_SR_TNF_NOTFULL);
+      LPC_SSP0->DR = data_to_send[0];
+    #endif
+
+    /* RX */
+    #if CFG_CC3000_SPI_PORT == 1
+      while ( (LPC_SSP1->SR & (SSP1_SR_BSY_BUSY|SSP1_SR_RNE_NOTEMPTY)) != SSP1_SR_RNE_NOTEMPTY );
+      data[i] = LPC_SSP1->DR;
+    #else
+      while ( (LPC_SSP0->SR & (SSP0_SR_BSY_BUSY|SSP0_SR_RNE_NOTEMPTY)) != SSP0_SR_RNE_NOTEMPTY );
+      data[i] = LPC_SSP0->DR;
+    #endif
+  }
+}
+
+/**************************************************************************/
+/*!
+
+ */
+/**************************************************************************/
+void SpiReadHeader(void)
+{
+  SpiReadDataSynchronous(sSpiInformation.pRxPacket, 10);
+}
+
+/**************************************************************************/
+/*!
+
+ */
+/**************************************************************************/
+long SpiReadDataCont(void)
+{
+  long data_to_recv;
+  unsigned char *evnt_buff, type;
+
+  /* Determine what type of packet we have */
+  evnt_buff =  sSpiInformation.pRxPacket;
+  data_to_recv = 0;
+  STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE), HCI_PACKET_TYPE_OFFSET, type);
+
+  switch(type)
+  {
+    case HCI_TYPE_DATA:
+      {
+        /* We need to read the rest of the data.. */
+        STREAM_TO_UINT16((char *)(evnt_buff + SPI_HEADER_SIZE), HCI_DATA_LENGTH_OFFSET, data_to_recv);
+        if (!((HEADERS_SIZE_EVNT + data_to_recv) & 1))
+        {
+          data_to_recv++;
+        }
+
+        if (data_to_recv)
+        {
+          SpiReadDataSynchronous(evnt_buff + 10, data_to_recv);
+        }
+        break;
+      }
+    case HCI_TYPE_EVNT:
+      {
+        /* Calculate the length of the data */
+        STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE), HCI_EVENT_LENGTH_OFFSET, data_to_recv);
+        data_to_recv -= 1;
+
+        /* Add padding byte if needed */
+        if ((HEADERS_SIZE_EVNT + data_to_recv) & 1)
+        {
+          data_to_recv++;
+        }
+
+        if (data_to_recv)
+        {
+          SpiReadDataSynchronous(evnt_buff + 10, data_to_recv);
+        }
+
+        sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT;
+        break;
+      }
+  }
+
+  return (0);
+}
+
+/**************************************************************************/
+/*!
+
+ */
+/**************************************************************************/
+void SpiPauseSpi(void)
+{
+  GPIOPinIntDisable( 2, 0 );
+}
+
+/**************************************************************************/
+/*!
+
+ */
+/**************************************************************************/
+void SpiResumeSpi(void)
+{
+  GPIOPinIntEnable( 2, 0 );
+}
+
+/**************************************************************************/
+/*!
+
+ */
+/**************************************************************************/
+void SpiTriggerRxProcessing(void)
+{
+  /* Trigger Rx processing */
+  SpiPauseSpi();
+  CC3000_DEASSERT_CS;
+
+  /* The magic number that resides at the end of the TX/RX buffer (1 byte after
+   * the allocated size) for the purpose of detection of the overrun. The
+   * location of the memory where the magic number resides shall never be
+   * written. In case it is written - an overrun occured and either receive
+   * function or send function will be stuck forever. */
+  if (sSpiInformation.pRxPacket[CC3000_RX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER)
+  {
+    /* You've got problems if you're here! */
+    while (1);
+  }
+
+  sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
+  sSpiInformation.SPIRxHandler(sSpiInformation.pRxPacket + SPI_HEADER_SIZE);
+}
+
+/**************************************************************************/
+/*!
+
+ */
+/**************************************************************************/
+void SSIContReadOperation(void)
+{
+  /* The header was read - continue with the payload read */
+  if (!SpiReadDataCont())
+  {
+    /* All the data was read - finalize handling by switching to the task
+     *  and calling from task event handler */
+    SpiTriggerRxProcessing();
+  }
+}
+
+/**************************************************************************/
+/*!
+    IRQ Handler (triggers on CC3000MOD IRQ line)
+
+    \brief  GPIO interrupt handler. When the external SPI WLAN device is
+            ready to interact with Host CPU it generates an interrupt signal.
+            After that Host CPU has registrated this interrupt request
+            it sets the corresponding /CS pin in active state.
+*/
+/**************************************************************************/
+#if defined CFG_MCU_FAMILY_LPC11UXX
+void FLEX_INT2_IRQHandler(void)
+#elif defined CFG_MCU_FAMILY_LPC13UXX
+void PIN_INT2_IRQHandler(void)
+#else
+  #error "CC3000 spi.c: No MCU defined"
+#endif
+{
+  /* Make sure the right flag is set in the int status register */
+  if ( LPC_GPIO_PIN_INT->IST & (0x1 << 2) )
+  {
+    /* Falling Edge */
+    if ( ( LPC_GPIO_PIN_INT->FALL & (0x1 << 2) ) && ( LPC_GPIO_PIN_INT->IENF & (0x1 << 2) ) )
+    {
+      if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP)
+      {
+        /* This means IRQ line was low call a callback of HCI Layer to inform on event */
+         sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED;
+      }
+      else if (sSpiInformation.ulSpiState == eSPI_STATE_IDLE)
+      {
+        sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ;
+
+        /* IRQ line goes down - start reception */
+        CC3000_ASSERT_CS;
+
+        /* Wait for TX/RX Compete which will come as DMA interrupt */
+        SpiReadHeader();
+
+        sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT;
+
+        SSIContReadOperation();
+      }
+      else if (sSpiInformation.ulSpiState == eSPI_STATE_WRITE_IRQ)
+      {
+        SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength);
+
+        sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
+
+        CC3000_DEASSERT_CS;
+      }
+      LPC_GPIO_PIN_INT->FALL = 0x1 << 2;
+    }
+    /* Clear the FLEX/PIN interrupt */
+    LPC_GPIO_PIN_INT->IST = 0x1 << 2;
+  }
+  return;
+}
+
+
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/spi.h b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/spi.h
new file mode 100644
index 0000000000000000000000000000000000000000..61ec379079b4b927f4a3116632fcbe65d1c4fada
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/spi.h
@@ -0,0 +1,65 @@
+/*****************************************************************************
+*
+*  spi.h  - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#ifndef __SPI_H__
+#define __SPI_H__
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef void (*gcSpiHandleRx)(void *p);
+typedef void (*gcSpiHandleTx)(void);
+
+extern unsigned char wlan_tx_buffer[];
+
+extern void SpiOpen(gcSpiHandleRx pfRxHandler);
+extern void SpiClose(void);
+extern long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength);
+extern void SpiResumeSpi(void);
+extern void SpiCleanGPIOISR(void);
+extern int  init_spi(void);
+extern long TXBufferIsEmpty(void);
+extern long RXBufferIsEmpty(void);
+
+#ifdef  __cplusplus
+}
+#endif // __cplusplus
+
+#endif
+
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/spi_version.h b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/spi_version.h
new file mode 100644
index 0000000000000000000000000000000000000000..a9154b07698facc2dc6665de6a355ea678b1cc48
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/spi_version.h
@@ -0,0 +1,63 @@
+/*****************************************************************************
+*
+*  spi_version.h  - CC3000 Host Driver Implementation.
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the   
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#ifndef __SPI_VERSION_H__
+#define __SPI_VERSION_H__
+
+#define SPI_VERSION_NUMBER   6
+
+
+//*****************************************************************************
+//
+// If building with a C++ compiler, make all of the definitions in this header
+// have a C binding.
+//
+//*****************************************************************************
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+
+//*****************************************************************************
+//
+// Mark the end of the C bindings section for C++ compilers.
+//
+//*****************************************************************************
+#ifdef  __cplusplus
+}
+#endif // __cplusplus
+
+#endif
+
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/wifi.c b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/wifi.c
new file mode 100644
index 0000000000000000000000000000000000000000..b1d1382684bc163b1d2c51f3de4a2a9cbd6173e3
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/wifi.c
@@ -0,0 +1,1054 @@
+/**************************************************************************/
+/*!
+    @file     wifi.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_CC3000
+
+#include "wifi.h"
+#include "spi.h"
+#include "hostdriver/wlan.h"
+#include "hostdriver/socket.h"
+#include "hostdriver/hci.h"
+#include "hostdriver/nvmem.h"
+#include "hostdriver/security.h"
+#include "hostdriver/netapp.h"
+#include "hostdriver/evnt_handler.h"
+#include "core/delay/delay.h"
+#include "core/gpio/gpio.h"
+
+/*=========================================================================
+    CC3000 API PARAM VALUES
+
+    Simple wrapper defines to abstract away CC3000 API param values
+    -----------------------------------------------------------------------*/
+    #define WIFI_DISABLE              (0)
+    #define WIFI_ENABLE               (1)
+    #define WIFI_TIMEOUT_CONNECT      (45000) /* ~45s */
+/*=========================================================================*/
+
+
+/*=========================================================================
+    CC3000 STATUS FLAGS
+    -----------------------------------------------------------------------*/
+    #define WIFI_STATUS_DISCONNECTED  (0)
+    #define WIFI_STATUS_SCANING       (1)
+    #define WIFI_STATUS_CONNECTING    (2)
+    #define WIFI_STATUS_CONNECTED     (3)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PRINTF RETARGET
+
+    Some wifi commands generate printf output (SSID scan, etc.), so this
+    simple macro can be reused to redirect the output to the correct
+    peripheral or output device
+    -----------------------------------------------------------------------*/
+    #define WIFI_PRINTF(...)          printf(__VA_ARGS__)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    WIFI ASSERT/DEBUG OUTPUT
+
+    Macro to check the return value of CC3000 API functions, and report an
+    error if we get an unexpected return value
+    -----------------------------------------------------------------------*/
+    #define CC3000_SUCCESS            (0)
+    #define WIFI_PRINTF_DBG(...)      printf(__VA_ARGS__)
+    #define WIFI_CHECK_SUCCESS(func, msg, error) \
+      do \
+      {  \
+        if ( (func) != CC3000_SUCCESS ) \
+        { \
+          WIFI_PRINTF_DBG(msg); \
+          return (error); \
+        } \
+      } while(0)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    SMARTCONFIG VALUES
+    -----------------------------------------------------------------------*/
+    /* AES Key for secure connections w/SmartConfig = 0123456789012345 */
+    char _wifi_ASEsecurity_key[] = { 0x30, 0x31, 0x32, 0x33,
+                                     0x34, 0x35, 0x36, 0x37,
+                                     0x38, 0x39, 0x30, 0x31,
+                                     0x32, 0x33, 0x34, 0x35 };
+    char _wifi_sc_deviceName[] = "CC3000";
+    char _wifi_sc_prefix[]     = { 'T', 'T', 'T' };
+    volatile unsigned char _wifi_stopSmartConfig;
+    static int _wifi_smartConfigFailure = 0;
+/*=========================================================================*/
+
+
+/*=========================================================================
+    PING VALUES
+    -----------------------------------------------------------------------*/
+    uint8_t _wifi_pingReportsReceived;
+    netapp_pingreport_args_t _wifi_pingReport;
+/*=========================================================================*/
+
+
+/*=========================================================================
+    ASYNC FLAGS (CONNECTED/DHCP/etc.)
+    -----------------------------------------------------------------------*/
+    volatile unsigned long _wifi_smartConfigFinished,
+                           _wifi_connected,
+                           _wifi_dhcp,
+                           _wifi_okToShutdown,
+                           _wifi_dhcpConfigured,
+                           _wifi_socketCheck;
+/*=========================================================================*/
+
+
+/*=========================================================================
+    MISC GUARD FLAGS
+    -----------------------------------------------------------------------*/
+    static int _wifi_initialised = 0;
+
+    #define WIFI_CHECK_INIT() \
+      do \
+      { \
+        err_t _err; \
+        if (!_wifi_initialised) \
+        { \
+          _err = wifi_init(0); \
+          if (_err) return _err; \
+        } \
+      } while (0)
+/*=========================================================================*/
+
+/* Callback functions for the CC3000 HAL (set in UsynchCallback) */
+void  wifi_UsynchCallback       (long lEventType, char * data, unsigned char length);
+char *wifi_sendDriverPatch      (unsigned long *length);
+char *wifi_sendBootLoaderPatch  (unsigned long *length);
+char *wifi_sendWLFWPatch        (unsigned long *length);
+long  wifi_readWlanInterruptPin (void);
+void  wifi_wlanInterruptEnable  (void);
+void  wifi_wlanInterruptDisable (void);
+void  wifi_writeWlanPin         (unsigned char val);
+
+/**************************************************************************/
+/*!
+    @brief  Helper function to reverse the byte order in a 4 byte array
+*/
+/**************************************************************************/
+void wifi_reverseByteOrder(uint8_t bytes[4])
+{
+  uint8_t rev[4];
+
+  rev[0] = bytes[3];
+  rev[1] = bytes[2];
+  rev[2] = bytes[1];
+  rev[3] = bytes[0];
+
+  memcpy(bytes, rev, 4);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Helper function to convert four bytes to a U32 IP value
+*/
+/**************************************************************************/
+uint32_t wifi_ip2u32(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
+{
+  uint32_t ip = d;
+
+  ip <<= 8;
+  ip |= c;
+  ip <<= 8;
+  ip |= b;
+  ip <<= 8;
+  ip |= a;
+
+  return ip;
+}
+
+/**************************************************************************/
+/*!
+    @brief  The function returns a pointer to the driver patch:
+            since there is no patch in the host - it returns 0
+
+    @param  Length    pointer to the length
+*/
+/**************************************************************************/
+char *wifi_sendDriverPatch(unsigned long *length)
+{
+  *length = 0;
+  return NULL ;
+}
+
+/**************************************************************************/
+/*!
+    @brief  The function returns a pointer to the boot loader patch:
+            since there is no patch in the host - it returns 0
+
+    @param  Length     pointer to the length
+*/
+/**************************************************************************/
+char *wifi_sendBootLoaderPatch(unsigned long *length)
+{
+  *length = 0;
+  return NULL ;
+}
+
+/**************************************************************************/
+/*!
+    @brief  The function returns a pointer to the FW patch:
+            since there is no patch in the host - it returns 0
+
+    @param  Length     pointer to the length
+*/
+/**************************************************************************/
+char *wifi_sendWLFWPatch(unsigned long *length)
+{
+  *length = 0;
+  return NULL ;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Callback function to read the status of interrupt pin
+
+    @return Returns the pin state (1 = high, 0 = low)
+*/
+/**************************************************************************/
+long wifi_readWlanInterruptPin(void)
+{
+  return (long) GPIOGetPinValue(CFG_CC3000_IRQ_PORT, CFG_CC3000_IRQ_PIN);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Callback function to enable the interrupt line on the CC3000
+*/
+/**************************************************************************/
+void wifi_wlanInterruptEnable()
+{
+  GPIOPinIntEnable(2, 0);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Callback function to disable the interrupt line on the CC3000
+*/
+/**************************************************************************/
+void wifi_wlanInterruptDisable()
+{
+  GPIOPinIntDisable(2, 0);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Callback function to set the CC3000_EN pin (enable the CC3000)
+
+    @param  val    Enable or disable CC3000 pin
+*/
+/**************************************************************************/
+void wifi_writeWlanPin(unsigned char val)
+{
+  GPIOSetBitValue(CFG_CC3000_EN_PORT, CFG_CC3000_EN_PIN, val);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Handles asynchronous events from the CC3000 module
+
+    @param  lEventType  Event type
+    @param  data        data of event
+    @param  length      data length
+*/
+/**************************************************************************/
+void wifi_UsynchCallback(long lEventType, char * data, unsigned char length)
+{
+  /* SmartConfig configuration process finished */
+  if (lEventType == HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE)
+  {
+    _wifi_smartConfigFinished = 1;
+    _wifi_stopSmartConfig = 1;
+  }
+
+  /* AP connection established */
+  if (lEventType == HCI_EVNT_WLAN_UNSOL_CONNECT)
+  {
+    _wifi_connected = 1;
+  }
+
+  /* AP disconnected */
+  if (lEventType == HCI_EVNT_WLAN_UNSOL_DISCONNECT)
+  {
+    _wifi_connected = 0;
+    _wifi_dhcp = 0;
+    _wifi_dhcpConfigured = 0;
+  }
+
+  /* DHCP complete (we have an IP address!) */
+  if (lEventType == HCI_EVNT_WLAN_UNSOL_DHCP)
+  {
+    _wifi_dhcp = 1;
+  }
+
+  /* Safe to shut down now */
+  if (lEventType == HCI_EVENT_CC3000_CAN_SHUT_DOWN)
+  {
+    _wifi_okToShutdown = 1;
+  }
+
+  if (lEventType == HCI_EVNT_BSD_TCP_CLOSE_WAIT)
+  {
+    _wifi_socketCheck = 1;
+  }
+
+  /* Ping report results */
+  if (lEventType == HCI_EVNT_WLAN_ASYNC_PING_REPORT)
+  {
+    _wifi_pingReportsReceived++;
+    memcpy(&_wifi_pingReport, data, length);
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Initialises the CC3000
+
+    @note   Possible error message are:
+
+            - ERROR_CC3000_WLAN_EVENT_MASK
+            - ERROR_NONE
+*/
+/**************************************************************************/
+err_t wifi_init(unsigned short cRequestPatch)
+{
+  /* Make sure the CC3000 SPI block is initialised (see spi.c) */
+  init_spi();
+
+  /* Pass in the callback functions for the CC3000 HAL */
+  wlan_init(wifi_UsynchCallback,
+            wifi_sendWLFWPatch,
+            wifi_sendDriverPatch,
+            wifi_sendBootLoaderPatch,
+            wifi_readWlanInterruptPin,
+            wifi_wlanInterruptEnable,
+            wifi_wlanInterruptDisable,
+            wifi_writeWlanPin);
+
+  /* Start the module */
+  wlan_start(cRequestPatch);
+
+  /* Set this up here for convenience sake w/SmartConfig */
+  wlan_smart_config_set_prefix((char*) _wifi_sc_prefix);
+
+  /* Don't store the connection details */
+  wlan_ioctl_set_connection_policy(WIFI_DISABLE, WIFI_DISABLE, WIFI_DISABLE);
+
+  /* Delete any previous profiles that are stored in NVMEM */
+  wlan_ioctl_del_profile(255);
+
+  /* Setup the event masks (async events we don't want, see hci.h) */
+  WIFI_CHECK_SUCCESS(wlan_set_event_mask(
+                     HCI_EVNT_WLAN_KEEPALIVE         |
+                     HCI_EVNT_WLAN_UNSOL_INIT        |
+                     // HCI_EVNT_WLAN_ASYNC_PING_REPORT |
+                     // HCI_EVNT_WLAN_TX_COMPLETE,
+                     HCI_EVNT_BSD_TCP_CLOSE_WAIT),
+                     "WLAN Set Event Mask FAIL",
+                     ERROR_CC3000_WLAN_EVENT_MASK);
+
+  /* Initialised! */
+  _wifi_initialised = 1;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the two byte firmware version number
+
+    @note   Possible error message are:
+
+            - ERROR_CC3000_WLAN_EVENT_MASK (wifi_init)
+            - ERROR_CC3000_NVMEM_READ
+            - ERROR_NONE
+
+    @code
+
+    uint8_t major, minor;
+    if (!wifi_getFirmwareVersion(&major, &minor))
+    {
+      printf("Firmware : v%d.%d%s", major, minor, CFG_PRINTF_NEWLINE);
+    }
+
+    @endcode
+*/
+/**************************************************************************/
+err_t wifi_getFirmwareVersion(uint8_t *major, uint8_t *minor)
+{
+  uint8_t version[2];
+
+  WIFI_CHECK_INIT();
+  WIFI_CHECK_SUCCESS(nvmem_read_sp_version(version),
+                     "Failed reading firmware version",
+                     ERROR_CC3000_NVMEM_READ);
+
+  *major = version[0];
+  *minor = version[1];
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the MAC address for the CC3000 module
+
+    @note   Possible error message are:
+
+            - ERROR_CC3000_WLAN_EVENT_MASK (wifi_init)
+            - ERROR_CC3000_NVMEM_READ
+            - ERROR_NONE
+
+    @code
+
+    uint8_t macAddress[6] = { 0, 0, 0, 0, 0, 0 };
+
+    if (!wifi_getMacAddress(macAddress))
+    {
+      printf("MAC Address : %02X:%02X:%02X:%02X:%02X:%02X%s",
+        macAddress[0], macAddress[1], macAddress[2],
+        macAddress[3], macAddress[4], macAddress[5],
+        CFG_PRINTF_NEWLINE);
+    }
+
+    @endcode
+*/
+/**************************************************************************/
+err_t wifi_getMacAddress(uint8_t macAddress[6])
+{
+  WIFI_CHECK_INIT();
+  WIFI_CHECK_SUCCESS(nvmem_read(NVMEM_MAC_FILEID, 6, 0, macAddress),
+      "Read MAC address failed", ERROR_CC3000_NVMEM_READ);
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the MAC address for the CC3000 module
+
+    @note   Possible error message are:
+
+            - ERROR_CC3000_WLAN_EVENT_MASK (wifi_init)
+            - ERROR_CC3000_NVMEM_SET_MAC_ADDRESS
+            - ERROR_NONE
+*/
+/**************************************************************************/
+err_t wifi_setMacAddress(uint8_t macAddress[6])
+{
+  WIFI_CHECK_INIT();
+
+  WIFI_CHECK_SUCCESS(netapp_config_mac_adrress(macAddress),
+                     "Failed updating MAC address",
+                     ERROR_CC3000_NVMEM_SET_MAC_ADDRESS);
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief   Enables or disables an SSID scan
+
+    @param   time  Stops scanning if equal to 0, otherwise scans for the
+                   specified number of milliseconds
+
+    @note    Possible error message are
+
+             - ERROR_CC3000_WLAN_EVENT_MASK (wifi_init)
+             - ERROR_CC3000_WLAN_SET_SCAN_PARAM
+             - ERROR_NONE
+*/
+/**************************************************************************/
+err_t wifi_ssidScan(uint32_t time)
+{
+  const unsigned long intervalTime[16] = { 2000, 2000, 2000, 2000,
+                                           2000, 2000, 2000, 2000,
+                                           2000, 2000, 2000, 2000,
+                                           2000, 2000, 2000, 2000  };
+
+  WIFI_CHECK_INIT();
+  WIFI_CHECK_SUCCESS(wlan_ioctl_set_scan_params(time, 20, 100, 5, 0x7FF,
+                -120, 0, 300, (unsigned long *)&intervalTime),
+                "Failed setting SSID scan params",
+                ERROR_CC3000_WLAN_SET_SCAN_PARAM);
+
+  delay(time + 500);
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief   Performs and SSID scan and display the results using printf
+
+    @note    Possible error message are
+
+             - ERROR_CC3000_WLAN_EVENT_MASK (wifi_init)
+             - ERROR_CC3000_WLAN_SET_SCAN_PARAM (wifi_ssidScan)
+             - ERROR_CC3000_WLAN_GET_SCAN_RESULT
+             - ERROR_NONE
+
+    @code
+
+    printf("Performing an SSID scan (~4s)%s", CFG_PRINTF_NEWLINE);
+    wifi_displaySSIDResults();
+
+    @endcode
+*/
+/**************************************************************************/
+err_t wifi_displaySSIDResults(void)
+{
+  uint16_t i, x;
+  ResultStruct_t resultBuff;
+  uint8_t valid, rssiValue, securityMode, ssidLen;
+
+  WIFI_CHECK_INIT();
+
+  /* Reboot first if there was a failed SmartConfig attempt */
+  if (_wifi_smartConfigFailure)
+  {
+    wlan_stop();
+    delay(1000);
+    wlan_start(0);
+    _wifi_smartConfigFailure = 0;
+  }
+
+  /* Scan for 4 seconds then stop */
+  ASSERT_STATUS_MESSAGE(wifi_ssidScan(4000), "SSID scan init failed");
+
+  /* Get the scan results */
+  WIFI_CHECK_SUCCESS(wlan_ioctl_get_scan_results(0, (uint8_t*)&resultBuff),
+                    "Failed reading SSID scan results",
+                    ERROR_CC3000_WLAN_GET_SCAN_RESULT);
+
+  /* Iterate over the scan results */
+  i = resultBuff.num_networks;
+  while (i)
+  {
+    i--;
+
+    /* Pull out the individual records from the result buffer */
+    valid        = (resultBuff.rssiByte & (~0xFE));
+    rssiValue    = (resultBuff.rssiByte >> 1);
+    securityMode = (resultBuff.Sec_ssidLen & (~0xFC));
+    ssidLen      = (resultBuff.Sec_ssidLen >> 2);
+
+    /* Display details of valid access points */
+    if (valid)
+    {
+      WIFI_PRINTF("%-20s", "SSID Name:");
+      for (x = 0; x < ssidLen; x++)
+      {
+        WIFI_PRINTF("%c", resultBuff.ssid_name[x]);
+      }
+      WIFI_PRINTF(CFG_PRINTF_NEWLINE);
+      WIFI_PRINTF("%-20s%d%s", "Security Mode:", securityMode, CFG_PRINTF_NEWLINE);
+      WIFI_PRINTF("%-20s%d%s", "RSSI Value:", rssiValue, CFG_PRINTF_NEWLINE);
+      WIFI_PRINTF(CFG_PRINTF_NEWLINE);
+    }
+
+    /* Read the next entry */
+    WIFI_CHECK_SUCCESS(wlan_ioctl_get_scan_results(0, (uint8_t*)&resultBuff),
+                "Failed reading SSID scan results",
+                ERROR_CC3000_WLAN_GET_SCAN_RESULT);
+  };
+
+  /* Stop the SSID scan (time = 0) */
+  ASSERT_STATUS_MESSAGE(wifi_ssidScan(0), "SSID scan stop failed");
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief   Connect to a secure AP
+
+    @param   sec     Security mode (0 = open, 1 = WEP, 2 = WPA, 3 = WPA2)
+    @param   ssid    Buffer to store the SSID name
+    @param   ssidlen SSID length
+    @param   key     Buffer to store the AP authentication key
+    @param   keylen  Key length (max 16 bytes)
+
+    @note    The CC3000 is limited to 16 bytes for key length!
+
+    @note    Possible error message are
+
+             - ERROR_CC3000_WLAN_EVENT_MASK (wifi_init)
+             - ERROR_INVALIDPARAMETER
+             - ERROR_CC3000_WLAN_SET_CONNECT_POLICY
+             - ERROR_CC3000_WLAN_CONNECT
+             - ERROR_CC3000_CONNECT_TIMEOUT
+             - ERROR_NONE
+
+    @code
+
+    uint8_t *ssid = "TESTNETWORK";
+    uint8_t *key  = "abcdefghijklmnop";
+    uint8_t sec   = 3;
+
+    printf("Connecting to %s (30s timeout) ...%s", ssid, CFG_PRINTF_NEWLINE);
+
+    error = wifi_connectSecure(3, ssid, strlen(ssid), key, strlen(key));
+
+    if (!error)
+    {
+      printf("Connected!%s", CFG_PRINTF_NEWLINE);
+      // ...
+    }
+
+    @endcode
+*/
+/**************************************************************************/
+err_t wifi_connectSecure(int32_t sec, int8_t *ssid, int32_t ssidlen,
+                           int8_t *key, int32_t keylen)
+{
+  WIFI_CHECK_INIT();
+
+  /* Check parameter lengths to make sure they're safe for the API */
+  ASSERT(sec     > -1,  ERROR_INVALIDPARAMETER);
+  ASSERT(sec     <= 3,  ERROR_INVALIDPARAMETER);
+  ASSERT(ssidlen <= 32, ERROR_INVALIDPARAMETER);
+  ASSERT(keylen  <= 16, ERROR_INVALIDPARAMETER);
+
+  /* Don't automatically reconnect to this AP */
+  WIFI_CHECK_SUCCESS(wlan_ioctl_set_connection_policy(WIFI_DISABLE, WIFI_DISABLE, WIFI_DISABLE),
+                    "Set connection policy failed", ERROR_CC3000_WLAN_SET_CONNECT_POLICY);
+
+  /* Wait a bit for the previous call to complete */
+  delay(500);
+
+  /* Try to establish a connection */
+  WIFI_CHECK_SUCCESS(wlan_connect(sec, (char *)ssid, ssidlen, NULL, (unsigned char *)key, keylen),
+                    "Connection failed", ERROR_CC3000_WLAN_CONNECT);
+
+  /* Wait for a connection and an IP address from DHCP */
+  uint32_t timeout = 0;
+  while ((!_wifi_connected) || (!_wifi_dhcp))
+  {
+    timeout++;
+    if(timeout > WIFI_TIMEOUT_CONNECT / 10)
+    {
+      return ERROR_CC3000_CONNECT_TIMEOUT;
+    }
+    delay(10);
+  }
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief   Starts the SmartConfig process and waits for a connection
+
+    @param   enableAES  True is AES is used for SmartConfig
+
+    @note    Possible error message are:
+
+             - ERROR_CC3000_WLAN_EVENT_MASK (wifi_init)
+             - ERROR_CC3000_WLAN_SET_CONNECT_POLICY
+             - ERROR_CC3000_WLAN_DEL_CONNECT_PROFILE
+             - ERROR_CC3000_WLAN_DISCONNECT
+             - ERROR_CC3000_NVMEM_CREATE_ENTRY
+             - ERROR_CC3000_NVMEM_WRITE
+             - ERROR_CC3000_SMARTCONFIG_SET_PREFIX
+             - ERROR_CC3000_SMARTCONFIG_START
+             - ERROR_CC3000_CONNECT_TIMEOUT
+             - ERROR_CC3000_SMARTCONFIG_PROCESS
+             - ERROR_NONE
+*/
+/**************************************************************************/
+err_t wifi_startSmartConfig(bool enableAES)
+{
+  uint8_t  loop    = 0;
+  uint32_t timeout = 0;
+
+  _wifi_smartConfigFinished = 0;
+  _wifi_connected = 0;
+  _wifi_dhcp = 0;
+  _wifi_okToShutdown = 0;
+
+  WIFI_CHECK_INIT();
+
+  /* Reset the connection policy */
+  WIFI_CHECK_SUCCESS(wlan_ioctl_set_connection_policy(WIFI_DISABLE, WIFI_DISABLE, WIFI_DISABLE),
+                     "Set Connection policy FAIL",
+                     ERROR_CC3000_WLAN_SET_CONNECT_POLICY);
+
+  /* Erase all previous connections stored in NVMEM */
+  WIFI_CHECK_SUCCESS(wlan_ioctl_del_profile(255),
+                     "Delete Profile FAIL",
+                     ERROR_CC3000_WLAN_DEL_CONNECT_PROFILE);
+
+  /* Disconnect from the current AP if we're connected to something */
+  while (wlan_ioctl_statusget() == WIFI_STATUS_CONNECTED)
+  {
+    WIFI_CHECK_SUCCESS(wlan_disconnect(),
+                       "Unable to disconnect from the AP",
+                       ERROR_CC3000_WLAN_DISCONNECT);
+    hci_unsolicited_event_handler();
+  }
+
+  /* Reboot the CC3000 */
+  wlan_stop();
+  delay(1000);
+  wlan_start(0);
+
+  /* Create a new entry for the AES encryption key */
+  WIFI_CHECK_SUCCESS(nvmem_create_entry(NVMEM_AES128_KEY_FILEID, 16),
+                    "Unable to create the AES key entry",
+                    ERROR_CC3000_NVMEM_CREATE_ENTRY);
+
+  /* Write the AES key to NVMEM */
+  WIFI_CHECK_SUCCESS(aes_write_key((uint8_t * )(&_wifi_ASEsecurity_key[0])),
+                     "Unable to commit the AES key",
+                     ERROR_CC3000_NVMEM_WRITE);
+
+  /* Set the prefix */
+  WIFI_CHECK_SUCCESS(wlan_smart_config_set_prefix((char * )&_wifi_sc_prefix),
+                     "Unable to set the SmartConfig prefix",
+                     ERROR_CC3000_SMARTCONFIG_SET_PREFIX);
+
+  /* Start the SmartConfig process */
+  WIFI_CHECK_SUCCESS(wlan_smart_config_start(enableAES),
+                     "wlan_smart_config_start failed",
+                     ERROR_CC3000_SMARTCONFIG_START);
+
+  /* Wait for the SmartConfig process to complete */
+  while (_wifi_smartConfigFinished == 0)
+  {
+    // Waiting here for the SIMPLE_CONFIG_DONE event
+    timeout++;
+    if (timeout > WIFI_TIMEOUT_CONNECT / 10)
+    {
+      _wifi_smartConfigFailure = 1;
+      return ERROR_CC3000_CONNECT_TIMEOUT;
+    }
+    delay(10);
+  }
+
+  if (enableAES)
+  {
+    WIFI_CHECK_SUCCESS(wlan_smart_config_process(),
+                       "wlan_smart_config_process failed",
+                       ERROR_CC3000_SMARTCONFIG_PROCESS);
+  }
+
+  /* Configure the device to automatically connect to the AP */
+  WIFI_CHECK_SUCCESS(wlan_ioctl_set_connection_policy(WIFI_DISABLE, WIFI_DISABLE, WIFI_ENABLE),
+                     "Set connection policy FAIL",
+                     ERROR_CC3000_WLAN_SET_CONNECT_POLICY);
+
+  /* Reset the CC3000 */
+  wlan_stop();
+  delay(1000);
+  wlan_start(0);
+
+  /* Setup the event masks (async events we don't want, see hci.h) */
+  WIFI_CHECK_SUCCESS(wlan_set_event_mask(
+                     HCI_EVNT_WLAN_KEEPALIVE         |
+                     HCI_EVNT_WLAN_UNSOL_INIT        |
+                     // HCI_EVNT_WLAN_ASYNC_PING_REPORT |
+                     // HCI_EVNT_WLAN_TX_COMPLETE,
+                     HCI_EVNT_BSD_TCP_CLOSE_WAIT),
+                     "WLAN Set Event Mask FAIL",
+                     ERROR_CC3000_WLAN_EVENT_MASK);
+
+  /* Small delay to wait for the CC3000 to connect to the AP */
+  timeout = 0;
+  delay(1000);
+
+  /**************** Connect to the AP (time out ~30s) ***********************/
+
+  while ((!_wifi_smartConfigFinished) || (!_wifi_connected) || (!_wifi_dhcp))
+  {
+    timeout ++;
+    if (timeout > WIFI_TIMEOUT_CONNECT / 10)
+    {
+      _wifi_smartConfigFailure = 1;
+      return ERROR_CC3000_CONNECT_TIMEOUT;
+    }
+    delay(10);
+  }
+
+  if (((_wifi_smartConfigFinished) && (_wifi_connected) && (_wifi_dhcp)))
+  {
+    while (loop < 5)
+    {
+      mdnsAdvertiser(1, (char *) _wifi_sc_deviceName, strlen(_wifi_sc_deviceName));
+      loop++;
+    }
+  }
+
+  _wifi_stopSmartConfig = 0;
+  _wifi_smartConfigFinished = 0;
+
+  /* Smart config was successful! */
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Disconnect if we are connected to an AP
+
+    @note   Possible error message are:
+
+            - ERROR_CC3000_WLAN_EVENT_MASK (wifi_init)
+            - ERROR_NONE
+*/
+/**************************************************************************/
+err_t wifi_disconnect(void)
+{
+  WIFI_CHECK_INIT();
+
+  /* Disconnect */
+  wlan_disconnect();
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the connection details for the module (IP, net mask,
+            gateway, DHCP server and DNS server addresses)
+
+    @note   Possible error message are:
+
+            - ERROR_CC3000_WLAN_EVENT_MASK (wifi_init)
+            - ERROR_CC3000_NETAPP_IPCONFIG
+            - ERROR_NONE
+
+    @code
+
+    // Display the connection details
+    uint8_t ip[4];
+    uint8_t netmask[4];
+    uint8_t gateway[4];
+    uint8_t dhcp[4];
+    uint8_t dns[4];
+
+    error = wifi_getConnectionDetails(ip, netmask, gateway, dhcp, dns);
+
+    if (!error)
+    {
+      printf("IP Address  : %d.%d.%d.%d %s",
+        ip[0], ip[1], ip[2], ip[3], CFG_PRINTF_NEWLINE);
+      printf("Netmask     : %d.%d.%d.%d %s",
+        netmask[0], netmask[1], netmask[2], netmask[3], CFG_PRINTF_NEWLINE);
+      printf("Gateway     : %d.%d.%d.%d %s",
+        gateway[0], gateway[1], gateway[2], gateway[3], CFG_PRINTF_NEWLINE);
+      printf("DHCP Server : %d.%d.%d.%d %s",
+        dhcp[0], dhcp[1], dhcp[2], dhcp[3], CFG_PRINTF_NEWLINE);
+      printf("DNS Server  : %d.%d.%d.%d %s",
+        dns[0], dns[1], dns[2], dns[3], CFG_PRINTF_NEWLINE);
+    }
+
+    @endcode
+*/
+/**************************************************************************/
+err_t wifi_getConnectionDetails(uint8_t ipAddress[4], uint8_t netmask[4],
+                                  uint8_t gateway[4], uint8_t dhcpServer[4],
+                                  uint8_t dnsServer[4])
+{
+  tNetappIpconfigRetArgs ipconfig;
+
+  WIFI_CHECK_INIT();
+
+  /* Request the connection details */
+  netapp_ipconfig(&ipconfig);
+
+  /* Make sure we have an IP address (connection was lost, etc.) */
+  ASSERT(ipconfig.aucIP[3] != 0, ERROR_CC3000_NETAPP_IPCONFIG);
+
+  /* Push the values into the placeholder variables */
+  memcpy(ipAddress,   ipconfig.aucIP,     4);
+  wifi_reverseByteOrder(ipAddress);
+  memcpy(netmask,     ipconfig.aucIP+4,   4);
+  wifi_reverseByteOrder(netmask);
+  memcpy(gateway,     ipconfig.aucIP+8,   4);
+  wifi_reverseByteOrder(gateway);
+  memcpy(dhcpServer,  ipconfig.aucIP+12,  4);
+  wifi_reverseByteOrder(dhcpServer);
+  memcpy(dnsServer,   ipconfig.aucIP+16,  4);
+  wifi_reverseByteOrder(dnsServer);
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Pings the specified IP address
+
+    @param   ip         Four byte array containg the IP address to ping
+    @param   attempts   The number of times to ping the IP address
+    @param   timeout    The ping timeout in milliseconds
+
+    @note    Possible error message are:
+
+             - ERROR_CC3000_WLAN_EVENT_MASK (wifi_init)
+             - ERROR_CC3000_NETAPP_PING
+             - ERROR_CC3000_NETAPP_PING_MISSINGEVENT
+             - ERROR_NONE
+
+    @code
+
+    // Ping www.adafruit.com 3 times
+    uint8_t  pingIP[4]    = { 207, 58, 139, 247 };
+    uint8_t  pingAttempts = 3;
+    uint16_t pingTimeout  = 1000;
+
+    printf("Pinging %d.%d.%d.%d %d times (%d ms timeout)%s",
+      pingIP[0], pingIP[1], pingIP[2], pingIP[3],
+      pingAttempts, pingTimeout, CFG_PRINTF_NEWLINE);
+
+    error = wifi_ping(pingIP, pingAttempts, pingTimeout);
+
+    @endcode
+*/
+/**************************************************************************/
+err_t wifi_ping(uint8_t ip[4], uint8_t attempts, uint16_t timeout)
+{
+  WIFI_CHECK_INIT();
+
+  uint32_t revIP = (ip[0] | (ip[1] << 8) | (ip[2] << 16) | (ip[3] << 24));
+
+  /* Reset the ping result placeholders */
+  _wifi_pingReportsReceived = 0;
+  memset(&_wifi_pingReport, 0, sizeof(netapp_pingreport_args_t));
+
+  /* Start the async request (response handled in wifi_UsynchCallback) */
+  WIFI_CHECK_SUCCESS(netapp_ping_send(&revIP, attempts, 32, timeout),
+                     "Ping failed", ERROR_CC3000_NETAPP_PING);
+
+  /* Give the ping time to execute */
+  delay( (timeout * attempts) + 500);
+
+  /* Force the async event by requesting the ping report */
+  /* See: http://e2e.ti.com/support/low_power_rf/f/851/p/214148/785692.aspx */
+  netapp_ping_report();
+
+  delay(1000);
+
+  /* Make sure the async ping event fired */
+  ASSERT(_wifi_pingReportsReceived, ERROR_CC3000_NETAPP_PING_MISSINGEVENT);
+
+  /* Display the results */
+  // WIFI_PRINTF("Packets Sent     : %u\r\n", _wifi_pingReport.packets_sent);
+  WIFI_PRINTF("Packets Received : %u\r\n", _wifi_pingReport.packets_received);
+  WIFI_PRINTF("Minimum Time     : %u\r\n", _wifi_pingReport.min_round_time);
+  WIFI_PRINTF("Maximum Time     : %u\r\n", _wifi_pingReport.max_round_time);
+  WIFI_PRINTF("Average Time     : %u\r\n", _wifi_pingReport.avg_round_time);
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Looks up the IP address of the specific host name
+
+    @param   hostName   The string containing the host name to lookup
+    @param   ip         The placeholder for the host IP address
+
+    @note    Possible error message are:
+
+             - ERROR_CC3000_WLAN_EVENT_MASK (wifi_init)
+             - ERROR_CC3000_SOCKET_GETHOSTBYNAME
+             - ERROR_NONE
+
+    @code
+
+    // Lookup the IP address for www.adafruit.com
+    uint8_t lookupIP[4] = { 0, 0, 0, 0 };
+
+    error = wifi_getHostByName("www.adafruit.com", lookupIP);
+
+    if (!error)
+    {
+      printf("www.adafruit.com = %d.%d.%d.%d %s",
+        lookupIP[0], lookupIP[1], lookupIP[2], lookupIP[3],
+        CFG_PRINTF_NEWLINE);
+    }
+
+    @endcode
+*/
+/**************************************************************************/
+err_t wifi_getHostByName(uint8_t *hostName, uint8_t ip[4])
+{
+  uint32_t revIP;
+
+  WIFI_CHECK_INIT();
+
+  /* gethostbyname returns a positive number is successful */
+  ASSERT_MESSAGE(gethostbyname(hostName, (unsigned short int)strlen(hostName), &revIP) > 0,
+                 ERROR_CC3000_SOCKET_GETHOSTBYNAME,
+                 "Host name lookup failed");
+
+  /* Assign IP contents */
+  memcpy(ip, &revIP, 4);
+  wifi_reverseByteOrder(ip);
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief   Checks if we are connected to an access point or not
+*/
+/**************************************************************************/
+bool wifi_isConnected(void)
+{
+  return _wifi_connected ? true : false;
+}
+
+/**************************************************************************/
+/*!
+    @brief   Checks if DHCP is complete or not (do we have an IP address?)
+*/
+/**************************************************************************/
+bool wifi_isDHCPComplete(void)
+{
+  return _wifi_dhcp ? true : false;
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/wifi.h b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/wifi.h
new file mode 100644
index 0000000000000000000000000000000000000000..03288b942b652bf065c01b163add107c9d34168d
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rf/wifi/cc3000/wifi.h
@@ -0,0 +1,71 @@
+/**************************************************************************/
+/*!
+    @file     wifi.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _WIFI_APPLICATION_BASIC_H_
+#define _WIFI_APPLICATION_BASIC_H_
+
+#include "projectconfig.h"
+
+#include <stdint.h>
+
+#pragma pack(1)
+/**! Stores the results of SSID scans  */
+typedef struct Result_Struct
+{
+  uint32_t  num_networks;
+  uint32_t  scan_status;
+  uint8_t   rssiByte;
+  uint8_t   Sec_ssidLen;
+  uint16_t  time;
+  uint8_t   ssid_name[32];
+  uint8_t   bssid[6];
+} ResultStruct_t;
+
+err_t  wifi_init(unsigned short cRequestPatch);
+err_t  wifi_getFirmwareVersion(uint8_t *major, uint8_t *minor);
+err_t  wifi_getMacAddress(uint8_t macAddress[6]);
+err_t  wifi_setMacAddress(uint8_t macAddress[6]);
+err_t  wifi_ssidScan(uint32_t time);
+err_t  wifi_displaySSIDResults(void);
+err_t  wifi_connectSecure(int32_t sec, int8_t *ssid, int32_t ssidlen, int8_t *key, int32_t keylen);
+err_t  wifi_startSmartConfig(bool enableAES);
+err_t  wifi_disconnect(void);
+err_t  wifi_getConnectionDetails(uint8_t ipAddress[4], uint8_t netmask[4], uint8_t gateway[4], uint8_t dhcpServer[4], uint8_t dnsServer[4]);
+err_t  wifi_ping(uint8_t ip[4], uint8_t attempts, uint16_t timeout);
+err_t  wifi_getHostByName(uint8_t *hostName, uint8_t ip[4]);
+bool     wifi_isConnected(void);
+bool     wifi_isDHCPComplete(void);
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rtc/pcf2129/pcf2129.c b/reform2-lpc-fw/src/drivers/rtc/pcf2129/pcf2129.c
new file mode 100644
index 0000000000000000000000000000000000000000..beee60619f3391e33277cf72987c2c7ba89d5ec7
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rtc/pcf2129/pcf2129.c
@@ -0,0 +1,540 @@
+/**************************************************************************/
+/*!
+    @file     pcf2129.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Drivers for NXP's PCF2129A temp-compensated RTC
+
+    @section DESCRIPTION
+
+    The PCF2129A is a CMOS Real Time Clock (RTC) and calendar with an
+    integrated Temperature Compensated Crystal (Xtal) Oscillator (TCXO)
+    and a 32.768 kHz quartz crystal optimized for very high accuracy and
+    very low power consumption.
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_RTC
+
+#include <string.h>
+#include "pcf2129.h"
+#include "core/gpio/gpio.h"
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+static bool _pcf2129Initialised = false;
+static void (*_pcf2129Callback)(void) = NULL;
+
+/**************************************************************************/
+/*!
+    @brief  Writes the specified number of bytes over I2C
+*/
+/**************************************************************************/
+err_t pcf2129WriteBytes(uint8_t reg, uint8_t *buffer, size_t length)
+{
+  uint32_t i;
+
+  /* Try to avoid buffer overflow */
+  ASSERT(length <= I2C_BUFSIZE - 2, ERROR_BUFFEROVERFLOW);
+
+  /* Fill write buffer */
+  for ( i = 2; i < length+2; i++ )
+  {
+    I2CMasterBuffer[i] = buffer[i-2];
+  }
+
+  /* Write transaction */
+  I2CWriteLength = 2+length;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = PCF2129_ADDRESS;
+  I2CMasterBuffer[1] = reg;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the specified number of bytes over I2C
+*/
+/**************************************************************************/
+err_t pcf2129ReadBytes(uint8_t reg, uint8_t *buffer, size_t length)
+{
+  uint32_t i;
+
+  /* Try to avoid buffer overflow */
+  ASSERT(length <= I2C_BUFSIZE, ERROR_BUFFEROVERFLOW);
+
+  /* Read and write need to be handled in separate transactions or the
+     PCF2129 increments the current register one step ahead of where
+     we should be. */
+
+  /* Write transaction */
+  I2CWriteLength = 2;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = PCF2129_ADDRESS;
+  I2CMasterBuffer[1] = reg;
+  i2cEngine();
+
+  /* Read transaction */
+  I2CWriteLength = 0;
+  I2CReadLength = length;
+  I2CMasterBuffer[0] = PCF2129_ADDRESS | PCF2129_READBIT;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  /* Fill the buffer with the I2C response */
+  for ( i = 0; i < length; i++ )
+  {
+    buffer[i] = I2CSlaveBuffer[i];
+  }
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Writes an 8 bit value over I2C
+*/
+/**************************************************************************/
+err_t pcf2129Write8 (uint8_t reg, uint8_t value)
+{
+  uint8_t buffer = value;
+  return pcf2129WriteBytes(reg, &buffer, 1);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads a single byte over I2C
+*/
+/**************************************************************************/
+err_t pcf2129Read8(uint8_t reg, uint8_t *result)
+{
+  return pcf2129ReadBytes(reg, result, 1);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Initialises the I2C block
+*/
+/**************************************************************************/
+err_t pcf2129Init(void)
+{
+  uint8_t result;
+
+  /* Initialise I2C */
+  i2cInit(I2CMASTER);
+
+  /* Ping the I2C device first to see if it exists! */
+  ASSERT(i2cCheckAddress(PCF2129_ADDRESS), ERROR_I2C_DEVICENOTFOUND);
+
+  /* Set CONTROL1 register (0x00)
+     ====================================================================
+     BIT  Symbol    Description                                   Default
+     ---  ------    --------------------------------------------- -------
+       7  EXT_TEST  0 = Normal mode, 1 = External clock test mode       0
+       6  --        RESERVED
+       5  STOP      0 = RTC clock runs, 1 = RTC clock stopped           0
+       4  TSF1      0 = No timestamp interrupt,                         0
+                    1 = Flag set when TS input is driven to an
+                        intermediate level between power supply
+                        and ground. (Flag must be cleared to
+                        clear interrupt.)
+       3  POR_OVRD  0 = Power on reset override disabled                0
+                    1 = Power on reset override enabled
+       2  12_24     0 = 24 hour mode, 1 = 12 hour mode                  0
+       1  MI        0 = Minute interrupt disabled, 1 = enabled          0
+       0  SI        0 = Second interrupt disabled, 1 = enabled          0 */
+
+  ASSERT_STATUS(pcf2129Write8(PCF2129_REG_CONTROL1, 0x00));
+
+  /* Set CONTROL2 register (0x01)
+     ====================================================================
+     BIT  Symbol    Description                                   Default
+     ---  ------    --------------------------------------------- -------
+       7  MSF       0 = No minute or second interrupt generated,        0
+                    1 = Flag set when minute or second interrupt
+                        generated. (Flag must be cleared to clear
+                        interrupt.)
+       6  WDTF      0 = No watchdog timer interrupt or reset            0
+                    1 = Flag set when watchdog timer interrupt or
+                        reset generated. (Flag cannot be cleared
+                        by using the interface [read only])
+       5  TSF2      0 = No timestamp interrupt generated                0
+                    1 = Flag set when TS input is driven to GND.
+                        (Flag must be cleared to clear interrupt)
+       4  AF        0 = No alarm interrupt generated,
+                    1 = Flag set when alarm triggered. (Flag must       0
+                        be cleared to clear interrupt)
+       3  --        RESERVED
+       2  TSIE      0 = No interrupt generated from timestamp           0
+                        interrupt
+                    1 = Interrupt generated when timestamp flag
+                        set
+       1  AIE       0 = No interrupt generated from the alarm           0
+                        flag
+                    1 = Interrupt generated when alarm flag set
+       0  --        RESERVED                                              */
+
+  ASSERT_STATUS(pcf2129Write8(PCF2129_REG_CONTROL2, 0x00));
+
+  /* Set CONTROL3 register (0x02)
+     ====================================================================
+     BIT  Symbol    Description                                   Default
+     ---  ------    --------------------------------------------- -------
+     7-5  PWRMNG    Control of the battery switch-over, battery       000
+                    low detection, and extra power fail detection
+                    function:
+                    000 Battery switch-over function is enabled
+                        in standard mode; battery low detection
+                        function is enabled
+                    001 Battery switch-over function is enabled
+                        in standard mode; battery low detection
+                        function is disabled
+                    010 Battery switch-over function is enabled
+                        in standard mode; battery low detection
+                        function is disabled
+                    011 Battery switch-over function is enabled
+                        in direct switching mode; battery low
+                        detection function is enabled
+                    100 Battery switch-over function is enabled
+                        in direct switching mode; battery low
+                        detection function is disabled
+                    101 Battery switch-over function is enabled
+                        in direct switching mode; battery low
+                        detection function is disabled
+                    111 Battery switch-over function is disabled,
+                        only one power supply (VDD); battery low
+                        detection function is disabled
+       4  BTSE      0 = No timestamp when battery switch-over           0
+                        occurs
+                    1 = Time-stamped when battery switch-over
+                        occurs
+       3  BF        0 = No battery switch-over interrupt                0
+                        generated
+                    1 = Flag set when battery switch-over occurs
+                        (Flag must be cleared to clear interrupt)
+       2  BLF       0 = Battery status OK (no battery low               0
+                        interrupt generated).
+                    1 = Battery status low (flag cannot be
+                        cleared using the interface)
+       1  BIE       0 = No interrupt generated from the battery         0
+                        flag (BF)
+                    1 = Interrupt generated when BF is set
+       0  BLIE      0 = No interrupt generated from the battery         0
+                        low flag (BLF)
+                    1 = Interrupt generated when BLF is set               */
+  ASSERT_STATUS(pcf2129Write8(PCF2129_REG_CONTROL2, 0x00));
+
+  /* Setup the IRQ pin */
+  #if PCF2129_INT_ENABLED
+    /* Setup the second and minute interrupts to pulse (avoids having to clear them) */
+    /* TI_TP (bit 5) = 1 for pulse, TF (bits 1:0) = 11 for 1/60Hz (default) */
+    ASSERT_STATUS(pcf2129Write8(PCF2129_REG_WATCHDOG_TIM_CTRL, 0x23));
+
+    /* INT is open drain so we need to enable the pullup on the pin */
+    PCF2129_INT_SETPULLUP;
+
+    /* Set interrupt/gpio pin to input */
+    LPC_GPIO->DIR[PCF2129_INT_PORT] &= ~(1 << PCF2129_INT_PIN);
+
+    /* Set RTC INT pin as edge sensitive, and active on the falling edge */
+    GPIOSetPinInterrupt( PCF2129_INT_FLEXIRQNUM, PCF2129_INT_PORT, PCF2129_INT_PIN, 0, 0 );
+
+    /* Allow the interrupt to wake the device up from power down */
+    // LPC_SYSCON->STARTERP0 |= (0x1 << PCF2129_INT_FLEXIRQNUM);
+
+    /* Adjust the interrupt priority if necessary */
+    // NVIC_SetPriority(FLEX_INT1_IRQn, 2);
+
+    /* Enable interrupt on falling edge */
+    GPIOPinIntEnable( PCF2129_INT_FLEXIRQNUM, 0 );
+
+    /* Clear any possible interrupts */
+    ASSERT_STATUS(pcf2129Read8(PCF2129_REG_CONTROL2, &result));
+    ASSERT_STATUS(pcf2129Write8(PCF2129_REG_CONTROL2, 0x00));
+  #endif
+
+  _pcf2129Initialised = true;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Registers the optional callback function that will be called
+            in the interrupt handler
+
+    @section EXAMPLE
+
+    @code
+
+    uint32_t _rtcCounter;
+    void rtcCounter(void)
+    {
+      _rtcCounter++;
+    }
+
+    // ...
+
+    // Try to initialise the PCF2129 RTC
+    if (pcf2129Init())
+    {
+      printf("PCF2129 failed to initialise");
+    }
+    else
+    {
+      // Setup an INT callback to rtcCounter
+      pcf2129SetCallback (&rtcCounter);
+
+      // Setup the INT line to generate an interrupt every second and on ALARM
+      pcf2129SetInterrupt(PCF2129_INTEVENT_SECONDTIMER | PCF2129_INTEVENT_ALARM);
+    }
+
+    @endcode
+*/
+/**************************************************************************/
+void pcf2129SetCallback (void (*pFunc)(void))
+{
+  _pcf2129Callback = pFunc;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the current time from the RTC
+
+    @section EXAMPLE
+
+    @code
+
+    // Try to initialise the PCF2129 RTC
+    if (pcf2129Init())
+    {
+      printf("PCF2129 failed to initialise");
+    }
+    else
+    {
+      // Constantly read the time
+      rtcTime_t time;
+      while(1)
+      {
+        pcf2129ReadTime(&time);
+        printf("%02d:%02d:%02d - %04d/%02d/%02d%s", time.hours, time.minutes, time.seconds, time.years+1900, time.months+1, time.days, CFG_PRINTF_NEWLINE);
+        printf("Epoch Time: %u%s", rtcToEpochTime(&time), CFG_PRINTF_NEWLINE);
+      }
+    }
+
+    @endcode
+*/
+/**************************************************************************/
+err_t pcf2129ReadTime(rtcTime_t *time)
+{
+  if (!_pcf2129Initialised )
+  {
+    ASSERT_STATUS(pcf2129Init());
+  }
+
+  /* The PCF2129 will auto-increment the register after a read or
+     write so we only need to pass the first register and set the
+     read length to get the full RTC time. */
+  ASSERT_STATUS(pcf2129ReadBytes(PCF2129_REG_SECONDS, (uint8_t *)time, sizeof(rtcTime_t)));
+
+  /* Convert time values to decimal from BCD */
+  time->seconds  = rtcBCDToDec(time->seconds & 0x7F);
+  time->minutes  = rtcBCDToDec(time->minutes);
+  time->hours    = rtcBCDToDec(time->hours);
+  time->days     = rtcBCDToDec(time->days);
+  time->weekdays = rtcBCDToDec(time->weekdays);
+  time->months   = rtcBCDToDec(time->months);
+  time->years    = rtcBCDToDec(time->years) + 100; /* PCF year is BCD so 0..99, rtcTime_t is years since 1900 */
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the time on the RTC to the supplied value
+
+    @section EXAMPLE
+
+    @code
+
+    // Try to initialise the PCF2129 RTC
+    if (pcf2129Init())
+    {
+      printf("PCF2129 failed to initialise");
+    }
+    else
+    {
+      // Set time to 10:04:00, 4 September 2012 (24-hour time)
+      rtcTime_t time;
+      rtcCreateTime(2012, RTC_MONTHS_SEPTEMBER, 4, 10, 4, 0, 0, &time);
+      pcf2129SetTime(time);
+    }
+
+    @endcode
+*/
+/**************************************************************************/
+err_t pcf2129SetTime(rtcTime_t time)
+{
+  if (!_pcf2129Initialised )
+  {
+    ASSERT_STATUS(pcf2129Init());
+  }
+
+  /* ToDo: Disable RTC while the time is updated? */
+
+  /* Convert time values to BCD format used by the RTC */
+  time.seconds  = rtcDecToBCD(time.seconds);
+  time.minutes  = rtcDecToBCD(time.minutes);
+  time.hours    = rtcDecToBCD(time.hours);
+  time.days     = rtcDecToBCD(time.days);
+  time.weekdays = rtcDecToBCD(time.weekdays);
+  time.months   = rtcDecToBCD(time.months);
+  time.years    = rtcDecToBCD(time.years - 100);
+
+  /* The PCF2129 will auto-increment the register after a read or
+     write so we only need to pass the first register and set the
+     write length to set the full RTC time. */
+  return pcf2129WriteBytes(PCF2129_REG_SECONDS, (uint8_t *)&time, sizeof(rtcTime_t));
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets up the RTC interrupt for the specified event
+
+    @section EXAMPLE
+
+    @code
+
+    if (pcf2129Init())
+    {
+      printf("PCF2129 failed to initialise");
+    }
+    else
+    {
+      // Setup the INT line to generate an interrupt every second and on ALARM
+      pcf2129SetInterrupt(PCF2129_INTEVENT_SECONDTIMER | PCF2129_INTEVENT_ALARM);
+    }
+
+    @endcode
+*/
+/**************************************************************************/
+err_t pcf2129SetInterrupt(pcf2129_INTEvent_t eventFlags)
+{
+  uint8_t config[3];
+
+  if (!_pcf2129Initialised )
+  {
+    ASSERT_STATUS(pcf2129Init());
+  }
+
+  /* Read the current config bytes */
+  ASSERT_STATUS(pcf2129ReadBytes(PCF2129_REG_CONTROL1, config, 3));
+
+  /* Set SI on REG_CONTROL1 (bit 0) */
+  if (eventFlags & PCF2129_INTEVENT_SECONDTIMER)
+    config[0] |= (1<<0);
+  else
+    config[0] &= ~(1<<0);
+
+  /* Set MI on REG_CONTROL1 (bit 1) */
+  if (eventFlags & PCF2129_INTEVENT_MINUTETIMER)
+    config[0] |= (1<<1);
+  else
+    config[0] &= ~(1<<1);
+
+  /* Set AIE on REG_CONTROL2 (bit 1) */
+  if (eventFlags & PCF2129_INTEVENT_ALARM)
+    config[1] |= (1<<1);
+  else
+    config[1] &= ~(1<<1);
+
+  /* Set TSIE on REG_CONTROL2 (bit 2) */
+  if (eventFlags & PCF2129_INTEVENT_TIMESTAMP)
+    config[1] |= (1<<2);
+  else
+    config[1] &= ~(1<<2);
+
+  /* Set BIE on REG_CONTROL3 (bit 1) */
+  if (eventFlags & PCF2129_INTEVENT_BATTERYSWITCH)
+    config[2] |= (1<<1);
+  else
+    config[2] &= ~(1<<1);
+
+  /* Set BLIE on REG_CONTROL3 (bit 0) */
+  if (eventFlags & PCF2129_INTEVENT_BATTERYLOW)
+    config[2] |= (1<<0);
+  else
+    config[2] &= ~(1<<0);
+
+  /* Write the updated config bits back to the RTC */
+  return pcf2129WriteBytes(PCF2129_REG_CONTROL1, config, 3);
+}
+
+/**************************************************************************/
+/*!
+    PCF2129 INT IRQ Handler
+*/
+/**************************************************************************/
+#if defined CFG_MCU_FAMILY_LPC11UXX
+void FLEX_INT1_IRQHandler(void)
+#elif defined CFG_MCU_FAMILY_LPC13UXX
+void PIN_INT1_IRQHandler(void)
+#else
+  #error "pcf2129.c: No MCU defined"
+#endif
+{
+  /* Make sure the right flag is set in the int status register */
+  if ( LPC_GPIO_PIN_INT->IST & (0x1<<1) )
+  {
+    /* Falling Edge */
+    if ( ( LPC_GPIO_PIN_INT->FALL & (0x1<<1) ) && ( LPC_GPIO_PIN_INT->IENF & (0x1<<1) ) )
+    {
+      /* Call the callback function if present */
+      if (NULL != _pcf2129Callback )
+      {
+        _pcf2129Callback();
+      }
+      LPC_GPIO_PIN_INT->FALL = 0x1<<1;
+    }
+    /* Clear the FLEX/PIN interrupt */
+    LPC_GPIO_PIN_INT->IST = 0x1<<1;
+  }
+  return;
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rtc/pcf2129/pcf2129.h b/reform2-lpc-fw/src/drivers/rtc/pcf2129/pcf2129.h
new file mode 100644
index 0000000000000000000000000000000000000000..81410327b9411ccb6b65170811901857414f0d68
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rtc/pcf2129/pcf2129.h
@@ -0,0 +1,110 @@
+/**************************************************************************/
+/*!
+    @file     pcf2129.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012 K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _PCF2129_H_
+#define _PCF2129_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "core/i2c/i2c.h"
+#include "drivers/rtc/rtc.h"
+
+#define PCF2129_ADDRESS           (0x51<<1)
+#define PCF2129_READBIT           (0x01)
+
+#define PCF2129_INT_ENABLED       (true)
+#define PCF2129_INT_PORT          (0)
+#define PCF2129_INT_PIN           (16)
+#define PCF2129_INT_FLEXIRQNUM    (1)       // Use FLEXIRQ 1
+#define PCF2129_INT_SETPULLUP     do { LPC_IOCON->PIO0_16 = (0<<0) | (2<<3) | (1<<7); } while(0)
+
+#define PCF2129_TIMESTAMP_ENABLED (false)
+#define PCF2129_TIMESTAMP_PORT    (0)
+#define PCF2129_TIMESTAMP_PIN     (17)
+
+typedef enum
+{
+  PCF2129_INTEVENT_SECONDTIMER    = (1<<0),
+  PCF2129_INTEVENT_MINUTETIMER    = (1<<1),
+  PCF2129_INTEVENT_ALARM          = (1<<2),
+  PCF2129_INTEVENT_TIMESTAMP      = (1<<3),
+  PCF2129_INTEVENT_BATTERYSWITCH  = (1<<4),
+  PCF2129_INTEVENT_BATTERYLOW     = (1<<5)
+} pcf2129_INTEvent_t;
+
+enum
+{
+  PCF2129_REG_CONTROL1            = 0x00,
+  PCF2129_REG_CONTROL2            = 0x01,
+  PCF2129_REG_CONTROL3            = 0x02,
+  PCF2129_REG_SECONDS             = 0x03,
+  PCF2129_REG_MINUTES             = 0x04,
+  PCF2129_REG_HOURS               = 0x05,
+  PCF2129_REG_DAYS                = 0x06,
+  PCF2129_REG_WEEKDAYS            = 0x07,
+  PCF2129_REG_MONTHS              = 0x08,
+  PCF2129_REG_YEARS               = 0x09,
+  PCF2129_REG_ALARM_SECOND        = 0x0A,
+  PCF2129_REG_ALARM_MINUTE        = 0x0B,
+  PCF2129_REG_ALARM_HOUR          = 0x0C,
+  PCF2129_REG_ALARM_DAY           = 0x0D,
+  PCF2129_REG_ALARM_WEEKDAY       = 0x0E,
+  PCF2129_REG_CLOCKOUT_CTRL       = 0x0F,
+  PCF2129_REG_WATCHDOG_TIM_CTRL   = 0x10,
+  PCF2129_REG_WATCHDOG_TIM_VAL    = 0x11,
+  PCF2129_REG_TIMESTAMP_CTRL      = 0x12,
+  PCF2129_REG_TIMESTAMP_SEC       = 0x13,
+  PCF2129_REG_TIMESTAMP_MIN       = 0x14,
+  PCF2129_REG_TIMESTAMP_HOUR      = 0x15,
+  PCF2129_REG_TIMESTAMP_DAY       = 0x16,
+  PCF2129_REG_TIMESTAMP_MONTH     = 0x17,
+  PCF2129_REG_TIMESTAMP_YEAR      = 0x18,
+  PCF2129_REG_AGINGOFFSET         = 0x19
+};
+
+err_t pcf2129Init(void);
+void    pcf2129SetCallback (void (*pFunc)(void));
+err_t pcf2129ReadTime(rtcTime_t *time);
+err_t pcf2129SetTime(rtcTime_t time);
+err_t pcf2129SetInterrupt(pcf2129_INTEvent_t eventFlags);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/rtc/rtc.c b/reform2-lpc-fw/src/drivers/rtc/rtc.c
new file mode 100644
index 0000000000000000000000000000000000000000..8346a8cd645c3b5ff8b7f4863995763e30877876
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rtc/rtc.c
@@ -0,0 +1,564 @@
+/**************************************************************************/
+/*!
+    @file rtc.c
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <string.h>
+#include "rtc.h"
+
+/**************************************************************************/
+/*!
+ @brief Checks whether a date is valid.
+
+ @note  Does not check the EPOCH range
+
+ @param[in] year    1900-based year (ex. 113 = 2013)
+ @param[in] month   month based on rtcMonths_t
+ @param[in] day     day of month
+
+ @return error code indicate whether the date is valid
+ @retval ERROR_NONE the date is valid
+ @retval ERROR_INVALIDPARAMETER the date is invalid
+ */
+/**************************************************************************/
+static err_t rtcCheckValidDate(uint32_t year, uint8_t month, uint32_t day)
+{
+    /* Basic validation of values */
+    if (year >= 1900)
+    {
+        year -= 1900;
+    }
+    if ((month > RTC_MONTHS_DECEMBER) || (month < RTC_MONTHS_JANUARY))
+    {
+        return ERROR_INVALIDPARAMETER;
+    }
+    if (month == 2)
+    {
+        if (rtcIsLeapYear(year))
+        {
+            if (day > 29)
+            {
+                return ERROR_INVALIDPARAMETER;
+            }
+        }
+        else
+        {
+            if (day > 28)
+            {
+                return ERROR_INVALIDPARAMETER;
+            }
+        }
+    }
+    else if ((month == 4) || (month == 6) || (month == 9) || (month == 11))
+    {
+        if (day > 30)
+        {
+            return ERROR_INVALIDPARAMETER;
+        }
+    }
+    else
+    {
+        if (day > 31)
+        {
+            return ERROR_INVALIDPARAMETER;
+        }
+    }
+    return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief   Standard decimal to binary coded decimal
+ @param   val[in]:  import number in Decimal
+ @return  number in BCD
+ */
+/**************************************************************************/
+uint8_t rtcDecToBCD(uint8_t val)
+{
+    return ((val / 10) << 4) | (val % 10);
+}
+
+/**************************************************************************/
+/*!
+ @brief   Binary coded decimal to standard decimal
+ @param   val[in]: import number in BCD
+ @return  number in Decimal
+ */
+/**************************************************************************/
+uint8_t rtcBCDToDec(uint8_t val)
+{
+    return (val >> 4) * 10 + (val & 0x0F);
+}
+
+/**************************************************************************/
+/*!
+ @brief  Automatically calculates the weekday value, and takes into
+         account if the supplied year is 'epoch' (8-bit value) or full
+         year (ex. 2013)
+ @param  year[in]:      year to assign to rtcTime_t
+         month[in]:     month to assign to rtcTime_t
+         day[in]:       day to assign to rtcTime_t
+         hour[in]:      hour to assign to rtcTime_t
+         minute[in]:    minute to assign to rtcTime_t
+         second[in]:    second to assign to rtcTime_t
+         timezone[in]:  timezone to assign to rtcTime_t
+         t[out]:        rtcTime_t reference to manipulate
+ @return errorCode
+ */
+/**************************************************************************/
+err_t rtcCreateTime(uint32_t year, rtcMonths_t month, uint8_t day,
+    uint8_t hour, uint8_t minute, uint8_t second, int8_t timezone, rtcTime_t *t)
+{
+    err_t errorCode;
+    rtcTime_t newTime;
+
+    /* Year is 8-bit value from 1900 */
+    if (year >= 1900)
+    {
+        year -= 1900;
+    }
+
+    /* Keep with the limits of epoch time: 1 Jan 1970 to 19 Jan 2038 */
+    if ((year < RTC_MIN_EPOCH_YEAR) || (year > RTC_MAX_EPOCH_YEAR))
+    {
+        return ERROR_RTC_OUTOFEPOCHRANGE;
+    }
+
+    /* Basic validation */
+    errorCode = rtcCheckValidDate(year, (uint8_t)month, day);
+    if (errorCode != ERROR_NONE)
+    {
+        return errorCode;
+    }
+    if ((hour > 23) || (minute > 59) || (second > 59))
+    {
+        return ERROR_INVALIDPARAMETER;
+    }
+    if ((timezone > 14) || (timezone < -12))
+    {
+        return ERROR_INVALIDPARAMETER;
+    }
+
+    newTime.years = year;
+    newTime.months = month;
+    newTime.days = day;
+    newTime.hours = hour;
+    newTime.minutes = minute;
+    newTime.seconds = second;
+    newTime.timezone = timezone;
+
+    if (rtcToEpochTime(&newTime) > RTC_MAX_EPOCH_TIME)
+    {
+        return ERROR_RTC_OUTOFEPOCHRANGE;
+    }
+    rtcAssignWeekday(&newTime);
+    memcpy(t, &newTime, sizeof(rtcTime_t));
+    return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief  Convert Unix epoch time to RTC time
+ @param  epochTime[in]: Unix epoch time
+         time[out]:     rtcTime_t reference to manipulate
+ @return errorCode
+ */
+/**************************************************************************/
+err_t rtcCreateTimeFromEpoch(uint32_t epochTime, rtcTime_t *time)
+{
+    int32_t j, g, dg, c, dc, b, db, a, da, y, m, d;
+
+    if (epochTime > RTC_MAX_EPOCH_TIME)
+    {
+        return ERROR_RTC_OUTOFEPOCHRANGE;
+    }
+    j = epochTime / 86400 + 2472632;
+    g = j / 146097;
+    dg = j % 146097;
+    c = (dg / 36524 + 1) * 3 / 4;
+    dc = dg - c * 36524;
+    b = dc / 1461;
+    db = dc % 1461;
+    a = (db / 365 + 1) * 3 / 4;
+    da = db - a * 365;
+    y = g * 400 + c * 100 + b * 4 + a;
+    m = (da * 5 + 308) / 153 - 2;
+    d = da - (m + 4) * 153 / 5 + 122;
+    time->years = y - 6700 + (m + 2) / 12;
+    time->months = (m + 2) % 12 + 1;
+    time->days = d + 1;
+    time->weekdays = (j + 2) % 7;
+
+    j = epochTime % 86400;
+    time->hours = j / 3600;
+    time->minutes = (j % 3600) / 60;
+    time->seconds = j % 60;
+    time->timezone = 0;
+    return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief  Convert seconds since 1980 to RTC Time
+ @param  seconds[in]: seconds since 1980
+         time[out]:   rtcTime_t reference to populate with the equivalent
+                      seconds since 1980
+ @return errorCode
+ */
+/**************************************************************************/
+err_t rtcCreateTimeFromSecondsSince1980(uint32_t seconds, rtcTime_t *time)
+{
+    return rtcCreateTimeFromEpoch(seconds + 315532800 /*epochTime of 1980 */,
+        time);
+}
+
+/**************************************************************************/
+/*!
+ @brief   Calculates and updates the day of the week to weekDay field of
+          the supplied rtcTime_t object based on the other values (year,
+          day, etc.)
+ @param   t[in/out]   rtcTime_t object containing the date to calculate
+                      the weekday for (assumes .weekdays is empty)
+ @return  errorCode
+ */
+/**************************************************************************/
+err_t rtcAssignWeekday(rtcTime_t *t)
+{
+    uint32_t NrOfDay;
+    NrOfDay = rtcGetEpochDate(t->years, t->months, t->days);
+    t->weekdays = (NrOfDay + 3) % 7;
+    return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief   Add seconds to rtcTime_t
+ @param   t[in/out]:  rtcTime_t to manipulate
+          s[in]:      Number of seconds to add (positive or negative)
+ @return  errorCode
+ */
+/**************************************************************************/
+err_t rtcAddSeconds(rtcTime_t *t, int32_t s)
+{
+    /* mls: We assume that t is a valid time in EPOCH range*/
+    int32_t epochTime = rtcToEpochTime(t);
+    epochTime += s;
+    if (epochTime < 0)
+    {
+        return ERROR_RTC_OUTOFEPOCHRANGE;
+    }
+    rtcCreateTimeFromEpoch(epochTime, t);
+    return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief   Add minutes to rtcTime_t
+ @param   t[in/out]:  rtcTime_t to manipulate
+          m[in]:      Number of minutes to add (positive or negative)
+ @return  errorCode
+ */
+/**************************************************************************/
+err_t rtcAddMinutes(rtcTime_t *t, int32_t m)
+{
+    if ((35791394 < m) || (-35791394 > m))
+    {
+        return ERROR_RTC_OUTOFEPOCHRANGE;
+    }
+    return rtcAddSeconds(t, m * 60);
+}
+
+/**************************************************************************/
+/*!
+ @brief   Add hours to rtcTime_t
+ @param   t[in/out]:  rtcTime_t to manipulate
+          h[in]:      import hours
+ @return  errorCode
+ */
+/**************************************************************************/
+err_t rtcAddHours(rtcTime_t *t, int32_t h)
+{
+    if ((596523 < h) || (-596523 > h))
+    {
+        return ERROR_RTC_OUTOFEPOCHRANGE;
+    }
+    return rtcAddSeconds(t, h * 3600);
+}
+
+/**************************************************************************/
+/*!
+ @brief   Add days to RTC
+ @param   t[in/out]:  rtcTime_t to manipulate
+          d[in]:      Number of days to add (positive or negative)
+ @return  errorCode
+ */
+/**************************************************************************/
+err_t rtcAddDays(rtcTime_t *t, int32_t d)
+{
+    if ((24855 < d) || (-24855 > d))
+    {
+        return ERROR_RTC_OUTOFEPOCHRANGE;
+    }
+    return rtcAddSeconds(t, d * 86400);
+}
+
+/**************************************************************************/
+/*!
+ @brief   Add month to RTC
+ @param   t[in/out]:  rtcTime_t to manipulate
+          m[in]:      Number of months to add (positive or negative)
+ @return  errorCode
+ */
+/**************************************************************************/
+err_t rtcAddMonths(rtcTime_t *t, int32_t m)
+{
+    rtcTime_t newTime;
+    int32_t monthCount = (int32_t) t->years * 12 + t->months;
+    monthCount += m;
+    if ((monthCount < RTC_MIN_EPOCH_YEAR * 12 + 1) || (monthCount > RTC_MIN_EPOCH_YEAR
+        * 12 + 1/*Jan 2038*/))
+    {
+        return ERROR_RTC_OUTOFEPOCHRANGE;
+    }
+
+    /* Check if new time is in EPOCH range */
+    memcpy(&newTime, t, sizeof(rtcTime_t));
+    newTime.years = (monthCount - 1) / 12;
+    newTime.months = (monthCount - 1) % 12 + 1;
+    if (rtcToEpochTime(&newTime) > RTC_MAX_EPOCH_TIME)
+    {
+        return ERROR_RTC_OUTOFEPOCHRANGE;
+    }
+    rtcAssignWeekday(&newTime);
+    memcpy(t, &newTime, sizeof(rtcTime_t));
+    return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief   Add year to RTC
+ @param   t[in/out]:  rtcTime_t to manipulate
+          y[in]:      Number of years to add (positive or negative)
+ @return  errorCode
+ */
+/**************************************************************************/
+err_t rtcAddYears(rtcTime_t *t, int32_t y)
+{
+    rtcTime_t newTime;
+    /* Check if new time is in EPOCH range */
+    memcpy(&newTime, t, sizeof(rtcTime_t));
+    newTime.years += y;
+    if ((newTime.years < RTC_MIN_EPOCH_YEAR) || (newTime.years > RTC_MAX_EPOCH_YEAR)
+        || (rtcToEpochTime(&newTime) > RTC_MAX_EPOCH_TIME))
+    {
+        return ERROR_RTC_OUTOFEPOCHRANGE;
+    }
+    rtcAssignWeekday(&newTime);
+    memcpy(t, &newTime, sizeof(rtcTime_t));
+    return ERROR_NONE;
+}
+
+
+/**************************************************************************/
+/*!
+ @brief   Return the seconds between t1 - t2
+ @param   t1[in]:       import RTC time t1
+          t2[in]:       import RTC time t2
+          seconds[out]: result (t1 - t2) in seconds
+ */
+/**************************************************************************/
+err_t rtcGetDifference(rtcTime_t *t1, rtcTime_t *t2, int32_t *seconds)
+{
+    /* If t1 and t2 are valid time in EPOCH range, overflow won't occur */
+    *seconds = rtcToEpochTime(t1) - rtcToEpochTime(t2);
+    return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief   Calculates the day of the week for the provided data.  Works for
+          any positive year, and checks for leap year if you attempt to
+          provide 29 Feb on a non-leap-year.
+ @param:  year[in]:     import year to Calculate
+          month[in]:    import month to Calculate
+          day[in]:      import day to Calculate
+          weekDay[out]: The calculate day of the week for year, month, day
+ @return  errorCode
+ */
+/**************************************************************************/
+err_t rtcGetWeekday(uint32_t year, rtcMonths_t month, uint8_t day,
+    rtcWeekdays_t *weekDay)
+{
+    /* ToDo: validate the supplied parameters */
+    err_t errorCode = ERROR_NONE;
+    uint32_t NrOfDay;
+    if (year >= 1900)
+    {
+        year -= 1900;
+    }
+    errorCode = rtcCheckValidDate(year, (uint8_t)month, day);
+    if (errorCode != ERROR_NONE)
+    {
+        return errorCode;
+    }
+    NrOfDay = rtcGetEpochDate(year, month, day);
+    *weekDay = (NrOfDay + 3) % 7;
+
+    return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief   Calculate the week number for the given date (9 January = week 2)
+ @param   t[in]:            import RTC time to calculate week number for
+          weekNumber[out]:  result after calculating
+ @return  errorCode
+ */
+/**************************************************************************/
+err_t rtcGetWeekNumber(rtcTime_t *t, uint8_t *weekNumber)
+{
+    uint32_t NrOfDay = rtcGetEpochDate(t->years, 1, 1);
+    uint8_t nextMondayDay = 8 - NrOfDay;
+
+    if ((t->months == 1) && (t->days < nextMondayDay))
+    {
+        *weekNumber = 1;
+    }
+    else
+    {
+        *weekNumber = (rtcGetEpochDate(t->years, t->months, t->days)
+            - rtcGetEpochDate(t->years, 1, nextMondayDay)) / 7 + 2;
+    }
+    return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief   Number of days in the supplied year
+ @param   year[in]: import year to take number of day
+ @return  365 days or 366 days
+ */
+/**************************************************************************/
+int32_t rtcGetDaysInYear(int32_t year)
+{
+    if (year >= 1900)
+    {
+        year -= 1900;
+    }
+    if (((year % 400) == 100) || (((year % 4) == 0) && ((year % 100) != 0)))
+    {
+        return 366;
+    }
+    return 365;
+}
+
+/**************************************************************************/
+/*!
+ @brief   Calculate number of days from Jan 1 1970
+ @prama   year[in]:   import year to calculate
+          month[in]:  import month to calculate
+          day[in]:    import day to calculate
+ @return  Number of day from Jan 1 1970
+ */
+/**************************************************************************/
+uint32_t rtcGetEpochDate(uint32_t year, rtcMonths_t month, uint8_t day)
+{
+    if (year >= 1900)
+    {
+        year -= 1900;
+    }
+    if ((year < RTC_MIN_EPOCH_YEAR) || (year > RTC_MAX_EPOCH_YEAR))
+    {
+        return 0;
+    }
+    /* month must be cast to uint8_t or this fails on some platforms */
+    uint8_t m = (uint8_t)(month & 0xFF);
+    return (1461 * (year + 6700 + (m - 14) / 12)) / 4 + (367 *
+        (m - 2 - 12 * ((m - 14) / 12))) / 12 -
+        (3 * ((year + 6800 + (m - 14) / 12) / 100)) / 4 +
+        day - 2472663;
+}
+
+/**************************************************************************/
+/*!
+ @brief   Convert the supplied rtcTime_t to the equivalent epoch time
+ @param   t[in]: import RTC time
+ @return  seconds since Jan 1 1970 to RTC time inputs
+ */
+/**************************************************************************/
+uint32_t rtcToEpochTime(rtcTime_t *t)
+{
+    if (t->years < 70)
+    {
+        return 0;
+    }
+    return rtcGetEpochDate(t->years, t->months, t->days) * 86400 + t->hours
+        * 3600 + t->minutes * 60 + t->seconds;
+}
+
+/**************************************************************************/
+/*!
+ @brief   Calculate seconds since Jan 1 1980 for the supplied rtcTime_t
+ @param   t[in]: import RTC time
+ @return  seconds since Jan 1 1980 to RTC time inputs
+ */
+/**************************************************************************/
+uint32_t rtcToSecondsSince1980(rtcTime_t *t)
+{
+    if (t->years < 80)
+    {
+        return 0;
+    }
+    return rtcGetEpochDate(t->years, t->months, t->days) * 86400 + t->hours
+        * 3600 + t->minutes * 60 + t->seconds - 315532800;
+}
+
+
+/**************************************************************************/
+/*!
+ @brief   Checks if the supplied year is a leap year or not
+ @param   year[in]: import year to take number of day
+ @return  RTC_LEAP_YEAR or RTC_NON_LEAP_YEAR
+ */
+/**************************************************************************/
+bool rtcIsLeapYear(int32_t year)
+{
+    if (year >= 1900)
+    {
+        year -= 1900;
+    }
+    if (((year % 400) == 100) || (((year % 4) == 0) && ((year % 100) != 0)))
+    {
+        return RTC_LEAP_YEAR;
+    }
+    return RTC_NON_LEAP_YEAR;
+}
diff --git a/reform2-lpc-fw/src/drivers/rtc/rtc.h b/reform2-lpc-fw/src/drivers/rtc/rtc.h
new file mode 100644
index 0000000000000000000000000000000000000000..16a182bad570fd13f72d87e72c829c4fdc099bbc
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/rtc/rtc.h
@@ -0,0 +1,134 @@
+/**************************************************************************/
+/*!
+    @file rtc.h
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _RTC_H_
+#define _RTC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "errors.h"
+
+#define RTC_LEAP_YEAR       (1)
+#define RTC_NON_LEAP_YEAR   (0)
+#define RTC_MAX_EPOCH_TIME  (2147483647UL)
+#define RTC_MIN_EPOCH_YEAR  (70)
+#define RTC_MAX_EPOCH_YEAR  (138)
+
+/**************************************************************************/
+/*!
+ * @brief     RTC weekdays structure (weekdays are zero-based and start
+              on Monday)
+ */
+/**************************************************************************/
+typedef enum rtcWeekdays_en
+{
+    RTC_WEEKDAYS_MONDAY = 0,
+    RTC_WEEKDAYS_TUESDAY,
+    RTC_WEEKDAYS_WEDNESDAY,
+    RTC_WEEKDAYS_THURSDAY,
+    RTC_WEEKDAYS_FRIDAY,
+    RTC_WEEKDAYS_SATURDAY,
+    RTC_WEEKDAYS_SUNDAY
+} rtcWeekdays_t;
+
+/**************************************************************************/
+/*!
+ * @brief     RTC months structure (months are one-based)
+ */
+/**************************************************************************/
+typedef enum rtcMonths_en
+{
+    RTC_MONTHS_JANUARY = 1,
+    RTC_MONTHS_FEBRUARY,
+    RTC_MONTHS_MARCH,
+    RTC_MONTHS_APRIL,
+    RTC_MONTHS_MAY,
+    RTC_MONTHS_JUNE,
+    RTC_MONTHS_JULY,
+    RTC_MONTHS_AUGUST,
+    RTC_MONTHS_SEPTEMBER,
+    RTC_MONTHS_OCTOBER,
+    RTC_MONTHS_NOVEMBER,
+    RTC_MONTHS_DECEMBER
+} rtcMonths_t;
+
+/**************************************************************************/
+/*!
+ * @brief     RTC time structure
+ * @warning:  To ensure that this structure always contains valid time in
+ *            the EPOCH range, do not assign field values directly. Please
+ *            call rtcAdd..., rtcCreateTime functions instead.
+ */
+/**************************************************************************/
+typedef struct rtcTime_st
+{
+    uint8_t seconds;
+    uint8_t minutes;
+    uint8_t hours;
+    uint8_t days;
+    uint8_t weekdays;   /**< Zero-based, first day of week = Monday (use rtcWeekdays_t) */
+    uint8_t months;     /**< One-based (use rtcMonths_t) */
+    uint8_t years;      /**< Years since 1900 */
+    int8_t timezone;    /**< Local time adjustment relative to GMT */
+} rtcTime_t;
+
+uint8_t   rtcDecToBCD ( uint8_t val );
+uint8_t   rtcBCDToDec ( uint8_t val );
+err_t   rtcCreateTime ( uint32_t year, rtcMonths_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, int8_t timezone, rtcTime_t *t );
+err_t   rtcCreateTimeFromEpoch ( uint32_t epochTime, rtcTime_t *time );
+err_t   rtcCreateTimeFromSecondsSince1980 ( uint32_t seconds, rtcTime_t *time );
+err_t   rtcAssignWeekday ( rtcTime_t *t );
+err_t   rtcAddSeconds ( rtcTime_t *t, int32_t s );
+err_t   rtcAddMinutes ( rtcTime_t *t, int32_t m );
+err_t   rtcAddHours ( rtcTime_t *t, int32_t h );
+err_t   rtcAddDays ( rtcTime_t *t, int32_t d );
+err_t   rtcAddMonths ( rtcTime_t *t, int32_t d );
+err_t   rtcAddYears ( rtcTime_t *t, int32_t y );
+err_t   rtcGetDifference ( rtcTime_t *t1, rtcTime_t *t2, int32_t *seconds );
+err_t   rtcGetWeekday ( uint32_t year, rtcMonths_t month, uint8_t day, rtcWeekdays_t *weekDay );
+err_t   rtcGetWeekNumber ( rtcTime_t *t, uint8_t *weekNumber );
+int32_t   rtcGetDaysInYear ( int32_t year );
+uint32_t  rtcGetEpochDate ( uint32_t year, rtcMonths_t month, uint8_t day );
+uint32_t  rtcToEpochTime ( rtcTime_t *t );
+uint32_t  rtcToSecondsSince1980 ( rtcTime_t *t );
+bool      rtcIsLeapYear ( int32_t year );
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/sensors/README.md b/reform2-lpc-fw/src/drivers/sensors/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..74737ef608891798ce0dcec30bf2a6440b965f25
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/README.md
@@ -0,0 +1,265 @@
+# Sensor Abstraction Layer #
+
+Many small embedded systems exist to collect data from sensors, analyse the data, and either take an appropriate action or send that sensor data to another system for processing.
+
+One of the many challenges of embedded systems design is the fact that parts you used today may be out of production tommorow, or system requirements may change and you may need to choose a different sensor down the road.
+
+Creating new drivers is a relatively easy task, but integrating them into existing systems is both error prone and time consuming since sensors rarely use the exact same units of measurement.
+
+By reducing all data to a single **sensors\_event\_t** 'type' and settling on specific, **standardised SI units** for each sensor family the same sensor types return values that are comparable with any other similar sensor.  This enables you to switch sensor models with very little impact on the rest of the system, which can help mitigate some of the risks and problems of sensor availability and code reuse.
+
+The sensor abstraction layer is also useful for data-logging and data-transmission.  The abstraction layer provides a single, well-understood and fixed-length record that can be recorded in your log files or transmitted to a target device without needing to know any HW-specific information.  Helper functions to that effect are provided in sensors.c, such as serialising sensor events and sensor details for transmission over the air or over a wire.
+
+## How Does it Work? ##
+
+There are two main typedefs and one enum defined in sensors.h that must be used by any sensor driver that you want to be compliant with the abstraction layer:
+
+**Sensor Types (sensors\_type\_t)**
+
+These pre-defined sensor types are used to properly handle the two related typedefs below, and allows us determine what types of units the sensor uses, etc.
+
+```
+/** Sensor types */
+typedef enum
+{
+  SENSOR_TYPE_ACCELEROMETER         = (1),
+  SENSOR_TYPE_MAGNETIC_FIELD        = (2),
+  SENSOR_TYPE_ORIENTATION           = (3),
+  SENSOR_TYPE_GYROSCOPE             = (4),
+  SENSOR_TYPE_LIGHT                 = (5),
+  SENSOR_TYPE_PRESSURE              = (6),
+  SENSOR_TYPE_PROXIMITY             = (8),
+  SENSOR_TYPE_GRAVITY               = (9),
+  SENSOR_TYPE_LINEAR_ACCELERATION   = (10),
+  SENSOR_TYPE_ROTATION_VECTOR       = (11),
+  SENSOR_TYPE_RELATIVE_HUMIDITY     = (12),
+  SENSOR_TYPE_AMBIENT_TEMPERATURE   = (13),
+  SENSOR_TYPE_VOLTAGE               = (15),
+  SENSOR_TYPE_CURRENT               = (16)
+} sensors_type_t;
+```
+
+**Sensor Details (sensor\_t)**
+
+This typedef describes the specific capabilities of this sensor, and allows us to know what sensor we are using beneath the abstraction layer.
+
+```
+/* Sensor details (40 bytes) */
+/** struct sensor_s is used to describe basic information about a specific sensor. */
+typedef struct
+{
+    char     name[12];
+    int32_t  version;
+    int32_t  sensor_id;
+    int32_t  type;
+    float    max_value;
+    float    min_value;
+    float    resolution;
+    int32_t  min_delay;
+} sensor_t;
+```
+
+The individual fields are intended to be used as follows:
+
+- **name**: The sensor name or ID, up to a maximum of twelve characters (ex. "MPL115A2")
+- **version**: The version of the sensor HW and the driver to allow us to differentiate versions of the board or driver
+- **sensor\_id**: A unique sensor identifier that is used to differentiate this specific sensor instance from any others that are present on the system or in the sensor network
+- **type**: The sensor type, based on **sensors\_type\_t** in sensors.h
+- **max\_value**: The maximum value that this sensor can return (in the appropriate SI unit)
+- **min\_value**: The minimum value that this sensor can return (in the appropriate SI unit)
+- **resolution**: The smallest difference between two values that this sensor can report (in the appropriate SI unit)
+- **min\_delay**: The minimum delay in microsecond between two sensor event, or '0' if there is no constant sensor rate
+
+**Sensor Data/Events (sensors\_event\_t)**
+
+This typedef is used to return sensor data from any sensor supported by the abstraction layer, using standard SI units and scales.
+
+```
+/* Sensor event (36 bytes) */
+/** struct sensor_event_s is used to provide a single sensor event in a common format. */
+typedef struct
+{
+    int32_t version;
+    int32_t sensor_id;
+    int32_t type;
+    int32_t reserved0;
+    int32_t timestamp;
+    union
+    {
+        float           data[4];
+        sensors_vec_t   acceleration;
+        sensors_vec_t   magnetic;
+        sensors_vec_t   orientation;
+        sensors_vec_t   gyro;
+        float           temperature;
+        float           distance;
+        float           light;
+        float           pressure;
+        float           relative_humidity;
+        float           current;
+        float           voltage;
+    };
+} sensors_event_t;
+```
+It includes the following fields:
+
+- **version**: Contain 'sizeof(sensors\_event\_t)' to identify which version of the API we're using in case this changes in the future
+- **sensor\_id**: A unique sensor identifier that is used to differentiate this specific sensor instance from any others that are present on the system or in the sensor network (must match the sensor\_id value in the corresponding sensor\_t enum above!)
+- **type**: the sensor type, based on **sensors\_type\_t** in sensors.h
+- **timestamp**: time in milliseconds when the sensor value was read
+- **data[4]**: An array of four 32-bit values that allows us to encapsulate any type of sensor data via a simple union (further described below)
+
+**Standardised SI values for sensors\_event\_t**
+
+A key part of the abstraction layer is the standardisation of values on SI units of a particular scale, which is accomplished via the data[4] union in sensors\_event\_t above.  This 16 byte union includes fields for each main sensor type, and uses the following SI units and scales:
+
+- **acceleration**: values are in **meter per second per second** (m/s^2)
+- **magnetic**: values are in **micro-Tesla** (uT)
+- **orientation**: values are in **degrees**
+- **gyro**: values are in **rad/s**
+- **temperature**: values in **degrees centigrade** (Celsius) 
+- **distance**: values are in **centimeters**
+- **light**: values are in **SI lux** units
+- **pressure**: values are in **hectopascal** (hPa)
+- **relative\_humidity**: values are in **percent**
+- **current**: values are in **milliamps** (mA)
+- **voltage**: values are in **volts** (V)
+
+## Adding sensors.c Support to an Existing Sensor Driver ##
+
+Sensor drivers should still be written in the traditional way, using efficient fixed-point math and the native units of the sensor.  
+
+The sensor abstraction layer should sit on top of these efficient, light-weight sensor drivers, and can be made to work with any existing sensor driver by simply adding two new functions on top of it:
+
+**Function One: Get Sensor Details**
+
+You need to create a function that populates a **sensor\_t** object, and that accurately describes the capabilities of this sensor.  An example of how to do this (for the l3gd20 gyroscope) is shown below:
+
+```
+/**************************************************************************/
+/*!
+    @brief  Provides the sensor_t data for this sensor
+*/
+/**************************************************************************/
+void l3gd20GetSensor(sensor_t *sensor)
+{
+  memset(sensor, 0, sizeof(sensor_t));
+
+  /* Insert the sensor name in the fixed length char array */
+  strncpy (sensor->name, "L3GD20", sizeof(sensor->name) - 1);
+  sensor->name[sizeof(sensor->name)- 1] = 0;
+  sensor->version     = 1;
+  sensor->sensor_id   = _l3gd20SensorID;
+  sensor->type        = SENSOR_TYPE_GYROSCOPE;
+  sensor->min_delay   = 0;
+
+  /* We need to do some calculations to determine resolution and maxRange in rad/s */
+  sensor->max_value   = _l3gd20MeasurementRange * SENSORS_DPS_TO_RADS;
+  sensor->min_value   = 0;
+  switch (_l3gd20MeasurementRange)
+  {
+    case 2000:
+      sensor->resolution  = (_l3gd20MeasurementRange / 32767.0F) * L3GD20_SENSITIVITY_2000DPS * SENSORS_DPS_TO_RADS;
+      break;
+    case 500:
+      sensor->resolution  = (_l3gd20MeasurementRange / 32767.0F) * L3GD20_SENSITIVITY_500DPS * SENSORS_DPS_TO_RADS;
+      break;
+    case 250:
+    default:
+      sensor->resolution  = (_l3gd20MeasurementRange / 32767.0F) * L3GD20_SENSITIVITY_250DPS * SENSORS_DPS_TO_RADS;
+      break;
+  }
+}
+```
+
+**Function Two: Get Sensor Event**
+
+The second function that is required must populate a **sensors\_event\_t** object, containing the sensor event data with the values converted to the appropriate SI units and scale.
+
+Another example using the l3gd20 gyroscope can be seen below, where the raw DPS (degrees per second) values provided by the sensor are converted to the rad/s units defined by the sensor abstraction layer, including compensation for the gain settings on the gyroscope:
+
+```
+/**************************************************************************/
+/*!
+    @brief  Reads the sensor and returns the data as a sensors_event_t
+*/
+/**************************************************************************/
+error_t l3gd20GetSensorEvent(sensors_event_t *event)
+{
+  l3gd20Data_t data;
+
+  /* Clear the event */
+  memset(event, 0, sizeof(sensors_event_t));
+
+  event->version   = sizeof(sensors_event_t);
+  event->sensor_id = _l3gd20SensorID;
+  event->type      = SENSOR_TYPE_GYROSCOPE;
+  event->timestamp = delayGetTicks();
+
+  /* Retrieve values from the sensor */
+  ASSERT_STATUS(l3gd20Poll(&data));
+
+  /* The L3GD20 returns degrees per second, adjusted by sensitivity which
+   * is shown as mdps/digit in the datasheet.  To convert this to proper
+   * degrees/s multiply by the appropriate sensitivity value and then
+   * convert it to the rad/s value that sensors_event_t is expecting. */
+  switch (_l3gd20MeasurementRange)
+  {
+    case (2000):
+      event->gyro.x = data.x * L3GD20_SENSITIVITY_2000DPS * SENSORS_DPS_TO_RADS;
+      event->gyro.y = data.y * L3GD20_SENSITIVITY_2000DPS * SENSORS_DPS_TO_RADS;
+      event->gyro.z = data.z * L3GD20_SENSITIVITY_2000DPS * SENSORS_DPS_TO_RADS;
+      break;
+    case (500):
+      event->gyro.x = data.x * L3GD20_SENSITIVITY_500DPS * SENSORS_DPS_TO_RADS;
+      event->gyro.y = data.y * L3GD20_SENSITIVITY_500DPS * SENSORS_DPS_TO_RADS;
+      event->gyro.z = data.z * L3GD20_SENSITIVITY_500DPS * SENSORS_DPS_TO_RADS;
+      break;
+    case (250):
+    default:
+      event->gyro.x = data.x * L3GD20_SENSITIVITY_250DPS * SENSORS_DPS_TO_RADS;
+      event->gyro.y = data.y * L3GD20_SENSITIVITY_250DPS * SENSORS_DPS_TO_RADS;
+      event->gyro.z = data.z * L3GD20_SENSITIVITY_250DPS * SENSORS_DPS_TO_RADS;
+      break;
+  }
+
+  return ERROR_NONE;
+}
+```
+
+## The Abstraction Layer in Practice ##
+
+Using the sensor abstraction layer is relatively easy once a compliant driver has been created.  
+
+Every compliant sensor can now be read using a single, well-known 'type' (sensors\_event\_t), and there is a standardised way of interrogating a sensor about its specific capabilities (via sensor\_t).
+
+An example of reading the l3gd20 gyroscope above can be seen below:
+
+```
+error_t error;
+sensors_event_t event;
+
+error = l3gd20GetSensorEvent(&event);
+if (!error)
+{
+  /* Check the X value */
+  if (event.gyro.x > 0.5F)
+  {
+    // Do something
+  }
+}
+```
+
+Similarly, we can get the basic technical capabilities of this sensor with the following code:
+
+```
+sensor_t sensor;
+
+// Get the sensor_t data
+l3gd20GetSensor(&sensor);
+
+// Display the resolution of this sensor
+printf("Gyroscope: %s %s", sensor.name, CFG_PRINTF_NEWLINE);
+printf("Resolution: %f rad/s %s", sensor.resolution, CFG_PRINTF_NEWLINE); 
+
+```
diff --git a/reform2-lpc-fw/src/drivers/sensors/accelerometers/accelerometers.c b/reform2-lpc-fw/src/drivers/sensors/accelerometers/accelerometers.c
new file mode 100644
index 0000000000000000000000000000000000000000..fdbc6026ab47900e9c49cbcdac43bc879d925eb7
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/accelerometers/accelerometers.c
@@ -0,0 +1,161 @@
+/**************************************************************************/
+/*!
+    @file     accelerometers.c
+    @author   Nguyen Quang Huy, Nguyen Thien Tin, K. Townsend
+    @ingroup  Sensors
+
+    @brief    Helper functions for accelerometers
+
+    @code
+
+    err_t error;
+    sensors_event_t event;
+    sensors_vec_t orientation;
+
+    // Initialise the accelerometer
+    error = lsm303accelInit();
+
+    while (1)
+    {
+      if (!error)
+      {
+        // Get sensor data
+        error = lsm303accelGetSensorEvent(&event);
+        if (!error)
+        {
+          // Calculate pitch and roll in degrees, placing the calculated
+          // values into the .pitch and .roll of our sensors_vec_t variable
+          accelGetOrientation(&event, &orientation);
+
+          // Display the accel + orientation values
+          printf("X: %f, Y: %f, Z: %f, Pitch: %d, Roll: %d\r\n",
+            event.acceleration.x,
+            event.acceleration.y,
+            event.acceleration.z,
+            (int)orientation.pitch,
+            (int)orientation.roll);
+
+          // Wait a bit before the next sample
+          delay(100);
+        }
+      }
+    }
+
+    @endcode
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+#include "accelerometers.h"
+#include "core/delay/delay.h"
+#include <math.h>
+
+/**************************************************************************/
+/*!
+    @brief  Populates the .pitch/.roll fields in the sensors_vec_t struct
+            with the right angular data (in degree)
+
+    @param  event         The sensors_event_t variable containing the
+                          data from the accelerometer
+    @param  orientation   The sensors_vec_t object that will have it's
+                          .pitch and .roll fields populated
+
+    @code
+
+    err_t error;
+    sensors_event_t event;
+    sensors_vec_t orientation;
+
+    // Get some sensor data and store it in our event variable
+    error = lsm303accelGetSensorEvent(&event);
+    if (!error)
+    {
+      // Calculate pitch and roll in degrees, placing the calculated
+      // values into the .pitch and .roll of our sensors_vec_t variable
+      accelGetOrientation(&event, &orientation);
+
+      // Display the accel + orientation values
+      printf("X: %f, Y: %f, Z: %f, Pitch: %d, Roll: %d\r\n",
+        event.acceleration.x,
+        event.acceleration.y,
+        event.acceleration.z,
+        (int)orientation.pitch,
+        (int)orientation.roll);
+    }
+
+    @endcode
+*/
+/**************************************************************************/
+void accelGetOrientation(sensors_event_t *event, sensors_vec_t *orientation)
+{
+  float t_pitch, t_roll;
+  float const PI = 3.14159265F;
+
+  /* roll: Rotation around the longitudinal axis (the plane body, 'X axis'). -180<=roll<=180  */
+  /* roll is positive and increasing when moving downward                                     */
+  /*                                                                                          */
+  /*                                 y                                                        */
+  /*             roll = atan(-----------------)                                               */
+  /*                          sqrt(x^2 + z^2)                                                 */
+  /* where:  x, y, z are returned value from accelerometer sensor                             */
+
+  t_roll = event->acceleration.x * event->acceleration.x + event->acceleration.z * event->acceleration.z;
+  orientation->roll = (float)atan2(event->acceleration.y, sqrt(t_roll)) * 180 / PI;
+
+  /* scale the angle of Roll in the range [-180, 180] */
+  if (event->acceleration.z < 0)
+  {
+    if (event->acceleration.y > 0)
+      orientation->roll = 180 - orientation->roll;
+    else
+      orientation->roll = -180 - orientation->roll ;
+  }
+
+  /* pitch: Rotation around the lateral axis (the wing span, 'Y axis'). -180<=pitch<=180)     */
+  /* pitch is positive and increasing when moving upwards                                     */
+  /*                                                                                          */
+  /*                                 x                                                        */
+  /*             roll = atan(-----------------)                                               */
+  /*                          sqrt(y^2 + z^2)                                                 */
+  /* where:  x, y, z are returned value from accelerometer sensor                             */
+
+  t_pitch = event->acceleration.y * event->acceleration.y + event->acceleration.z * event->acceleration.z;
+  orientation->pitch = (float)atan2(event->acceleration.x, sqrt(t_pitch)) * 180 / PI;
+
+  /* scale the angle of Pitch in the range [-180, 180] */
+  if (event->acceleration.z < 0)
+  {
+    if (event->acceleration.x > 0)
+      orientation->pitch = 180 - orientation->pitch;
+    else
+      orientation->pitch = -180 - orientation->pitch ;
+  }
+}
diff --git a/reform2-lpc-fw/src/drivers/sensors/accelerometers/accelerometers.h b/reform2-lpc-fw/src/drivers/sensors/accelerometers/accelerometers.h
new file mode 100644
index 0000000000000000000000000000000000000000..fbd02bad0feb1f2a2cc4d86c94f77c355e5c789d
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/accelerometers/accelerometers.h
@@ -0,0 +1,54 @@
+/**************************************************************************/
+/*!
+    @file     accelerometers.h
+    @author   Nguyen Quang Huy, Nguyen Thien Tin
+    @ingroup  Sensors
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _ACCELEROMETERS_H_
+#define _ACCELEROMETERS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "drivers/sensors/sensors.h"
+
+void accelGetOrientation(sensors_event_t *event, sensors_vec_t *orientation);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _ACCELEROMETERS_H_
+
diff --git a/reform2-lpc-fw/src/drivers/sensors/accelerometers/adxl345.c b/reform2-lpc-fw/src/drivers/sensors/accelerometers/adxl345.c
new file mode 100644
index 0000000000000000000000000000000000000000..78b96d0d8a0c7ed088dbcb2598efc29009fa6b4f
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/accelerometers/adxl345.c
@@ -0,0 +1,277 @@
+/**************************************************************************/
+/*!
+    @file     adxl345.c
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @brief    Driver for Analog Devices ADXL345 Accelerometer
+
+    @details
+
+    The ADXL345 is a digital accelerometer with 13-bit resolution, capable
+    of measuring up to +/-16g.  This driver communicate using I2C.
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+#include "adxl345.h"
+#include "core/delay/delay.h"
+#include <string.h>
+
+#define ADXL345_MG2G_MULTIPLIER (0.004)  // 4mg per lsb
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+static bool    _adxl345Initialised = false;
+static int32_t _adxl345SensorID = 0;
+
+/**************************************************************************/
+/*!
+    @brief  Sends a single command byte over I2C
+*/
+/**************************************************************************/
+static err_t adxl345Write8 (uint8_t reg, uint8_t value)
+{
+  I2CWriteLength = 3;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = ADXL345_ADDRESS;
+  I2CMasterBuffer[1] = reg;
+  I2CMasterBuffer[2] = value;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads a 16 bit values over I2C
+*/
+/**************************************************************************/
+static err_t adxl345Read8(uint8_t reg, uint8_t *value)
+{
+  I2CWriteLength = 2;
+  I2CReadLength = 1;
+  I2CMasterBuffer[0] = ADXL345_ADDRESS;
+  I2CMasterBuffer[1] = reg;
+  /* Append address w/read bit */
+  I2CMasterBuffer[2] = ADXL345_ADDRESS | ADXL345_READBIT;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  /* Shift values to create properly formed integer */
+  *value = I2CSlaveBuffer[0];
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Initialises the I2C block
+*/
+/**************************************************************************/
+err_t adxl345Init(void)
+{
+  uint8_t devid = 0x00;
+
+  /* Initialise I2C */
+  i2cInit(I2CMASTER);
+
+  /* Ping the I2C device first to see if it exists! */
+  ASSERT(i2cCheckAddress(ADXL345_ADDRESS), ERROR_I2C_DEVICENOTFOUND);
+
+  /* Check device ID register to see if everything is properly connected */
+  ASSERT_STATUS(adxl345Read8(ADXL345_REG_DEVID, &devid));
+  if (devid != 0xE5)
+  {
+    return ERROR_I2C_DEVICENOTFOUND;
+  }
+
+  /* Enable measurements */
+  ASSERT_STATUS(adxl345Write8(ADXL345_REG_POWER_CTL, 0x08));
+
+  _adxl345Initialised = true;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the latest X/Y/Z values
+*/
+/**************************************************************************/
+err_t adxl345GetXYZ(int16_t *x, int16_t *y, int16_t *z)
+{
+  int32_t i2cState;
+
+  if (!_adxl345Initialised)
+  {
+    ASSERT_STATUS(adxl345Init());
+  }
+
+  I2CWriteLength = 2;
+  I2CReadLength = 6;
+  I2CMasterBuffer[0] = ADXL345_ADDRESS;
+  I2CMasterBuffer[1] = ADXL345_REG_DATAX0;
+  I2CMasterBuffer[2] = ADXL345_ADDRESS | ADXL345_READBIT;
+  i2cState = i2cEngine();
+
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cState);
+
+  /* Shift values to create properly formed integer */
+  *x = (I2CSlaveBuffer[1] << 8) | (I2CSlaveBuffer[0]);
+  *y = (I2CSlaveBuffer[3] << 8) | (I2CSlaveBuffer[2]);
+  *z = (I2CSlaveBuffer[5] << 8) | (I2CSlaveBuffer[4]);
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the g range for the accelerometer
+*/
+/**************************************************************************/
+err_t adxl345SetRange(adxl345_range_t range)
+{
+  uint8_t format;
+
+  /* Red the data format register to preserve bits */
+  ASSERT_STATUS(adxl345Read8(ADXL345_REG_DATA_FORMAT, &format));
+
+  /* Update the data rate */
+  format &= ~0x0F;
+  format |= range;
+
+  /* Make sure that the FULL-RES bit is enabled for range scaling */
+  format |= 0x08;
+
+  /* Write the register back to the IC */
+  ASSERT_STATUS(adxl345Write8(ADXL345_REG_DATA_FORMAT, format));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the g range for the accelerometer
+*/
+/**************************************************************************/
+err_t adxl345GetRange(adxl345_range_t *range)
+{
+  uint8_t results;
+  ASSERT_STATUS(adxl345Read8(ADXL345_REG_DATA_FORMAT, &results));
+  *range = (adxl345_range_t)(results & 0x03);
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the data rate for the ADXL345 (controls power consumption)
+*/
+/**************************************************************************/
+err_t adxl345SetDataRate(adxl345_dataRate_t dataRate)
+{
+  /* Note: The LOW_POWER bits are currently ignored and we always keep
+     the device in 'normal' mode */
+  ASSERT_STATUS(adxl345Write8(ADXL345_REG_BW_RATE, dataRate));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the g range for the accelerometer
+*/
+/**************************************************************************/
+err_t adxl345GetDataRate(adxl345_dataRate_t *dataRate)
+{
+  uint8_t results;
+  ASSERT_STATUS(adxl345Read8(ADXL345_REG_BW_RATE, &results));
+  *dataRate = (adxl345_dataRate_t)(results & 0x0F);
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Provides the sensor_t data for this sensor
+*/
+/**************************************************************************/
+void adxl345GetSensor(sensor_t *sensor)
+{
+  /* Clear the sensor_t object */
+  memset(sensor, 0, sizeof(sensor_t));
+
+  /* Insert the sensor name in the fixed length char array */
+  strncpy (sensor->name, "ADXL345", sizeof(sensor->name) - 1);
+  sensor->name[sizeof(sensor->name)- 1] = 0;
+  sensor->version     = 1;
+  sensor->sensor_id   = _adxl345SensorID;
+  sensor->type        = SENSOR_TYPE_ACCELEROMETER;
+  sensor->min_delay   = 0;
+  sensor->max_value   = -156.9064F; /* -16g = 156.9064 m/s^2  */
+  sensor->min_value   = 156.9064F;  /*  16g = 156.9064 m/s^2  */
+  sensor->resolution  = 0.03923F;   /*  4mg = 0.0392266 m/s^2 */
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the sensor and returns the data as a sensors_event_t
+*/
+/**************************************************************************/
+err_t adxl345GetSensorEvent(sensors_event_t *event)
+{
+  int16_t x, y, z;
+
+  /* Clear the event */
+  memset(event, 0, sizeof(sensors_event_t));
+
+  event->version   = sizeof(sensors_event_t);
+  event->sensor_id = _adxl345SensorID;
+  event->type      = SENSOR_TYPE_ACCELEROMETER;
+  event->timestamp = delayGetTicks();
+
+  /* Retrieve values from the sensor */
+  ASSERT_STATUS(adxl345GetXYZ(&x, &y, &z));
+
+  /* The ADXL345 returns a raw value where each lsb represents 4mg.  To
+   * convert this to a normal g value, multiply by 0.004 and then convert
+   * it to the m/s^2 value that sensors_event_t is expecting. */
+  event->acceleration.x = x * ADXL345_MG2G_MULTIPLIER * SENSORS_GRAVITY_STANDARD;
+  event->acceleration.y = y * ADXL345_MG2G_MULTIPLIER * SENSORS_GRAVITY_STANDARD;
+  event->acceleration.z = z * ADXL345_MG2G_MULTIPLIER * SENSORS_GRAVITY_STANDARD;
+
+  return ERROR_NONE;
+}
diff --git a/reform2-lpc-fw/src/drivers/sensors/accelerometers/adxl345.h b/reform2-lpc-fw/src/drivers/sensors/accelerometers/adxl345.h
new file mode 100644
index 0000000000000000000000000000000000000000..ad2f3ec75f45ec97b7ee5f608c2baf94d2a7eebd
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/accelerometers/adxl345.h
@@ -0,0 +1,133 @@
+/**************************************************************************/
+/*!
+    @file     adxl345.h
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _ADXL345_H_
+#define _ADXL345_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "core/i2c/i2c.h"
+#include "drivers/sensors/sensors.h"
+
+/*=========================================================================
+    I2C ADDRESS/BITS
+    -----------------------------------------------------------------------*/
+    #define ADXL345_ADDRESS                 (0x53<<1) // Assumes ALT address pin low ... use 0x3A with ALT high
+    #define ADXL345_READBIT                 (0x01)
+/*=========================================================================*/
+
+/*=========================================================================
+    REGISTERS
+    -----------------------------------------------------------------------*/
+    #define ADXL345_REG_DEVID               (0x00)    // Device ID
+    #define ADXL345_REG_THRESH_TAP          (0x1D)    // Tap threshold
+    #define ADXL345_REG_OFSX                (0x1E)    // X-axis offset
+    #define ADXL345_REG_OFSY                (0x1F)    // Y-axis offset
+    #define ADXL345_REG_OFSZ                (0x20)    // Z-axis offset
+    #define ADXL345_REG_DUR                 (0x21)    // Tap duration
+    #define ADXL345_REG_LATENT              (0x22)    // Tap latency
+    #define ADXL345_REG_WINDOW              (0x23)    // Tap window
+    #define ADXL345_REG_THRESH_ACT          (0x24)    // Activity threshold
+    #define ADXL345_REG_THRESH_INACT        (0x25)    // Inactivity threshold
+    #define ADXL345_REG_TIME_INACT          (0x26)    // Inactivity time
+    #define ADXL345_REG_ACT_INACT_CTL       (0x27)    // Axis enable control for activity and inactivity detection
+    #define ADXL345_REG_THRESH_FF           (0x28)    // Free-fall threshold
+    #define ADXL345_REG_TIME_FF             (0x29)    // Free-fall time
+    #define ADXL345_REG_TAP_AXES            (0x2A)    // Axis control for single/double tap
+    #define ADXL345_REG_ACT_TAP_STATUS      (0x2B)    // Source for single/double tap
+    #define ADXL345_REG_BW_RATE             (0x2C)    // Data rate and power mode control
+    #define ADXL345_REG_POWER_CTL           (0x2D)    // Power-saving features control
+    #define ADXL345_REG_INT_ENABLE          (0x2E)    // Interrupt enable control
+    #define ADXL345_REG_INT_MAP             (0x2F)    // Interrupt mapping control
+    #define ADXL345_REG_INT_SOURCE          (0x30)    // Source of interrupts
+    #define ADXL345_REG_DATA_FORMAT         (0x31)    // Data format control
+    #define ADXL345_REG_DATAX0              (0x32)    // X-axis data 0
+    #define ADXL345_REG_DATAX1              (0x33)    // X-axis data 1
+    #define ADXL345_REG_DATAY0              (0x34)    // Y-axis data 0
+    #define ADXL345_REG_DATAY1              (0x35)    // Y-axis data 1
+    #define ADXL345_REG_DATAZ0              (0x36)    // Z-axis data 0
+    #define ADXL345_REG_DATAZ1              (0x37)    // Z-axis data 1
+    #define ADXL345_REG_FIFO_CTL            (0x38)    // FIFO control
+    #define ADXL345_REG_FIFO_STATUS         (0x39)    // FIFO status
+/*=========================================================================*/
+
+/* Used with register 0x2C (ADXL345_REG_BW_RATE) to set bandwidth */
+typedef enum
+{
+  ADXL345_DATARATE_3200_HZ    = BIN8(1111), // 1600Hz Bandwidth   140µA IDD
+  ADXL345_DATARATE_1600_HZ    = BIN8(1110), //  800Hz Bandwidth    90µA IDD
+  ADXL345_DATARATE_800_HZ     = BIN8(1101), //  400Hz Bandwidth   140µA IDD
+  ADXL345_DATARATE_400_HZ     = BIN8(1100), //  200Hz Bandwidth   140µA IDD
+  ADXL345_DATARATE_200_HZ     = BIN8(1011), //  100Hz Bandwidth   140µA IDD
+  ADXL345_DATARATE_100_HZ     = BIN8(1010), //   50Hz Bandwidth   140µA IDD (Default)
+  ADXL345_DATARATE_50_HZ      = BIN8(1001), //   25Hz Bandwidth    90µA IDD
+  ADXL345_DATARATE_25_HZ      = BIN8(1000), // 12.5Hz Bandwidth    60µA IDD
+  ADXL345_DATARATE_12_5_HZ    = BIN8(0111), // 6.25Hz Bandwidth    50µA IDD
+  ADXL345_DATARATE_6_25HZ     = BIN8(0110), // 3.13Hz Bandwidth    45µA IDD
+  ADXL345_DATARATE_3_13_HZ    = BIN8(0101), // 1.56Hz Bandwidth    40µA IDD
+  ADXL345_DATARATE_1_56_HZ    = BIN8(0100), // 0.78Hz Bandwidth    34µA IDD
+  ADXL345_DATARATE_0_78_HZ    = BIN8(0011), // 0.39Hz Bandwidth    23µA IDD
+  ADXL345_DATARATE_0_39_HZ    = BIN8(0010), // 0.20Hz Bandwidth    23µA IDD
+  ADXL345_DATARATE_0_20_HZ    = BIN8(0001), // 0.10Hz Bandwidth    23µA IDD
+  ADXL345_DATARATE_0_10_HZ    = BIN8(0000)  // 0.05Hz Bandwidth    23µA IDD
+} adxl345_dataRate_t;
+
+/* Used with register 0x31 (ADXL345_REG_DATA_FORMAT) to set g range */
+typedef enum
+{
+  ADXL345_RANGE_16_G          = 0x03,   // +/- 16g
+  ADXL345_RANGE_8_G           = 0x02,   // +/- 8g
+  ADXL345_RANGE_4_G           = 0x01,   // +/- 4g
+  ADXL345_RANGE_2_G           = 0x00    // +/- 2g  (Default)
+} adxl345_range_t;
+
+err_t adxl345Init(void);
+err_t adxl345GetXYZ(int16_t *x, int16_t *y, int16_t *z);
+err_t adxl345SetRange(adxl345_range_t range);
+err_t adxl345GetRange(adxl345_range_t *range);
+err_t adxl345SetDataRate(adxl345_dataRate_t dataRate);
+err_t adxl345GetDataRate(adxl345_dataRate_t *dataRate);
+void    adxl345GetSensor(sensor_t *sensor);
+err_t adxl345GetSensorEvent(sensors_event_t *event);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/sensors/accelerometers/lis3dh.c b/reform2-lpc-fw/src/drivers/sensors/accelerometers/lis3dh.c
new file mode 100644
index 0000000000000000000000000000000000000000..ae02ea94d5cec59a3b716db691823e3dea58a27b
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/accelerometers/lis3dh.c
@@ -0,0 +1,285 @@
+/**************************************************************************/
+/*!
+    @file     lis3dh.c
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @brief    Driver for the ST LIS3DH I2C/SPI Accelerometer
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+#include "lis3dh.h"
+#include "core/delay/delay.h"
+#include <string.h>
+
+#define LIS3DH_SENSITIVITY_2G  (0.001F)
+#define LIS3DH_SENSITIVITY_4G  (0.002F)
+#define LIS3DH_SENSITIVITY_8G  (0.004F)
+#define LIS3DH_SENSITIVITY_16G (0.012F)
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+static bool    _lis3dhInitialised = false;
+static uint8_t _lis3dhMeasurementRange = 2;        /* +/-2, 4, 8 or 16 g */
+static int32_t _lis3dhSensorID = 0;
+
+/**************************************************************************/
+/*!
+    @brief  Writes an unsigned 8 bit values over I2C
+*/
+/**************************************************************************/
+err_t lis3dhWrite8 (uint8_t reg, uint8_t value)
+{
+  I2CWriteLength = 3;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = LIS3DH_ADDRESS;
+  I2CMasterBuffer[1] = reg;
+  I2CMasterBuffer[2] = (value);
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads an unsigned 8 bit values over I2C
+*/
+/**************************************************************************/
+err_t lis3dhRead8(uint8_t reg, uint8_t *value)
+{
+  /* Write transaction */
+  I2CWriteLength = 2;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = LIS3DH_ADDRESS;
+  I2CMasterBuffer[1] = reg;
+  i2cEngine();
+
+  /* Read transaction */
+  I2CWriteLength = 0;
+  I2CReadLength = 1;
+  I2CMasterBuffer[0] = LIS3DH_ADDRESS | LIS3DH_READBIT;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  /* Send received value back to the caller */
+  *value = I2CSlaveBuffer[0];
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads three signed 16 bit values over I2C
+*/
+/**************************************************************************/
+err_t lis3dhRead48(uint8_t reg, int16_t *x, int16_t *y, int16_t *z)
+{
+  /* Write transaction */
+  I2CWriteLength = 2;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = LIS3DH_ADDRESS;
+  I2CMasterBuffer[1] = reg | (0x80);
+  i2cEngine();
+
+  /* Read transaction */
+  I2CWriteLength = 0;
+  I2CReadLength = 6;
+  I2CMasterBuffer[0] = LIS3DH_ADDRESS | LIS3DH_READBIT;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  /* Shift values to create properly formed integer (low byte first) */
+  *x = (int16_t)(I2CSlaveBuffer[1] << 8 | I2CSlaveBuffer[0]);
+  *y = (int16_t)(I2CSlaveBuffer[3] << 8 | I2CSlaveBuffer[2]);
+  *z = (int16_t)(I2CSlaveBuffer[5] << 8 | I2CSlaveBuffer[4]);
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Initialises the I2C block
+*/
+/**************************************************************************/
+err_t lis3dhInit(void)
+{
+  /* Initialise I2C */
+  i2cInit(I2CMASTER);
+
+  /* Ping the I2C device first to see if it exists! */
+  ASSERT(i2cCheckAddress(LIS3DH_ADDRESS), ERROR_I2C_DEVICENOTFOUND);
+
+  /* Set data rate and power mode, and enable X/Y/Z */
+  ASSERT_STATUS(lis3dhWrite8(LIS3DH_REGISTER_CTRL_REG1,
+    LIS3DH_CTRL_REG1_DATARATE_50HZ |    /* Normal mode, 50Hz */
+    LIS3DH_CTRL_REG1_XYZEN));           /* Enable X, Y and Z */
+
+  /* Enable block update and set range to +/-2G */
+  ASSERT_STATUS(lis3dhWrite8(LIS3DH_REGISTER_CTRL_REG4,
+    LIS3DH_CTRL_REG4_BLOCKDATAUPDATE |  /* Enable block update */
+    LIS3DH_CTRL_REG4_SCALE_2G));        /* +/-2G measurement range */
+
+  /* Make sure the measurement range is updated here if you change it */
+  _lis3dhMeasurementRange = 2;
+
+  _lis3dhInitialised = true;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Polls the device for a new X/Y/Z reading
+*/
+/**************************************************************************/
+err_t lis3dhPoll(lis3dhData_t* data)
+{
+  uint8_t timeout = 0;
+  uint8_t buffer = 0x00;
+
+  if (!_lis3dhInitialised)
+  {
+    ASSERT_STATUS(lis3dhInit());
+  }
+
+  /* Check the status register until a new X/Y/Z sample is ready */
+  do
+  {
+    ASSERT_STATUS(lis3dhRead8(LIS3DH_REGISTER_STATUS_REG_AUX, &buffer));
+    ASSERT(timeout++ <= LIS3DH_POLL_TIMEOUT, ERROR_OPERATIONTIMEDOUT);
+  } while (!(buffer & LIS3DH_STATUS_REG_ZYXDA));
+
+  // /* Check if the data is new or not (data has changed) */
+  // if (buffer & LIS3DH_STATUS_REG_ZYXOR)
+  // {
+  //   /* New data is available */
+  // }
+
+  /* For now, always read data even if it hasn't changed */
+  ASSERT_STATUS(lis3dhRead48(LIS3DH_REGISTER_OUT_X_L, &(data->x), &(data->y), &(data->z)));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Provides the sensor_t data for this sensor
+*/
+/**************************************************************************/
+void lis3dhGetSensor(sensor_t *sensor)
+{
+  /* Clear the sensor_t object */
+  memset(sensor, 0, sizeof(sensor_t));
+
+  /* Insert the sensor name in the fixed length char array */
+  strncpy (sensor->name, "LIS3DH", sizeof(sensor->name) - 1);
+  sensor->name[sizeof(sensor->name)- 1] = 0;
+  sensor->version     = 1;
+  sensor->sensor_id   = _lis3dhSensorID;
+  sensor->type        = SENSOR_TYPE_ACCELEROMETER;
+  sensor->min_delay   = 0;
+
+  /* We need to do some calculations to determine resolution and maxRange in m/s^2 */
+  sensor->max_value   = _lis3dhMeasurementRange * SENSORS_GRAVITY_STANDARD;
+  sensor->min_value   = 0;
+  switch (_lis3dhMeasurementRange)
+  {
+    case 16:
+      sensor->resolution  = (_lis3dhMeasurementRange / 32767.0F) * LIS3DH_SENSITIVITY_16G * SENSORS_GRAVITY_STANDARD;
+      break;
+    case 8:
+      sensor->resolution  = (_lis3dhMeasurementRange / 32767.0F) * LIS3DH_SENSITIVITY_8G * SENSORS_GRAVITY_STANDARD;
+      break;
+    case 4:
+      sensor->resolution  = (_lis3dhMeasurementRange / 32767.0F) * LIS3DH_SENSITIVITY_4G * SENSORS_GRAVITY_STANDARD;
+      break;
+    case 2:
+    default:
+      sensor->resolution  = (_lis3dhMeasurementRange / 32767.0F) * LIS3DH_SENSITIVITY_2G * SENSORS_GRAVITY_STANDARD;
+      break;
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the sensor and returns the data as a sensors_event_t
+*/
+/**************************************************************************/
+err_t lis3dhGetSensorEvent(sensors_event_t *event)
+{
+  lis3dhData_t data;
+
+  /* Clear the event */
+  memset(event, 0, sizeof(sensors_event_t));
+
+  event->version   = sizeof(sensors_event_t);
+  event->sensor_id = _lis3dhSensorID;
+  event->type      = SENSOR_TYPE_ACCELEROMETER;
+  event->timestamp = delayGetTicks();
+
+  /* Retrieve values from the sensor */
+  ASSERT_STATUS(lis3dhPoll(&data));
+
+  /* The LIS3DH returns a raw g value which needs to be adjusted by
+   * sensitivity which is shown as mg/digit in the datasheet.  To convert
+   * this to a normal g value, multiply by the appropriate sensitivity value
+   * and then convert it to the m/s^2 value that sensors_event_t is expecting. */
+  switch (_lis3dhMeasurementRange)
+  {
+    case 16:
+      event->acceleration.x = data.x * LIS3DH_SENSITIVITY_16G * SENSORS_GRAVITY_STANDARD;
+      event->acceleration.y = data.y * LIS3DH_SENSITIVITY_16G * SENSORS_GRAVITY_STANDARD;
+      event->acceleration.z = data.z * LIS3DH_SENSITIVITY_16G * SENSORS_GRAVITY_STANDARD;
+      break;
+    case 8:
+      event->acceleration.x = data.x * LIS3DH_SENSITIVITY_8G * SENSORS_GRAVITY_STANDARD;
+      event->acceleration.y = data.y * LIS3DH_SENSITIVITY_8G * SENSORS_GRAVITY_STANDARD;
+      event->acceleration.z = data.z * LIS3DH_SENSITIVITY_8G * SENSORS_GRAVITY_STANDARD;
+      break;
+    case 4:
+      event->acceleration.x = data.x * LIS3DH_SENSITIVITY_4G * SENSORS_GRAVITY_STANDARD;
+      event->acceleration.y = data.y * LIS3DH_SENSITIVITY_4G * SENSORS_GRAVITY_STANDARD;
+      event->acceleration.z = data.z * LIS3DH_SENSITIVITY_4G * SENSORS_GRAVITY_STANDARD;
+      break;
+    case 2:
+    default:
+      event->acceleration.x = data.x * LIS3DH_SENSITIVITY_2G * SENSORS_GRAVITY_STANDARD;
+      event->acceleration.y = data.y * LIS3DH_SENSITIVITY_2G * SENSORS_GRAVITY_STANDARD;
+      event->acceleration.z = data.z * LIS3DH_SENSITIVITY_2G * SENSORS_GRAVITY_STANDARD;
+      break;
+  }
+
+  return ERROR_NONE;
+}
diff --git a/reform2-lpc-fw/src/drivers/sensors/accelerometers/lis3dh.h b/reform2-lpc-fw/src/drivers/sensors/accelerometers/lis3dh.h
new file mode 100644
index 0000000000000000000000000000000000000000..d76a0d8b860da99e225cbea45738cfeaf2056831
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/accelerometers/lis3dh.h
@@ -0,0 +1,138 @@
+/**************************************************************************/
+/*!
+    @file     lis3dh.h
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _LIS3DH_H_
+#define _LIS3DH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "core/i2c/i2c.h"
+#include "drivers/sensors/sensors.h"
+
+#define LIS3DH_ADDRESS                (0x18<<1)   // 0011000 (Assumes SDO/SA0 = GND)
+#define LIS3DH_READBIT                (0x01)
+#define LIS3DH_POLL_TIMEOUT           (100)       // Maximum number of read attempts in lis3dhPoll()
+
+/* Struct to hold the accelerometer sensor data */
+typedef struct
+{
+  int16_t x;
+  int16_t y;
+  int16_t z;
+} lis3dhData_t;
+
+// Core registers
+enum
+{                                               // BINARY   DEFAULT   TYPE
+  LIS3DH_REGISTER_STATUS_REG_AUX      = 0x07,   // 00000111           r
+  LIS3DH_REGISTER_OUT_ADC1_L          = 0x08,   // 00001000 output    r
+  LIS3DH_REGISTER_OUT_ADC1_H          = 0x09,   // 00001001 output    r
+  LIS3DH_REGISTER_OUT_ADC2_L          = 0x0A,   // 00001010 output    r
+  LIS3DH_REGISTER_OUT_ADC2_H          = 0x0B,   // 00001011 output    r
+  LIS3DH_REGISTER_OUT_ADC3_L          = 0x0C,   // 00001100 output    r
+  LIS3DH_REGISTER_OUT_ADC3_H          = 0x0D,   // 00001101 output    r
+  LIS3DH_REGISTER_INT_COUNTER_REG     = 0x0E,   // 00001110           r
+  LIS3DH_REGISTER_WHO_AM_I            = 0x0F,   // 00001111 00110011  r
+  LIS3DH_REGISTER_TEMP_CFG_REG        = 0x1F,   // 00011111           rw
+  LIS3DH_REGISTER_CTRL_REG1           = 0x20,   // 00100000 00000111  rw
+  LIS3DH_REGISTER_CTRL_REG2           = 0x21,   // 00100001 00000000  rw
+  LIS3DH_REGISTER_CTRL_REG3           = 0x22,   // 00100010 00000000  rw
+  LIS3DH_REGISTER_CTRL_REG4           = 0x23,   // 00100011 00000000  rw
+  LIS3DH_REGISTER_CTRL_REG5           = 0x24,   // 00100100 00000000  rw
+  LIS3DH_REGISTER_CTRL_REG6           = 0x25,   // 00100101 00000000  rw
+  LIS3DH_REGISTER_REFERENCE           = 0x26,   // 00100110 00000000  rw
+  LIS3DH_REGISTER_STATUS_REG2         = 0x27,   // 00100111 00000000  r
+  LIS3DH_REGISTER_OUT_X_L             = 0x28,   // 00101000 output    r
+  LIS3DH_REGISTER_OUT_X_H             = 0x29,   // 00101001 output    r
+  LIS3DH_REGISTER_OUT_Y_L             = 0x2A,   // 00101010 output    r
+  LIS3DH_REGISTER_OUT_Y_H             = 0x2B,   // 00101011 output    r
+  LIS3DH_REGISTER_OUT_Z_L             = 0x2C,   // 00101100 output    r
+  LIS3DH_REGISTER_OUT_Z_H             = 0x2D,   // 00101101 output    r
+  LIS3DH_REGISTER_FIFO_CTRL_REG       = 0x2E,   // 00101110 00000000  rw
+  LIS3DH_REGISTER_FIFO_SRC_REG        = 0x2F,   // 00101111           r
+  LIS3DH_REGISTER_INT1_CFG            = 0x30,   // 00110000 00000000  rw
+  LIS3DH_REGISTER_INT1_SOURCE         = 0x31,   // 00110001 00000000  r
+  LIS3DH_REGISTER_INT1_THS            = 0x32,   // 00110010 00000000  rw
+  LIS3DH_REGISTER_INT1_DURATION       = 0x33,   // 00110011 00000000  rw
+  LIS3DH_REGISTER_CLICK_CFG           = 0x38,   // 00111000 00000000  rw
+  LIS3DH_REGISTER_CLICK_SRC           = 0x39,   // 00111001 00000000  r
+  LIS3DH_REGISTER_CLICK_THS           = 0x3A,   // 00111010 00000000  rw
+  LIS3DH_REGISTER_TIME_LIMIT          = 0x3B,   // 00111011 00000000  rw
+  LIS3DH_REGISTER_TIME_LATENCY        = 0x3C,   // 00111100 00000000  rw
+  LIS3DH_REGISTER_TIME_WINDOW         = 0x3D    // 00111101 00000000  rw
+};
+
+// Bit twiddling keys for use with different registers
+enum
+{
+  LIS3DH_STATUS_REG_ZYXDA             = 0x08,   // STATUS_REG: XYZ - sample ready
+  LIS3DH_STATUS_REG_ZYXOR             = 0x80,   // STATUS_REG: XYZ - new set of data has overwritten the previous ones
+  LIS3DH_CTRL_REG1_XEN                = 0x01,   // CTRL_REG1: X enable
+  LIS3DH_CTRL_REG1_YEN                = 0x02,   // CTRL_REG1: Y enable
+  LIS3DH_CTRL_REG1_ZEN                = 0x04,   // CTRL_REG1: Z enable
+  LIS3DH_CTRL_REG1_XYZEN              = 0x07,   // CTRL_REG1: X+Y+Z enable
+  LIS3DH_CTRL_REG1_LPEN               = 0x08,   // CTRL_REG1: Low power enable
+  LIS3DH_CTRL_REG1_DATARATE_POWERDOWN = 0x00,   // CTRL_REG1: 0000 xxxx
+  LIS3DH_CTRL_REG1_DATARATE_1HZ       = 0x10,   // CTRL_REG1: 0001 xxxx
+  LIS3DH_CTRL_REG1_DATARATE_10HZ      = 0x20,   // CTRL_REG1: 0010 xxxx
+  LIS3DH_CTRL_REG1_DATARATE_25HZ      = 0x30,   // CTRL_REG1: 0011 xxxx
+  LIS3DH_CTRL_REG1_DATARATE_50HZ      = 0x40,   // CTRL_REG1: 0100 xxxx
+  LIS3DH_CTRL_REG1_DATARATE_100HZ     = 0x50,   // CTRL_REG1: 0101 xxxx
+  LIS3DH_CTRL_REG1_DATARATE_200HZ     = 0x60,   // CTRL_REG1: 0110 xxxx
+  LIS3DH_CTRL_REG1_DATARATE_400HZ     = 0x70,   // CTRL_REG1: 0111 xxxx
+  LIS3DH_CTRL_REG1_DATARATE_1500HZ    = 0x80,   // CTRL_REG1: 1000 xxxx
+  LIS3DH_CTRL_REG1_DATARATE_5000HZ    = 0x90,   // CTRL_REG1: 1001 xxxx
+  LIS3DH_CTRL_REG4_BLOCKDATAUPDATE    = 0x80,   // CTRL_REG4: 1xxx xxxx
+  LIS3DH_CTRL_REG4_SCALE_2G           = 0x00,   // CTRL_REG4: xx00 xxxx
+  LIS3DH_CTRL_REG4_SCALE_4G           = 0x10,   // CTRL_REG4: xx01 xxxx
+  LIS3DH_CTRL_REG4_SCALE_8G           = 0x20,   // CTRL_REG4: xx10 xxxx
+  LIS3DH_CTRL_REG4_SCALE_16G          = 0x30,   // CTRL_REG4: xx11 xxxx
+};
+
+// Function prototypes
+err_t lis3dhInit(void);
+err_t lis3dhPoll(lis3dhData_t* data);
+void    lis3dhGetSensor(sensor_t *sensor);
+err_t lis3dhGetSensorEvent(sensors_event_t *event);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/sensors/accelerometers/lsm303accel.c b/reform2-lpc-fw/src/drivers/sensors/accelerometers/lsm303accel.c
new file mode 100644
index 0000000000000000000000000000000000000000..ede5cb0fca2ab414a29bb6a681b23d0a26553d90
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/accelerometers/lsm303accel.c
@@ -0,0 +1,248 @@
+/**************************************************************************/
+/*!
+    @file     lsm303accel.c
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @brief    Driver for the ST LSM303DLHC I2C accelerometer
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+#include "lsm303accel.h"
+#include "core/delay/delay.h"
+#include <string.h>
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+static bool               _lsm303accelInitialised = false;
+static int32_t            _lsm303accelSensorID = 0;
+static lsm303AccelData_t  _lsm303accelData;
+static float              _lsm303accel_MG_LSB = 0.001F;      // 1, 2, 4 or 12 mg per lsb
+
+/**************************************************************************/
+/*!
+    @brief  Writes an unsigned 8 bit values over I2C
+*/
+/**************************************************************************/
+err_t lsm303accelWrite8(uint8_t addr, uint8_t reg, uint8_t value)
+{
+  I2CWriteLength = 3;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = addr;
+  I2CMasterBuffer[1] = reg;
+  I2CMasterBuffer[2] = (value);
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads an unsigned 8 bit value over I2C
+*/
+/**************************************************************************/
+err_t lsm303accelRead8(uint8_t addr, uint8_t reg, uint8_t *value)
+{
+  /* Write transaction */
+  I2CWriteLength = 2;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = addr;
+  I2CMasterBuffer[1] = reg;
+  i2cEngine();
+
+  /* Read transaction */
+  I2CWriteLength = 0;
+  I2CReadLength = 1;
+  I2CMasterBuffer[0] = addr | 0x01;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  /* Send received value back to the caller */
+  *value = I2CSlaveBuffer[0];
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads three signed 16 bit values over I2C
+*/
+/**************************************************************************/
+err_t lsm303accelRead48(uint8_t addr, uint8_t reg, uint8_t buffer[6])
+{
+  /* Write transaction */
+  I2CWriteLength = 2;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = addr;
+  I2CMasterBuffer[1] = reg | (0x80);
+  i2cEngine();
+
+  /* Read transaction */
+  I2CWriteLength = 0;
+  I2CReadLength = 6;
+  I2CMasterBuffer[0] = addr | 0x01;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  uint8_t i;
+  for (i = 0; i < 6; i++)
+  {
+    buffer[i] = I2CSlaveBuffer[i];
+  }
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Initialises the I2C block
+*/
+/**************************************************************************/
+err_t lsm303accelInit(void)
+{
+  // Initialise I2C
+  i2cInit(I2CMASTER);
+
+  /* Ping the I2C device first to see if it exists! */
+  ASSERT(i2cCheckAddress(LSM303_ADDRESS_ACCEL), ERROR_I2C_DEVICENOTFOUND);
+
+  /* Enable the accelerometer (10Hz) */
+  // ASSERT_STATUS(lsm303accelWrite8(LSM303_ADDRESS_ACCEL, LSM303_REGISTER_ACCEL_CTRL_REG1_A, 0x27));
+  /* Enable the accelerometer (100Hz) */
+  ASSERT_STATUS(lsm303accelWrite8(LSM303_ADDRESS_ACCEL, LSM303_REGISTER_ACCEL_CTRL_REG1_A, 0x57));
+
+  _lsm303accelInitialised = true;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the raw accelerometer values if you want to skip
+            the sensor system abstraction layer and the float overhead
+*/
+/**************************************************************************/
+err_t lsm303accelReadRaw(int16_t *x, int16_t *y, int16_t *z)
+{
+  uint8_t buffer[6] = { 0, 0, 0, 0, 0, 0 };
+
+  if (!_lsm303accelInitialised)
+  {
+    ASSERT_STATUS(lsm303accelInit());
+  }
+
+  /* Read the accelerometer */
+  ASSERT_STATUS(lsm303accelRead48(LSM303_ADDRESS_ACCEL, LSM303_REGISTER_ACCEL_OUT_X_L_A, buffer));
+
+  /* Shift values to create properly formed integer (low byte first) */
+  /* Note: Accelerometer is X/Y/Z, low byte then high */
+  *x = ((int16_t)(buffer[0] | (buffer[1] << 8))) >> 4;
+  *y = ((int16_t)(buffer[2] | (buffer[3] << 8))) >> 4;
+  *z = ((int16_t)(buffer[4] | (buffer[5] << 8))) >> 4;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the current accelerometer values
+*/
+/**************************************************************************/
+err_t lsm303accelRead(void)
+{
+  uint8_t buffer[6] = { 0, 0, 0, 0, 0, 0 };
+
+  if (!_lsm303accelInitialised)
+  {
+    ASSERT_STATUS(lsm303accelInit());
+  }
+
+  /* Read the accelerometer */
+  ASSERT_STATUS(lsm303accelRead48(LSM303_ADDRESS_ACCEL, LSM303_REGISTER_ACCEL_OUT_X_L_A, buffer));
+
+  /* Shift values to create properly formed integer (low byte first) */
+  /* Note: Accelerometer is X/Y/Z, low byte then high */
+  _lsm303accelData.x = ((int16_t)(buffer[0] | (buffer[1] << 8))) >> 4;
+  _lsm303accelData.y = ((int16_t)(buffer[2] | (buffer[3] << 8))) >> 4;
+  _lsm303accelData.z = ((int16_t)(buffer[4] | (buffer[5] << 8))) >> 4;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Provides the sensor_t data for this sensor
+*/
+/**************************************************************************/
+void lsm303accelGetSensor(sensor_t *sensor)
+{
+  /* Clear the sensor_t object */
+  memset(sensor, 0, sizeof(sensor_t));
+
+  /* Insert the sensor name in the fixed length char array */
+  strncpy (sensor->name, "LSM303DLHC", sizeof(sensor->name) - 1);
+  sensor->name[sizeof(sensor->name)- 1] = 0;
+  sensor->version     = 1;
+  sensor->sensor_id   = _lsm303accelSensorID;
+  sensor->type        = SENSOR_TYPE_ACCELEROMETER;
+  sensor->min_delay   = 0;
+  sensor->max_value   = 1.0;                  // TBD
+  sensor->min_value   = 1.0;                  // TBD
+  sensor->resolution  = 1.0;                  // TBD
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the sensor and returns the data as a sensors_event_t
+*/
+/**************************************************************************/
+err_t lsm303accelGetSensorEvent(sensors_event_t *event)
+{
+  /* Clear the event */
+  memset(event, 0, sizeof(sensors_event_t));
+
+  event->version   = sizeof(sensors_event_t);
+  event->sensor_id = _lsm303accelSensorID;
+  event->type      = SENSOR_TYPE_ACCELEROMETER;
+  event->timestamp = delayGetTicks();
+
+  /* Convert units to m/s^2 */
+  ASSERT_STATUS(lsm303accelRead());
+  event->acceleration.x = _lsm303accelData.x * _lsm303accel_MG_LSB * SENSORS_GRAVITY_STANDARD;
+  event->acceleration.y = _lsm303accelData.y * _lsm303accel_MG_LSB * SENSORS_GRAVITY_STANDARD;
+  event->acceleration.z = _lsm303accelData.z * _lsm303accel_MG_LSB * SENSORS_GRAVITY_STANDARD;
+
+  return ERROR_NONE;
+}
diff --git a/reform2-lpc-fw/src/drivers/sensors/accelerometers/lsm303accel.h b/reform2-lpc-fw/src/drivers/sensors/accelerometers/lsm303accel.h
new file mode 100644
index 0000000000000000000000000000000000000000..9823755a08fcc984313fb6e8ddb30e21aba59ac8
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/accelerometers/lsm303accel.h
@@ -0,0 +1,100 @@
+/**************************************************************************/
+/*!
+    @file     lsm303accel.h
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _LSM303DLHC_ACCEL_H_
+#define _LSM303DLHC_ACCEL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "core/i2c/i2c.h"
+#include "drivers/sensors/sensors.h"
+
+#define LSM303_ADDRESS_ACCEL      (0x19<<1) // 0011001
+
+enum
+{                                                                                                          // DEFAULT    TYPE
+  LSM303_REGISTER_ACCEL_CTRL_REG1_A         = 0x20,   // 00000111   rw
+  LSM303_REGISTER_ACCEL_CTRL_REG2_A         = 0x21,   // 00000000   rw
+  LSM303_REGISTER_ACCEL_CTRL_REG3_A         = 0x22,   // 00000000   rw
+  LSM303_REGISTER_ACCEL_CTRL_REG4_A         = 0x23,   // 00000000   rw
+  LSM303_REGISTER_ACCEL_CTRL_REG5_A         = 0x24,   // 00000000   rw
+  LSM303_REGISTER_ACCEL_CTRL_REG6_A         = 0x25,   // 00000000   rw
+  LSM303_REGISTER_ACCEL_REFERENCE_A         = 0x26,   // 00000000   r
+  LSM303_REGISTER_ACCEL_STATUS_REG_A        = 0x27,   // 00000000   r
+  LSM303_REGISTER_ACCEL_OUT_X_L_A           = 0x28,
+  LSM303_REGISTER_ACCEL_OUT_X_H_A           = 0x29,
+  LSM303_REGISTER_ACCEL_OUT_Y_L_A           = 0x2A,
+  LSM303_REGISTER_ACCEL_OUT_Y_H_A           = 0x2B,
+  LSM303_REGISTER_ACCEL_OUT_Z_L_A           = 0x2C,
+  LSM303_REGISTER_ACCEL_OUT_Z_H_A           = 0x2D,
+  LSM303_REGISTER_ACCEL_FIFO_CTRL_REG_A     = 0x2E,
+  LSM303_REGISTER_ACCEL_FIFO_SRC_REG_A      = 0x2F,
+  LSM303_REGISTER_ACCEL_INT1_CFG_A          = 0x30,
+  LSM303_REGISTER_ACCEL_INT1_SOURCE_A       = 0x31,
+  LSM303_REGISTER_ACCEL_INT1_THS_A          = 0x32,
+  LSM303_REGISTER_ACCEL_INT1_DURATION_A     = 0x33,
+  LSM303_REGISTER_ACCEL_INT2_CFG_A          = 0x34,
+  LSM303_REGISTER_ACCEL_INT2_SOURCE_A       = 0x35,
+  LSM303_REGISTER_ACCEL_INT2_THS_A          = 0x36,
+  LSM303_REGISTER_ACCEL_INT2_DURATION_A     = 0x37,
+  LSM303_REGISTER_ACCEL_CLICK_CFG_A         = 0x38,
+  LSM303_REGISTER_ACCEL_CLICK_SRC_A         = 0x39,
+  LSM303_REGISTER_ACCEL_CLICK_THS_A         = 0x3A,
+  LSM303_REGISTER_ACCEL_TIME_LIMIT_A        = 0x3B,
+  LSM303_REGISTER_ACCEL_TIME_LATENCY_A      = 0x3C,
+  LSM303_REGISTER_ACCEL_TIME_WINDOW_A       = 0x3D
+};
+
+typedef struct lsm303AccelData_s
+{
+  float x;
+  float y;
+  float z;
+} lsm303AccelData_t;
+
+err_t  lsm303accelInit(void);
+err_t  lsm303accelReadRaw(int16_t *x, int16_t *y, int16_t *z);
+err_t  lsm303accelGetSensorEvent(sensors_event_t *event);
+void     lsm303accelGetSensor(sensor_t *sensor);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/sensors/characterisation.txt b/reform2-lpc-fw/src/drivers/sensors/characterisation.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d9630ad5835c074d9c2becd27ad687b5947133e8
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/characterisation.txt
@@ -0,0 +1,93 @@
+Driver Characterisation Results
+-------------------------------
+
+Basic tests results for various drivers and the sensor API to determine the
+real-world sampling rate of different sensors, and to identify where
+development effort should be spent to improve existing drivers.
+
+Comparing Raw Data Reads (Native Units) and GetSensorEvent
+----------------------------------------------------------
+
+To get an idea of the overhead of the sensor abstraction layer (since it
+does use some floating point calculations, and the SI unit conversion has
+some overhead), the raw data reads were compared with GetSensorEvent, with
+the following results.
+
+The lsm303accel.c driver was using in the following test, which uses int16_t
+for the native types (returned via ReadRaw):
+
+|---------------------+-----------+---------+---------+---------+------------|
+| Function            | Code Base |   Avg   |   Min   |   Max   |   Notes    |
+|                     |  Version  |  Ticks  |  Ticks  |  Ticks  |            |
+|---------------------+-----------+---------+---------+---------+------------|
+| GetSensorEvent      |   0.8.7   |   20256 |   20230 |   20387 | -o0        |
+| ReadRaw             |   0.8.7   |   19136 |   19019 |   20410 | -o0        |
+|---------------------|-----------|---------|---------|---------|------------|
+| Difference          |           |    1120 |    1211 |     -23 |            |
+|---------------------+-----------+---------+---------+---------+------------|
+
+GetSensorEvent Performance Tests
+--------------------------------
+
+The following tests results show the average number of ticks required to run
+*GetSensorEvent over 1,000 samples, as well as the min and max tick count.
+
+The code base version is included to take into account future improvements to
+the drivers, and put the performance numbers in historical perspective.
+
+|---------------------+-----------+---------+---------+---------+------------|
+| Sensor Driver       | Code Base |   Avg   |   Min   |   Max   |   Notes    |
+|                     |  Version  |  Ticks  |  Ticks  |  Ticks  |            |
+|---------------------+-----------+---------+---------+---------+------------|
+| bmp085.c (LOWPOWER) |   0.8.7   |  719963 |  718978 |  722893 | -o0        |
+| bmp085.c (STANDARD) |   0.8.7   |  935976 |  934972 |  938757 | -o0        |
+| bmp085.c (HIGHRES)  |   0.8.7   | 1367998 | 1367023 | 1370931 | -o0        |
+| bmp085.c (UHIGHRES) |   0.8.7   | 2232047 | 2230899 | 2234985 | -o0        |
+| mpl115a2.c          |   0.8.7   |  287882 |  241913 |  288924 | -o0        |
+| lsm303accel.c       |   0.8.7   |   20256 |   20230 |   20387 | -o0        |
+| lsm303mag.c         |   0.8.7   |   20420 |   20397 |   22068 | -o0        |
+|---------------------+-----------+---------+---------+---------+------------|
+
+The following test code was used on a Cortex M3 LPC1347 processor at 72MHz to
+generate these test results (bmp085 used an example here):
+
+  error_t error;
+  sensors_event_t event;
+
+  error = bmp085Init(BMP085_MODE_ULTRALOWPOWER);
+
+  if (!error)
+  {
+    uint32_t min, max, cur, avg, errors;
+    uint64_t total = 0;
+    uint32_t i = 0;
+    min = max = cur = avg = errors = 0;
+    printf("Collecting 1000 samples from the sensor %s", CFG_PRINTF_NEWLINE);
+    for (i=0;i<1000;i++)
+    {
+      DWT_RESET_CYCLECOUNTER;
+      error = bmp085GetSensorEvent(&event);
+      cur = DWT->CYCCNT;
+      if (min == 0) min = cur;
+      if (error)
+      {
+        errors++;
+      }
+      else
+      {
+        if (cur < min) min = cur;
+        if (cur > max) max = cur;
+        total+=cur;
+      }
+    }
+    avg = total/1000;
+    printf("Min: %d, Max: %d, Avg: %d, Errors: %d %s", 
+            min, max, avg, errors, CFG_PRINTF_NEWLINE);
+  }
+  else
+  {
+    while(1)
+    {
+      __NOP();
+    }
+  }
diff --git a/reform2-lpc-fw/src/drivers/sensors/color/tcs34725.c b/reform2-lpc-fw/src/drivers/sensors/color/tcs34725.c
new file mode 100644
index 0000000000000000000000000000000000000000..91be1ef4ccae857ca2dde83e4d6682968d87ab2f
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/color/tcs34725.c
@@ -0,0 +1,323 @@
+/**************************************************************************/
+/*!
+    @file     tcs34725.c
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+    @brief    Driver for the TAOS TCS34725 I2C digital RGB/color sensor
+    @license  BSD (see license.txt)
+*/
+/**************************************************************************/
+#include <string.h>
+#include <math.h>
+
+#include "projectconfig.h"
+#include "tcs34725.h"
+#include "core/delay/delay.h"
+
+extern volatile uint8_t  I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t  I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t I2CReadLength, I2CWriteLength;
+
+static bool                       _tcs34725Initialised = false;
+static int32_t                    _tcs34725SensorID = 0;
+static tcs34725Gain_t             _tcs34725Gain = TCS34725_GAIN_1X;
+static tcs34725IntegrationTime_t  _tcs34725IntegrationTime = TCS34725_INTEGRATIONTIME_2_4MS;
+
+/**************************************************************************/
+/*!
+    @brief  Writes an 8 bit values over I2C
+*/
+/**************************************************************************/
+err_t tcs34725Write8 (uint8_t reg, uint8_t value)
+{
+  I2CWriteLength = 3;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = TCS34725_ADDRESS;
+  I2CMasterBuffer[1] = TCS34725_COMMAND_BIT | reg;
+  I2CMasterBuffer[2] = value;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads a 16 bit values over I2C
+*/
+/**************************************************************************/
+err_t tcs34725Read8(uint8_t reg, uint8_t *value)
+{
+  /* Write transaction */
+  I2CWriteLength = 2;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = TCS34725_ADDRESS;
+  I2CMasterBuffer[1] = TCS34725_COMMAND_BIT | reg;
+  i2cEngine();
+
+  /* Read transaction */
+  I2CWriteLength = 0;
+  I2CReadLength = 1;
+  I2CMasterBuffer[0] = TCS34725_ADDRESS | TCS34725_READBIT;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  *value = I2CSlaveBuffer[0];
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads a 16 bit values over I2C
+*/
+/**************************************************************************/
+err_t tcs34725Read16(uint8_t reg, uint16_t *value)
+{
+  /* Write transaction */
+  I2CWriteLength = 2;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = TCS34725_ADDRESS;
+  I2CMasterBuffer[1] = TCS34725_COMMAND_BIT | reg;
+  i2cEngine();
+
+  /* Read transaction */
+  I2CWriteLength = 0;
+  I2CReadLength = 2;
+  I2CMasterBuffer[0] = TCS34725_ADDRESS | TCS34725_READBIT;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  /* Shift values to create properly formed integer (low byte first) */
+  *value = (I2CSlaveBuffer[0] | (I2CSlaveBuffer[1] << 8));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Enables the device
+*/
+/**************************************************************************/
+err_t tcs34725Enable(void)
+{
+  ASSERT_STATUS(tcs34725Write8(TCS34725_ENABLE, TCS34725_ENABLE_PON));
+  delay(3);
+  ASSERT_STATUS(tcs34725Write8(TCS34725_ENABLE, TCS34725_ENABLE_PON | TCS34725_ENABLE_AEN));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Disables the device (putting it in lower power sleep mode)
+*/
+/**************************************************************************/
+err_t tcs34725Disable(void)
+{
+  /* Turn the device off to save power */
+  uint8_t reg = 0;
+  ASSERT_STATUS(tcs34725Read8(TCS34725_ENABLE, &reg));
+  ASSERT_STATUS(tcs34725Write8(TCS34725_ENABLE, reg & ~(TCS34725_ENABLE_PON | TCS34725_ENABLE_AEN)));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Initialises the I2C block
+*/
+/**************************************************************************/
+err_t tcs34725Init(void)
+{
+  uint8_t id = 0;
+
+  /* Initialise I2C */
+  i2cInit(I2CMASTER);
+
+  /* Ping the I2C device first to see if it exists! */
+  ASSERT(i2cCheckAddress(TCS34725_ADDRESS), ERROR_I2C_DEVICENOTFOUND);
+
+  /* Make sure we have the right IC (0x44 = TCS34725 and TCS34721) */
+  ASSERT_STATUS(tcs34725Read8(TCS34725_ID, &id));
+  ASSERT(id == 0x44, ERROR_DEVICENOTINITIALISED);
+
+  /* Enable the device */
+  ASSERT_STATUS(tcs34725Enable());
+
+  /* Ready to go ... set the initialised flag */
+  _tcs34725Initialised = true;
+
+  /* This needs to take place after the initialisation flag! */
+  ASSERT_STATUS(tcs34725SetIntegrationTime(TCS34725_INTEGRATIONTIME_2_4MS));
+  ASSERT_STATUS(tcs34725SetGain(TCS34725_GAIN_60X));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the integration time to the specified value
+*/
+/**************************************************************************/
+err_t tcs34725SetIntegrationTime(tcs34725IntegrationTime_t it)
+{
+  if (!_tcs34725Initialised)
+  {
+    ASSERT_STATUS(tcs34725Init());
+  }
+
+  ASSERT_STATUS(tcs34725Write8(TCS34725_ATIME, it));
+  _tcs34725IntegrationTime = it;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets gain to the specified value
+*/
+/**************************************************************************/
+err_t tcs34725SetGain(tcs34725Gain_t gain)
+{
+  if (!_tcs34725Initialised)
+  {
+    ASSERT_STATUS(tcs34725Init());
+  }
+
+  ASSERT_STATUS(tcs34725Write8(TCS34725_CONTROL, gain));
+  _tcs34725Gain = gain;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the raw red, green, blue and clear channel values
+*/
+/**************************************************************************/
+err_t tcs34725GetRawData(uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *c)
+{
+  if (!_tcs34725Initialised)
+  {
+    ASSERT_STATUS(tcs34725Init());
+  }
+
+  /* ToDo: Insert a blocky delay until the data is ready! */
+  ASSERT_STATUS(tcs34725Read16(TCS34725_CDATAL, c));
+  ASSERT_STATUS(tcs34725Read16(TCS34725_RDATAL, r));
+  ASSERT_STATUS(tcs34725Read16(TCS34725_GDATAL, g));
+  ASSERT_STATUS(tcs34725Read16(TCS34725_BDATAL, b));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Converts the raw R/G/B values to color temperature in degrees
+            Kelvin
+*/
+/**************************************************************************/
+uint16_t tcs34725CalculateColorTemperature(uint16_t r, uint16_t g, uint16_t b)
+{
+  float X, Y, Z;      /* RGB to XYZ correlation      */
+  float xc, yc;       /* Chromaticity co-ordinates   */
+  float n;            /* McCamy's formula            */
+  float cct;
+
+  /* 1. Map RGB values to their XYZ counterparts.    */
+  /* Based on 6500K fluorescent, 3000K fluorescent   */
+  /* and 60W incandescent values for a wide range.   */
+  /* Note: Y = Illuminance or lux                    */
+  X = (-0.14282F * r) + (1.54924F * g) + (-0.95641F * b);
+  Y = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b);
+  Z = (-0.68202F * r) + (0.77073F * g) + ( 0.56332F * b);
+
+  /* 2. Calculate the chromaticity co-ordinates      */
+  xc = (X) / (X + Y + Z);
+  yc = (Y) / (X + Y + Z);
+
+  /* 3. Use McCamy's formula to determine the CCT    */
+  n = (xc - 0.3320F) / (0.1858F - yc);
+
+  /* Calculate the final CCT */
+  cct = (449.0F * powf(n, 3)) + (3525.0F * powf(n, 2)) + (6823.3F * n) + 5520.33F;
+
+  /* Return the results in degrees Kelvin */
+  return (uint16_t)cct;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Converts the raw R/G/B values to color temperature in degrees
+            Kelvin
+*/
+/**************************************************************************/
+uint16_t tcs34725CalculateLux(uint16_t r, uint16_t g, uint16_t b)
+{
+  float illuminance;
+
+  /* This only uses RGB ... how can we integrate clear or calculate lux */
+  /* based exclusively on clear since this might be more reliable?      */
+  illuminance = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b);
+
+  return (uint16_t)illuminance;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Provides the sensor_t data for this sensor
+*/
+/**************************************************************************/
+void tcs34725GetSensor(sensor_t *sensor)
+{
+  /* Clear the sensor_t object */
+  memset(sensor, 0, sizeof(sensor_t));
+
+  /* Insert the sensor name in the fixed length char array */
+  strncpy (sensor->name, "TCS34725", sizeof(sensor->name) - 1);
+  sensor->name[sizeof(sensor->name)- 1] = 0;
+  sensor->version     = 1;
+  sensor->sensor_id   = _tcs34725SensorID;
+  sensor->type        = SENSOR_TYPE_COLOR;
+  sensor->min_delay   = 0;
+  sensor->max_value   = 0.0;
+  sensor->min_value   = 1.0;
+  sensor->resolution  = 1.0;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the sensor and returns the data as a sensors_event_t
+*/
+/**************************************************************************/
+err_t tcs34725GetSensorEvent(sensors_event_t *event)
+{
+  float maxCount;
+  uint16_t r, g, b, c;
+
+  /* Clear the event */
+  memset(event, 0, sizeof(sensors_event_t));
+
+  event->version   = sizeof(sensors_event_t);
+  event->sensor_id = _tcs34725SensorID;
+  event->type      = SENSOR_TYPE_COLOR;
+  event->timestamp = delayGetTicks();
+
+  /* Get the raw RGB values */
+  ASSERT_STATUS(tcs34725GetRawData(&r, &g, &b, &c));
+
+  /* Convert RGB values to floats */
+  maxCount = (256 - _tcs34725IntegrationTime) * 1024;
+  event->color.r = r / maxCount;
+  event->color.g = g / maxCount;
+  event->color.b = b / maxCount;
+
+  /* Convert to a 24-bit ARGB value */
+  event->color.rgba = (uint8_t)(event->color.r * 0xFF) << 16|
+                      (uint8_t)(event->color.g * 0xFF) << 8 |
+                      (uint8_t)(event->color.b * 0xFF) |
+                      0xFF000000;
+
+  return ERROR_NONE;
+}
diff --git a/reform2-lpc-fw/src/drivers/sensors/color/tcs34725.h b/reform2-lpc-fw/src/drivers/sensors/color/tcs34725.h
new file mode 100644
index 0000000000000000000000000000000000000000..a02204d4063378d2046c578ea6f5198eefeb7a4a
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/color/tcs34725.h
@@ -0,0 +1,104 @@
+/**************************************************************************/
+/*!
+    @file     tcs34725.h
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+    @license  BSD (see license.txt)
+*/
+/**************************************************************************/
+#ifndef _TCS34725_H_
+#define _TCS34725_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "core/i2c/i2c.h"
+#include "drivers/sensors/sensors.h"
+
+#define TCS34725_ADDRESS          (0x29<<1)
+#define TCS34725_READBIT          (0x01)
+
+#define TCS34725_COMMAND_BIT      (0x80)
+
+#define TCS34725_ENABLE           (0x00)
+#define TCS34725_ENABLE_AIEN      (0x10)    /* RGBC Interrupt Enable */
+#define TCS34725_ENABLE_WEN       (0x08)    /* Wait enable - Writing 1 activates the wait timer */
+#define TCS34725_ENABLE_AEN       (0x02)    /* RGBC Enable - Writing 1 actives the ADC, 0 disables it */
+#define TCS34725_ENABLE_PON       (0x01)    /* Power on - Writing 1 activates the internal oscillator, 0 disables it */
+#define TCS34725_ATIME            (0x01)    /* Integration time */
+#define TCS34725_WTIME            (0x03)    /* Wait time (if TCS34725_ENABLE_WEN is asserted) */
+#define TCS34725_WTIME_2_4MS      (0xFF)    /* WLONG0 = 2.4ms   WLONG1 = 0.029s */
+#define TCS34725_WTIME_204MS      (0xAB)    /* WLONG0 = 204ms   WLONG1 = 2.45s  */
+#define TCS34725_WTIME_614MS      (0x00)    /* WLONG0 = 614ms   WLONG1 = 7.4s   */
+#define TCS34725_AILTL            (0x04)    /* Clear channel lower interrupt threshold */
+#define TCS34725_AILTH            (0x05)
+#define TCS34725_AIHTL            (0x06)    /* Clear channel upper interrupt threshold */
+#define TCS34725_AIHTH            (0x07)
+#define TCS34725_PERS             (0x0C)    /* Persistence register - basic SW filtering mechanism for interrupts */
+#define TCS34725_PERS_NONE        (0b0000)  /* Every RGBC cycle generates an interrupt                                */
+#define TCS34725_PERS_1_CYCLE     (0b0001)  /* 1 clean channel value outside threshold range generates an interrupt   */
+#define TCS34725_PERS_2_CYCLE     (0b0010)  /* 2 clean channel values outside threshold range generates an interrupt  */
+#define TCS34725_PERS_3_CYCLE     (0b0011)  /* 3 clean channel values outside threshold range generates an interrupt  */
+#define TCS34725_PERS_5_CYCLE     (0b0100)  /* 5 clean channel values outside threshold range generates an interrupt  */
+#define TCS34725_PERS_10_CYCLE    (0b0101)  /* 10 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_15_CYCLE    (0b0110)  /* 15 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_20_CYCLE    (0b0111)  /* 20 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_25_CYCLE    (0b1000)  /* 25 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_30_CYCLE    (0b1001)  /* 30 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_35_CYCLE    (0b1010)  /* 35 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_40_CYCLE    (0b1011)  /* 40 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_45_CYCLE    (0b1100)  /* 45 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_50_CYCLE    (0b1101)  /* 50 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_55_CYCLE    (0b1110)  /* 55 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_60_CYCLE    (0b1111)  /* 60 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_CONFIG           (0x0D)
+#define TCS34725_CONFIG_WLONG     (0x02)    /* Choose between short and long (12x) wait times via TCS34725_WTIME */
+#define TCS34725_CONTROL          (0x0F)    /* Set the gain level for the sensor */
+#define TCS34725_ID               (0x12)    /* 0x44 = TCS34721/TCS34725, 0x4D = TCS34723/TCS34727 */
+#define TCS34725_STATUS           (0x13)
+#define TCS34725_STATUS_AINT      (0x10)    /* RGBC Clean channel interrupt */
+#define TCS34725_STATUS_AVALID    (0x01)    /* Indicates that the RGBC channels have completed an integration cycle */
+#define TCS34725_CDATAL           (0x14)    /* Clear channel data */
+#define TCS34725_CDATAH           (0x15)
+#define TCS34725_RDATAL           (0x16)    /* Red channel data */
+#define TCS34725_RDATAH           (0x17)
+#define TCS34725_GDATAL           (0x18)    /* Green channel data */
+#define TCS34725_GDATAH           (0x19)
+#define TCS34725_BDATAL           (0x1A)    /* Blue channel data */
+#define TCS34725_BDATAH           (0x1B)
+
+typedef enum
+{
+  TCS34725_INTEGRATIONTIME_2_4MS  = 0xFF,   /**<  2.4ms - 1 cycle    - Max Count: 1024  */
+  TCS34725_INTEGRATIONTIME_24MS   = 0xF6,   /**<  24ms  - 10 cycles  - Max Count: 10240 */
+  TCS34725_INTEGRATIONTIME_101MS  = 0xD5,   /**<  101ms - 42 cycles  - Max Count: 43008 */
+  TCS34725_INTEGRATIONTIME_154MS  = 0xC0,   /**<  154ms - 64 cycles  - Max Count: 65535 */
+  TCS34725_INTEGRATIONTIME_700MS  = 0x00    /**<  700ms - 256 cycles - Max Count: 65535 */
+}
+tcs34725IntegrationTime_t;
+
+typedef enum
+{
+  TCS34725_GAIN_1X                = 0x00,   /**<  No gain  */
+  TCS34725_GAIN_4X                = 0x01,   /**<  2x gain  */
+  TCS34725_GAIN_16X               = 0x02,   /**<  16x gain */
+  TCS34725_GAIN_60X               = 0x03    /**<  60x gain */
+}
+tcs34725Gain_t;
+
+err_t tcs34725Init(void);
+err_t tcs34725Enable(void);
+err_t tcs34725Disable(void);
+err_t tcs34725GetRawData(uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *c);
+err_t tcs34725SetIntegrationTime(tcs34725IntegrationTime_t it);
+err_t tcs34725SetGain(tcs34725Gain_t gain);
+void    tcs34725GetSensor(sensor_t *sensor);
+err_t tcs34725GetSensorEvent(sensors_event_t *event);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/sensors/gyroscopes/l3gd20.c b/reform2-lpc-fw/src/drivers/sensors/gyroscopes/l3gd20.c
new file mode 100644
index 0000000000000000000000000000000000000000..c152faea5da8e9a63aab0798b5a5df3120b302b5
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/gyroscopes/l3gd20.c
@@ -0,0 +1,346 @@
+/**************************************************************************/
+/*!
+    @file     l3gd20.c
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @brief    Driver for the ST L3GD20 I2C Gyroscope
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+#include "l3gd20.h"
+#include "core/delay/delay.h"
+#include <string.h>
+
+#define L3GD20_SENSITIVITY_250DPS  (0.00875F)   // Roughly 22/256 for fixed point match
+#define L3GD20_SENSITIVITY_500DPS  (0.0175F)    // Roughly 45/256
+#define L3GD20_SENSITIVITY_2000DPS (0.070F)     // Roughly 18/256
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+static bool     _l3gd20Initialised = false;
+static uint16_t _l3gd20MeasurementRange = 250;  // 250, 500, or 2000
+static int32_t  _l3gd20SensorID = 0;
+
+/**************************************************************************/
+/*!
+    @brief  Writes an unsigned 8 bit value over I2C
+*/
+/**************************************************************************/
+err_t l3gd20Write8 (uint8_t reg, uint8_t value)
+{
+  I2CWriteLength = 3;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = L3GD20_ADDRESS;
+  I2CMasterBuffer[1] = reg;
+  I2CMasterBuffer[2] = value;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads an unsigned 8 bit value over I2C
+*/
+/**************************************************************************/
+err_t l3gd20Read8(uint8_t reg, uint8_t *value)
+{
+  /* Write transaction */
+  I2CWriteLength = 2;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = L3GD20_ADDRESS;
+  I2CMasterBuffer[1] = reg;
+  i2cEngine();
+
+  /* Read transaction */
+  I2CWriteLength = 0;
+  I2CReadLength = 1;
+  I2CMasterBuffer[0] = L3GD20_ADDRESS | L3GD20_READBIT;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  /* Send received value back to the caller */
+  *value = I2CSlaveBuffer[0];
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads three signed 16 bit values over I2C
+*/
+/**************************************************************************/
+err_t l3gd20Read48(uint8_t reg, int16_t *x, int16_t *y, int16_t *z)
+{
+  /* Write transaction */
+  I2CWriteLength = 2;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = L3GD20_ADDRESS;
+  I2CMasterBuffer[1] = reg | (0x80);
+  i2cEngine();
+
+  /* Read transaction */
+  I2CWriteLength = 0;
+  I2CReadLength = 6;
+  I2CMasterBuffer[0] = L3GD20_ADDRESS | L3GD20_READBIT;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  /* Shift values to create properly formed integer (low byte first) */
+  *x = (int16_t)(I2CSlaveBuffer[1] << 8 | I2CSlaveBuffer[0]);
+  *y = (int16_t)(I2CSlaveBuffer[3] << 8 | I2CSlaveBuffer[2]);
+  *z = (int16_t)(I2CSlaveBuffer[5] << 8 | I2CSlaveBuffer[4]);
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Initialises the I2C block
+
+    @section EXAMPLE
+
+    @code
+    if (lis3dhInit())
+    {
+      printf("LIS3DH: %s%s", STRING(STRINGS_TEXT_No_response_on_the_I2C_bus), CFG_PRINTF_NEWLINE);
+    }
+    else
+    {
+      int16_t x, y, z;
+      while(1)
+      {
+        lis3dhPoll(&x, &y, &z);
+        printf("X: %i, Y: %i, Z: %i %s", x, y, z, CFG_PRINTF_NEWLINE);
+      }
+    }
+    @endcode
+*/
+/**************************************************************************/
+err_t l3gd20Init(void)
+{
+  uint8_t id;
+
+  /* Initialise I2C */
+  i2cInit(I2CMASTER);
+
+  /* Ping the I2C device first to see if it exists! */
+  ASSERT(i2cCheckAddress(L3GD20_ADDRESS), ERROR_I2C_DEVICENOTFOUND);
+
+  /* Check the ID register to make sure everything is correct */
+  ASSERT_STATUS(l3gd20Read8(L3GD20_REGISTER_WHO_AM_I, &id));
+
+  /* Check the address against the expected value, etc. */
+  ASSERT(id == L3GD20_ID, ERROR_I2C_DEVICENOTFOUND);
+
+  /* Set CTRL_REG1 (0x20)
+     ====================================================================
+     BIT  Symbol    Description                                   Default
+     ---  ------    --------------------------------------------- -------
+     7-6  DR1/0     Output data rate                                   00
+     5-4  BW1/0     Bandwidth selection                                00
+       3  PD        0 = Power-down mode, 1 = normal/sleep mode          0
+       2  ZEN       Z-axis enable (0 = disabled, 1 = enabled)           1
+       1  YEN       Y-axis enable (0 = disabled, 1 = enabled)           1
+       0  XEN       X-axis enable (0 = disabled, 1 = enabled)           1 */
+
+  /* Switch to normal mode and enable all three channels */
+  ASSERT_STATUS(l3gd20Write8(L3GD20_REGISTER_CTRL_REG1, 0x0F));
+
+  /* Set CTRL_REG2 (0x21)
+     ====================================================================
+     BIT  Symbol    Description                                   Default
+     ---  ------    --------------------------------------------- -------
+     5-4  HPM1/0    High-pass filter mode selection                    00
+     3-0  HPCF3..0  High-pass filter cutoff frequency selection      0000 */
+
+  /* Set CTRL_REG3 (0x22)
+     ====================================================================
+     BIT  Symbol    Description                                   Default
+     ---  ------    --------------------------------------------- -------
+       7  I1_Int1   Interrupt enable on INT1 (0=disable,1=enable)       0
+       6  I1_Boot   Boot status on INT1 (0=disable,1=enable)            0
+       5  H-Lactive Interrupt active config on INT1 (0=high,1=low)      0
+       4  PP_OD     Push-Pull/Open-Drain (0=PP, 1=OD)                   0
+       3  I2_DRDY   Data ready on DRDY/INT2 (0=disable,1=enable)        0
+       2  I2_WTM    FIFO wtrmrk int on DRDY/INT2 (0=dsbl,1=enbl)        0
+       1  I2_ORun   FIFO overrun int on DRDY/INT2 (0=dsbl,1=enbl)       0
+       0  I2_Empty  FIFI empty int on DRDY/INT2 (0=dsbl,1=enbl)         0 */
+
+  /* Set CTRL_REG4 (0x23)
+     ====================================================================
+     BIT  Symbol    Description                                   Default
+     ---  ------    --------------------------------------------- -------
+       7  BDU       Block Data Update (0=continuous, 1=LSB/MSB)         0
+       6  BLE       Big/Little-Endian (0=Data LSB, 1=Data MSB)          0
+     5-4  FS1/0     Full scale selection                               00
+                    00 = 250 dps
+                    01 = 500 dps
+                    10 = 2000 dps
+                    11 = 2000 dps
+       0  SIM       SPI Mode (0=4-wire, 1=3-wire)                       0 */
+
+  /* Enable BDU for more accurate measurements */
+  ASSERT_STATUS(l3gd20Write8(L3GD20_REGISTER_CTRL_REG4, 0x1 << 7));
+
+  /* Make sure to update the measurement range if you change it here! */
+  _l3gd20MeasurementRange = 250;
+
+  /* Set CTRL_REG5 (0x24)
+     ====================================================================
+     BIT  Symbol    Description                                   Default
+     ---  ------    --------------------------------------------- -------
+       7  BOOT      Reboot memory content (0=normal, 1=reboot)          0
+       6  FIFO_EN   FIFO enable (0=FIFO disable, 1=enable)              0
+       4  HPen      High-pass filter enable (0=disable,1=enable)        0
+     3-2  INT1_SEL  INT1 Selection config                              00
+     1-0  OUT_SEL   Out selection config                               00 */
+
+  _l3gd20Initialised = true;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Polls the device for a new X/Y/Z reading
+*/
+/**************************************************************************/
+err_t l3gd20Poll(l3gd20Data_t* data)
+{
+  uint8_t timeout = 0;
+  uint8_t buffer;
+
+  if (!_l3gd20Initialised)
+  {
+    ASSERT_STATUS(l3gd20Init());
+  }
+
+  /* Wait for a new X/Y/Z sample */
+  do
+  {
+    ASSERT_STATUS(l3gd20Read8(L3GD20_REGISTER_STATUS_REG, &buffer));
+    ASSERT(timeout++ <= L3GD20_POLL_TIMEOUT, ERROR_OPERATIONTIMEDOUT);
+  } while (!(buffer & (1<<3)));
+
+  /* Read data (in degrees per second) */
+  ASSERT_STATUS(l3gd20Read48(L3GD20_REGISTER_OUT_X_L | (1<<7), &(data->x), &(data->y), &(data->z)));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Provides the sensor_t data for this sensor
+*/
+/**************************************************************************/
+void l3gd20GetSensor(sensor_t *sensor)
+{
+  /* Clear the sensor_t object */
+  memset(sensor, 0, sizeof(sensor_t));
+
+  /* Insert the sensor name in the fixed length char array */
+  strncpy (sensor->name, "L3GD20", sizeof(sensor->name) - 1);
+  sensor->name[sizeof(sensor->name)- 1] = 0;
+  sensor->version     = 1;
+  sensor->sensor_id   = _l3gd20SensorID;
+  sensor->type        = SENSOR_TYPE_GYROSCOPE;
+  sensor->min_delay   = 0;
+
+  /* We need to do some calculations to determine resolution and maxRange in rad/s */
+  sensor->max_value   = _l3gd20MeasurementRange * SENSORS_DPS_TO_RADS;
+  sensor->min_value   = 0;
+  switch (_l3gd20MeasurementRange)
+  {
+    case 2000:
+      sensor->resolution  = (_l3gd20MeasurementRange / 32767.0F) * L3GD20_SENSITIVITY_2000DPS * SENSORS_DPS_TO_RADS;
+      break;
+    case 500:
+      sensor->resolution  = (_l3gd20MeasurementRange / 32767.0F) * L3GD20_SENSITIVITY_500DPS * SENSORS_DPS_TO_RADS;
+      break;
+    case 250:
+    default:
+      sensor->resolution  = (_l3gd20MeasurementRange / 32767.0F) * L3GD20_SENSITIVITY_250DPS * SENSORS_DPS_TO_RADS;
+      break;
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the sensor and returns the data as a sensors_event_t
+*/
+/**************************************************************************/
+err_t l3gd20GetSensorEvent(sensors_event_t *event)
+{
+  l3gd20Data_t data;
+
+  /* Clear the event */
+  memset(event, 0, sizeof(sensors_event_t));
+
+  event->version   = sizeof(sensors_event_t);
+  event->sensor_id = _l3gd20SensorID;
+  event->type      = SENSOR_TYPE_GYROSCOPE;
+  event->timestamp = delayGetTicks();
+
+  /* Retrieve values from the sensor */
+  ASSERT_STATUS(l3gd20Poll(&data));
+
+  /* The L3GD20 returns degrees per second, adjusted by sensitivity which
+   * is shown as mdps/digit in the datasheet.  To convert this to proper
+   * degrees/s multiply by the appropriate sensitivity value and then
+   * convert it to the rad/s value that sensors_event_t is expecting. */
+  switch (_l3gd20MeasurementRange)
+  {
+    case (2000):
+      event->gyro.x = data.x * L3GD20_SENSITIVITY_2000DPS * SENSORS_DPS_TO_RADS;
+      event->gyro.y = data.y * L3GD20_SENSITIVITY_2000DPS * SENSORS_DPS_TO_RADS;
+      event->gyro.z = data.z * L3GD20_SENSITIVITY_2000DPS * SENSORS_DPS_TO_RADS;
+      break;
+    case (500):
+      event->gyro.x = data.x * L3GD20_SENSITIVITY_500DPS * SENSORS_DPS_TO_RADS;
+      event->gyro.y = data.y * L3GD20_SENSITIVITY_500DPS * SENSORS_DPS_TO_RADS;
+      event->gyro.z = data.z * L3GD20_SENSITIVITY_500DPS * SENSORS_DPS_TO_RADS;
+      break;
+    case (250):
+    default:
+      event->gyro.x = data.x * L3GD20_SENSITIVITY_250DPS * SENSORS_DPS_TO_RADS;
+      event->gyro.y = data.y * L3GD20_SENSITIVITY_250DPS * SENSORS_DPS_TO_RADS;
+      event->gyro.z = data.z * L3GD20_SENSITIVITY_250DPS * SENSORS_DPS_TO_RADS;
+      break;
+  }
+
+  return ERROR_NONE;
+}
diff --git a/reform2-lpc-fw/src/drivers/sensors/gyroscopes/l3gd20.h b/reform2-lpc-fw/src/drivers/sensors/gyroscopes/l3gd20.h
new file mode 100644
index 0000000000000000000000000000000000000000..61fb703761787bd77eca656f06d269b5e8a54923
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/gyroscopes/l3gd20.h
@@ -0,0 +1,102 @@
+/**************************************************************************/
+/*!
+    @file     l3gd20.h
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _L3GD20_H_
+#define _L3GD20_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "core/i2c/i2c.h"
+#include "drivers/sensors/sensors.h"
+
+#define L3GD20_ADDRESS                (0x6B<<1)     // 1101001
+#define L3GD20_READBIT                (0x01)
+#define L3GD20_POLL_TIMEOUT           (100)         // Maximum number of read attempts in l3gd20Poll()
+#define L3GD20_ID                     BIN8(11010100)
+
+/* Struct to hold the gyroscope sensor data */
+typedef struct
+{
+  int16_t x;
+  int16_t y;
+  int16_t z;
+} l3gd20Data_t;
+
+// Core registers
+enum
+{                                               // DEFAULT    TYPE
+  L3GD20_REGISTER_WHO_AM_I            = 0x0F,   // 11010100   r
+  L3GD20_REGISTER_CTRL_REG1           = 0x20,   // 00000111   rw
+  L3GD20_REGISTER_CTRL_REG2           = 0x21,   // 00000000   rw
+  L3GD20_REGISTER_CTRL_REG3           = 0x22,   // 00000000   rw
+  L3GD20_REGISTER_CTRL_REG4           = 0x23,   // 00000000   rw
+  L3GD20_REGISTER_CTRL_REG5           = 0x24,   // 00000000   rw
+  L3GD20_REGISTER_REFERENCE           = 0x25,   // 00000000   rw
+  L3GD20_REGISTER_OUT_TEMP            = 0x26,   //            r
+  L3GD20_REGISTER_STATUS_REG          = 0x27,   //            r
+  L3GD20_REGISTER_OUT_X_L             = 0x28,   //            r
+  L3GD20_REGISTER_OUT_X_H             = 0x29,   //            r
+  L3GD20_REGISTER_OUT_Y_L             = 0x2A,   //            r
+  L3GD20_REGISTER_OUT_Y_H             = 0x2B,   //            r
+  L3GD20_REGISTER_OUT_Z_L             = 0x2C,   //            r
+  L3GD20_REGISTER_OUT_Z_H             = 0x2D,   //            r
+  L3GD20_REGISTER_FIFO_CTRL_REG       = 0x2E,   // 00000000   rw
+  L3GD20_REGISTER_FIFO_SRC_REG        = 0x2F,   //            r
+  L3GD20_REGISTER_INT1_CFG            = 0x30,   // 00000000   rw
+  L3GD20_REGISTER_INT1_SRC            = 0x31,   //            r
+  L3GD20_REGISTER_TSH_XH              = 0x32,   // 00000000   rw
+  L3GD20_REGISTER_TSH_XL              = 0x33,   // 00000000   rw
+  L3GD20_REGISTER_TSH_YH              = 0x34,   // 00000000   rw
+  L3GD20_REGISTER_TSH_YL              = 0x35,   // 00000000   rw
+  L3GD20_REGISTER_TSH_ZH              = 0x36,   // 00000000   rw
+  L3GD20_REGISTER_TSH_ZL              = 0x37,   // 00000000   rw
+  L3GD20_REGISTER_INT1_DURATION       = 0x38    // 00000000   rw
+};
+
+// Function prototypes
+err_t l3gd20Init(void);
+err_t l3gd20Poll(l3gd20Data_t* data);
+void    l3gd20GetSensor(sensor_t *sensor);
+err_t l3gd20GetSensorEvent(sensors_event_t *event);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/sensors/light/tsl2561.c b/reform2-lpc-fw/src/drivers/sensors/light/tsl2561.c
new file mode 100644
index 0000000000000000000000000000000000000000..c2590c480e46670ec6f3675b0acab1f3b0e18ed1
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/light/tsl2561.c
@@ -0,0 +1,552 @@
+/**************************************************************************/
+/*!
+    @file     tsl2561.c
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @brief    Driver for the TAOS TSL2561 I2C digital luminosity sensor
+
+    @details
+
+    The TSL2561 is a 16-bit digital luminosity sensor the approximates
+    the human eye's response to light.  It contains one broadband
+    photodiode that measures visible plus infrared light (channel 0)
+    and one infrared photodiode (channel 1).
+
+    @code
+    #include "drivers/sensors/tsl2561/tsl2561.h"
+    ...
+    uint16_t broadband, ir;
+    uint32_t lux;
+
+    // Initialise luminosity sensor
+    if (tsl2561Init())
+    {
+      printf("No response on the I2C bus from the TSL2561 ... check address/connections%s", CFG_PRINTF_NEWLINE);
+    }
+    else
+    {
+      // Optional ... default setting is 13ms with no gain
+      // Set timing to 101ms with no gain
+      tsl2561SetGain(TSL2561_GAIN_1X);
+      tsl2561SetIntegrationTime(TSL2561_INTEGRATIONTIME_101MS);
+
+      // Check luminosity level and calculate lux
+      tsl2561GetLuminosity(&broadband, &ir);
+      lux = tsl2561CalculateLux(broadband, ir);
+      printf("Broadband: %u, IR: %u, Lux: %d %s", broadband, ir, lux, CFG_PRINTF_NEWLINE);
+    }
+
+    @endcode
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+#include "tsl2561.h"
+#include "core/delay/delay.h"
+#include <string.h>
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+static bool                     _tsl2561Initialised = false;
+static bool                     _tsl2561AutoGain = false;
+static tsl2561IntegrationTime_t _tsl2561IntegrationTime = TSL2561_INTEGRATIONTIME_13MS;
+static tsl2561Gain_t            _tsl2561Gain = TSL2561_GAIN_1X;
+static int32_t                  _tsl2561SensorID = 0;
+
+/**************************************************************************/
+/*!
+    @brief  Sends a single command byte over I2C
+*/
+/**************************************************************************/
+err_t tsl2561WriteCmd (uint8_t cmd)
+{
+  I2CWriteLength = 2;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = TSL2561_ADDRESS;
+  I2CMasterBuffer[1] = cmd;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Writes an 8 bit values over I2C
+*/
+/**************************************************************************/
+err_t tsl2561Write8 (uint8_t reg, uint32_t value)
+{
+  I2CWriteLength = 3;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = TSL2561_ADDRESS;
+  I2CMasterBuffer[1] = reg;
+  I2CMasterBuffer[2] = (value & 0xFF);
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads a 16 bit values over I2C
+*/
+/**************************************************************************/
+err_t tsl2561Read16(uint8_t reg, uint16_t *value)
+{
+  /* Write transaction */
+  I2CWriteLength = 2;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = TSL2561_ADDRESS;
+  I2CMasterBuffer[1] = reg;
+  i2cEngine();
+
+  /* Read transaction */
+  I2CWriteLength = 0;
+  I2CReadLength = 2;
+  I2CMasterBuffer[0] = TSL2561_ADDRESS | TSL2561_READBIT;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  /* Shift values to create properly formed integer (low byte first) */
+  *value = (I2CSlaveBuffer[0] | (I2CSlaveBuffer[1] << 8));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Enables the device
+*/
+/**************************************************************************/
+err_t tsl2561Enable(void)
+{
+  /* Enable the device by setting the control bit to 0x03 */
+  return tsl2561Write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWERON);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Disables the device (putting it in lower power sleep mode)
+*/
+/**************************************************************************/
+err_t tsl2561Disable(void)
+{
+  /* Turn the device off to save power */
+  return tsl2561Write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWEROFF);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Private function to read luminosity on both channels
+*/
+/**************************************************************************/
+err_t tsl2561GetData (uint16_t *broadband, uint16_t *ir)
+{
+  /* Enable the device by setting the control bit to 0x03 */
+  ASSERT_STATUS(tsl2561Enable());
+
+  /* Wait x ms for ADC to complete */
+  switch (_tsl2561IntegrationTime)
+  {
+    case TSL2561_INTEGRATIONTIME_13MS:
+      delay(14);
+      break;
+    case TSL2561_INTEGRATIONTIME_101MS:
+      delay(102);
+      break;
+    default:
+      delay(403);
+      break;
+  }
+
+  /* Reads a two byte value from channel 0 (visible + infrared) */
+  ASSERT_STATUS(tsl2561Read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW, broadband));
+
+  /* Reads a two byte value from channel 1 (infrared) */
+  ASSERT_STATUS(tsl2561Read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW, ir));
+
+  /* Turn the device off to save power */
+  ASSERT_STATUS(tsl2561Disable());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Initialises the I2C block
+*/
+/**************************************************************************/
+err_t tsl2561Init(void)
+{
+  /* Initialise I2C */
+  i2cInit(I2CMASTER);
+
+  /* Ping the I2C device first to see if it exists! */
+  ASSERT(i2cCheckAddress(TSL2561_ADDRESS), ERROR_I2C_DEVICENOTFOUND);
+
+  /* Note: by default, the device is in power down mode on bootup */
+  _tsl2561Initialised = true;
+
+  /* Set default integration time and gain */
+  ASSERT_STATUS(tsl2561SetIntegrationTime(_tsl2561IntegrationTime));
+  ASSERT_STATUS(tsl2561SetGain(_tsl2561Gain));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Enables or disables the auto-gain settings when reading
+            data from the sensor
+*/
+/**************************************************************************/
+void tsl2561EnableAutoGain(bool enable)
+{
+   _tsl2561AutoGain = enable ? true : false;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the integration time for the sensor.
+*/
+/**************************************************************************/
+err_t tsl2561SetIntegrationTime(tsl2561IntegrationTime_t time)
+{
+  if (!_tsl2561Initialised)
+  {
+    ASSERT_STATUS(tsl2561Init());
+  }
+
+  /* Enable the device by setting the control bit to 0x03 */
+  ASSERT_STATUS(tsl2561Enable());
+
+  /* Update the timing register */
+  ASSERT_STATUS(tsl2561Write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, time | _tsl2561Gain));
+
+  /* Update value placeholders */
+  _tsl2561IntegrationTime = time;
+
+  /* Turn the device off to save power */
+  ASSERT_STATUS(tsl2561Disable());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the integration time for the sensor.
+*/
+/**************************************************************************/
+err_t tsl2561SetGain(tsl2561Gain_t gain)
+{
+  if (!_tsl2561Initialised)
+  {
+    ASSERT_STATUS(tsl2561Init());
+  }
+
+  /* Enable the device by setting the control bit to 0x03 */
+  ASSERT_STATUS(tsl2561Enable());
+
+  /* Update the timing register */
+  ASSERT_STATUS(tsl2561Write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, _tsl2561IntegrationTime | gain));
+
+  /* Update value placeholders */
+  _tsl2561Gain = gain;
+
+  /* Turn the device off to save power */
+  ASSERT_STATUS(tsl2561Disable());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the broadband (mixed lighting) and IR only values from
+            the TSL2561, adjusting gain if auto-gain is enabled
+*/
+/**************************************************************************/
+err_t tsl2561GetLuminosity (uint16_t *broadband, uint16_t *ir)
+{
+  bool valid = false;
+
+  if (!_tsl2561Initialised)
+  {
+    ASSERT_STATUS(tsl2561Init());
+  }
+
+  /* If Auto gain disabled get a single reading and continue */
+  if(!_tsl2561AutoGain)
+  {
+    return tsl2561GetData (broadband, ir);
+  }
+
+  /* Read data until we find a valid range */
+  bool _agcCheck = false;
+  do
+  {
+    uint16_t _b, _ir;
+    uint16_t _hi, _lo;
+    tsl2561IntegrationTime_t _it = _tsl2561IntegrationTime;
+
+    /* Get the hi/low threshold for the current integration time */
+    switch(_it)
+    {
+      case TSL2561_INTEGRATIONTIME_13MS:
+        _hi = TSL2561_AGC_THI_13MS;
+        _lo = TSL2561_AGC_TLO_13MS;
+        break;
+      case TSL2561_INTEGRATIONTIME_101MS:
+        _hi = TSL2561_AGC_THI_101MS;
+        _lo = TSL2561_AGC_TLO_101MS;
+        break;
+      default:
+        _hi = TSL2561_AGC_THI_402MS;
+        _lo = TSL2561_AGC_TLO_402MS;
+        break;
+    }
+
+    ASSERT_STATUS(tsl2561GetData(&_b, &_ir));
+
+    /* Run an auto-gain check if we haven't already done so ... */
+    if (!_agcCheck)
+    {
+      if ((_b < _lo) && (_tsl2561Gain == TSL2561_GAIN_1X))
+      {
+        /* Increase the gain and try again */
+        ASSERT_STATUS(tsl2561SetGain(TSL2561_GAIN_16X));
+        /* Drop the previous conversion results */
+        ASSERT_STATUS(tsl2561GetData(&_b, &_ir));
+        /* Set a flag to indicate we've adjusted the gain */
+        _agcCheck = true;
+      }
+      else if ((_b > _hi) && (_tsl2561Gain == TSL2561_GAIN_16X))
+      {
+        /* Drop gain to 1x and try again */
+        ASSERT_STATUS(tsl2561SetGain(TSL2561_GAIN_1X));
+        /* Drop the previous conversion results */
+        ASSERT_STATUS(tsl2561GetData(&_b, &_ir));
+        /* Set a flag to indicate we've adjusted the gain */
+        _agcCheck = true;
+      }
+      else
+      {
+        /* Nothing to look at here, keep moving ....
+           Reading is either valid, or we're already at the chips limits */
+        *broadband = _b;
+        *ir = _ir;
+        valid = true;
+      }
+    }
+    else
+    {
+      /* If we've already adjusted the gain once, just return the new results.
+         This avoids endless loops where a value is at one extreme pre-gain,
+         and the the other extreme post-gain */
+      *broadband = _b;
+      *ir = _ir;
+      valid = true;
+    }
+  } while (!valid);
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Calculates LUX from the supplied ch0 (broadband) and ch1
+            (IR) readings
+*/
+/**************************************************************************/
+uint32_t tsl2561CalculateLux(uint16_t ch0, uint16_t ch1)
+{
+  unsigned long chScale;
+  unsigned long channel1;
+  unsigned long channel0;
+  uint32_t lux;
+  unsigned long temp;
+  unsigned long ratio1;
+  unsigned long ratio;
+  unsigned int b, m;
+
+  /* Make sure the sensor isn't saturated! */
+  uint16_t clipThreshold;
+  switch (_tsl2561IntegrationTime)
+  {
+    case TSL2561_INTEGRATIONTIME_13MS:
+      /* Ti 13ms, max value is 5047 */
+      clipThreshold = TSL2561_CLIPPING_13MS;
+      break;
+    case TSL2561_INTEGRATIONTIME_101MS:
+      /* Ti 13ms, max value is 37177 */
+      clipThreshold = TSL2561_CLIPPING_101MS;
+      break;
+    default:
+      /* Ti 13ms, max value is 65535 */
+      clipThreshold = TSL2561_CLIPPING_402MS;
+      break;
+  }
+
+  /* Return 0 is sensor is saturated */
+  if ((ch0 > clipThreshold) || (ch1 > clipThreshold))
+  {
+    return 0;
+  }
+
+  /* Scale factor for integration time */
+  switch (_tsl2561IntegrationTime)
+  {
+    case TSL2561_INTEGRATIONTIME_13MS:
+      chScale = TSL2561_LUX_CHSCALE_TINT0;
+      break;
+    case TSL2561_INTEGRATIONTIME_101MS:
+      chScale = TSL2561_LUX_CHSCALE_TINT1;
+      break;
+    default: // No scaling ... integration time = 402ms
+      chScale = (1 << TSL2561_LUX_CHSCALE);
+      break;
+  }
+
+  /* Scale factor for gain (1x or 16x) */
+  if (!_tsl2561Gain) chScale = chScale << 4;
+
+  /* Scale the channel values */
+  channel0 = (ch0 * chScale) >> TSL2561_LUX_CHSCALE;
+  channel1 = (ch1 * chScale) >> TSL2561_LUX_CHSCALE;
+
+  /* Find the ratio of the channel values (Channel1/Channel0) */
+  ratio1 = 0;
+  if (channel0 != 0) ratio1 = (channel1 << (TSL2561_LUX_RATIOSCALE+1)) / channel0;
+
+  /* Round the ratio values */
+  ratio = (ratio1 + 1) >> 1;
+
+#ifdef TSL2561_PACKAGE_CS
+  if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1C))
+    {b=TSL2561_LUX_B1C; m=TSL2561_LUX_M1C;}
+  else if (ratio <= TSL2561_LUX_K2C)
+    {b=TSL2561_LUX_B2C; m=TSL2561_LUX_M2C;}
+  else if (ratio <= TSL2561_LUX_K3C)
+    {b=TSL2561_LUX_B3C; m=TSL2561_LUX_M3C;}
+  else if (ratio <= TSL2561_LUX_K4C)
+    {b=TSL2561_LUX_B4C; m=TSL2561_LUX_M4C;}
+  else if (ratio <= TSL2561_LUX_K5C)
+    {b=TSL2561_LUX_B5C; m=TSL2561_LUX_M5C;}
+  else if (ratio <= TSL2561_LUX_K6C)
+    {b=TSL2561_LUX_B6C; m=TSL2561_LUX_M6C;}
+  else if (ratio <= TSL2561_LUX_K7C)
+    {b=TSL2561_LUX_B7C; m=TSL2561_LUX_M7C;}
+  else if (ratio > TSL2561_LUX_K8C)
+    {b=TSL2561_LUX_B8C; m=TSL2561_LUX_M8C;}
+#else
+  if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1T))
+    {b=TSL2561_LUX_B1T; m=TSL2561_LUX_M1T;}
+  else if (ratio <= TSL2561_LUX_K2T)
+    {b=TSL2561_LUX_B2T; m=TSL2561_LUX_M2T;}
+  else if (ratio <= TSL2561_LUX_K3T)
+    {b=TSL2561_LUX_B3T; m=TSL2561_LUX_M3T;}
+  else if (ratio <= TSL2561_LUX_K4T)
+    {b=TSL2561_LUX_B4T; m=TSL2561_LUX_M4T;}
+  else if (ratio <= TSL2561_LUX_K5T)
+    {b=TSL2561_LUX_B5T; m=TSL2561_LUX_M5T;}
+  else if (ratio <= TSL2561_LUX_K6T)
+    {b=TSL2561_LUX_B6T; m=TSL2561_LUX_M6T;}
+  else if (ratio <= TSL2561_LUX_K7T)
+    {b=TSL2561_LUX_B7T; m=TSL2561_LUX_M7T;}
+  else if (ratio > TSL2561_LUX_K8T)
+    {b=TSL2561_LUX_B8T; m=TSL2561_LUX_M8T;}
+#endif
+
+  temp = ((channel0 * b) - (channel1 * m));
+
+  /* Round lsb (2^(LUX_SCALE-1)) */
+  temp += (1 << (TSL2561_LUX_LUXSCALE-1));
+
+  /* Strip off fractional portion */
+  lux = temp >> TSL2561_LUX_LUXSCALE;
+
+  return lux;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Provides the sensor_t data for this sensor
+*/
+/**************************************************************************/
+void tsl2561GetSensor(sensor_t *sensor)
+{
+  /* Clear the sensor_t object */
+  memset(sensor, 0, sizeof(sensor_t));
+
+  /* Note: Max lux can't be provided accurately because the max */
+  /* value changes depending on the light source.  Fluorescent  */
+  /* lights will have a higher max lux that can be calculated   */
+  /* by the visible + IR sensors than incandescent lights, etc. */
+
+  /* Insert the sensor name in the fixed length char array */
+  strncpy (sensor->name, "TSL2561", sizeof(sensor->name) - 1);
+  sensor->name[sizeof(sensor->name)- 1] = 0;
+  sensor->version     = 1;
+  sensor->sensor_id   = _tsl2561SensorID;
+  sensor->type        = SENSOR_TYPE_LIGHT;
+  sensor->min_delay   = 0;
+  sensor->max_value   = 17000.0;  /* Based on trial and error ... confirm! */
+  sensor->min_value   = 0.0;
+  sensor->resolution  = 1.0;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the sensor and returns the data as a sensors_event_t
+*/
+/**************************************************************************/
+err_t tsl2561GetSensorEvent(sensors_event_t *event)
+{
+  uint16_t broadband, ir;
+
+  /* Clear the event */
+  memset(event, 0, sizeof(sensors_event_t));
+
+  event->version   = sizeof(sensors_event_t);
+  event->sensor_id = _tsl2561SensorID;
+  event->type      = SENSOR_TYPE_LIGHT;
+  event->timestamp = delayGetTicks();
+
+  /* Calculate the actual lux value */
+  ASSERT_STATUS(tsl2561GetLuminosity(&broadband, &ir));
+  event->light = tsl2561CalculateLux(broadband, ir);
+
+  return ERROR_NONE;
+}
diff --git a/reform2-lpc-fw/src/drivers/sensors/light/tsl2561.h b/reform2-lpc-fw/src/drivers/sensors/light/tsl2561.h
new file mode 100644
index 0000000000000000000000000000000000000000..8fe1ae885d9e1a889e6bdbdd8ce5dde2347fb69e
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/light/tsl2561.h
@@ -0,0 +1,178 @@
+/**************************************************************************/
+/*!
+    @file     tsl2561.h
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _TSL2561_H_
+#define _TSL2561_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "core/i2c/i2c.h"
+#include "drivers/sensors/sensors.h"
+
+#define TSL2561_PACKAGE_CS                  // Lux calculations differ slightly for CS package
+// #define TSL2561_PACKAGE_T_FN_CL
+
+#define TSL2561_ADDRESS           (0x39<<1) // Assumes ADDR = floating
+#define TSL2561_READBIT           (0x01)
+
+#define TSL2561_COMMAND_BIT       (0x80)    // Must be 1
+#define TSL2561_CLEAR_BIT         (0x40)    // Clears any pending interrupt (write 1 to clear)
+#define TSL2561_WORD_BIT          (0x20)    // 1 = read/write word (rather than byte)
+#define TSL2561_BLOCK_BIT         (0x10)    // 1 = using block read/write
+
+#define TSL2561_CONTROL_POWERON   (0x03)
+#define TSL2561_CONTROL_POWEROFF  (0x00)
+
+#define TSL2561_LUX_LUXSCALE      (14)      // Scale by 2^14
+#define TSL2561_LUX_RATIOSCALE    (9)       // Scale ratio by 2^9
+#define TSL2561_LUX_CHSCALE       (10)      // Scale channel values by 2^10
+#define TSL2561_LUX_CHSCALE_TINT0 (0x7517)  // 322/11 * 2^TSL2561_LUX_CHSCALE
+#define TSL2561_LUX_CHSCALE_TINT1 (0x0FE7)  // 322/81 * 2^TSL2561_LUX_CHSCALE
+
+// T, FN and CL package values
+#define TSL2561_LUX_K1T           (0x0040)  // 0.125 * 2^RATIO_SCALE
+#define TSL2561_LUX_B1T           (0x01f2)  // 0.0304 * 2^LUX_SCALE
+#define TSL2561_LUX_M1T           (0x01be)  // 0.0272 * 2^LUX_SCALE
+#define TSL2561_LUX_K2T           (0x0080)  // 0.250 * 2^RATIO_SCALE
+#define TSL2561_LUX_B2T           (0x0214)  // 0.0325 * 2^LUX_SCALE
+#define TSL2561_LUX_M2T           (0x02d1)  // 0.0440 * 2^LUX_SCALE
+#define TSL2561_LUX_K3T           (0x00c0)  // 0.375 * 2^RATIO_SCALE
+#define TSL2561_LUX_B3T           (0x023f)  // 0.0351 * 2^LUX_SCALE
+#define TSL2561_LUX_M3T           (0x037b)  // 0.0544 * 2^LUX_SCALE
+#define TSL2561_LUX_K4T           (0x0100)  // 0.50 * 2^RATIO_SCALE
+#define TSL2561_LUX_B4T           (0x0270)  // 0.0381 * 2^LUX_SCALE
+#define TSL2561_LUX_M4T           (0x03fe)  // 0.0624 * 2^LUX_SCALE
+#define TSL2561_LUX_K5T           (0x0138)  // 0.61 * 2^RATIO_SCALE
+#define TSL2561_LUX_B5T           (0x016f)  // 0.0224 * 2^LUX_SCALE
+#define TSL2561_LUX_M5T           (0x01fc)  // 0.0310 * 2^LUX_SCALE
+#define TSL2561_LUX_K6T           (0x019a)  // 0.80 * 2^RATIO_SCALE
+#define TSL2561_LUX_B6T           (0x00d2)  // 0.0128 * 2^LUX_SCALE
+#define TSL2561_LUX_M6T           (0x00fb)  // 0.0153 * 2^LUX_SCALE
+#define TSL2561_LUX_K7T           (0x029a)  // 1.3 * 2^RATIO_SCALE
+#define TSL2561_LUX_B7T           (0x0018)  // 0.00146 * 2^LUX_SCALE
+#define TSL2561_LUX_M7T           (0x0012)  // 0.00112 * 2^LUX_SCALE
+#define TSL2561_LUX_K8T           (0x029a)  // 1.3 * 2^RATIO_SCALE
+#define TSL2561_LUX_B8T           (0x0000)  // 0.000 * 2^LUX_SCALE
+#define TSL2561_LUX_M8T           (0x0000)  // 0.000 * 2^LUX_SCALE
+
+// CS package values
+#define TSL2561_LUX_K1C           (0x0043)  // 0.130 * 2^RATIO_SCALE
+#define TSL2561_LUX_B1C           (0x0204)  // 0.0315 * 2^LUX_SCALE
+#define TSL2561_LUX_M1C           (0x01ad)  // 0.0262 * 2^LUX_SCALE
+#define TSL2561_LUX_K2C           (0x0085)  // 0.260 * 2^RATIO_SCALE
+#define TSL2561_LUX_B2C           (0x0228)  // 0.0337 * 2^LUX_SCALE
+#define TSL2561_LUX_M2C           (0x02c1)  // 0.0430 * 2^LUX_SCALE
+#define TSL2561_LUX_K3C           (0x00c8)  // 0.390 * 2^RATIO_SCALE
+#define TSL2561_LUX_B3C           (0x0253)  // 0.0363 * 2^LUX_SCALE
+#define TSL2561_LUX_M3C           (0x0363)  // 0.0529 * 2^LUX_SCALE
+#define TSL2561_LUX_K4C           (0x010a)  // 0.520 * 2^RATIO_SCALE
+#define TSL2561_LUX_B4C           (0x0282)  // 0.0392 * 2^LUX_SCALE
+#define TSL2561_LUX_M4C           (0x03df)  // 0.0605 * 2^LUX_SCALE
+#define TSL2561_LUX_K5C           (0x014d)  // 0.65 * 2^RATIO_SCALE
+#define TSL2561_LUX_B5C           (0x0177)  // 0.0229 * 2^LUX_SCALE
+#define TSL2561_LUX_M5C           (0x01dd)  // 0.0291 * 2^LUX_SCALE
+#define TSL2561_LUX_K6C           (0x019a)  // 0.80 * 2^RATIO_SCALE
+#define TSL2561_LUX_B6C           (0x0101)  // 0.0157 * 2^LUX_SCALE
+#define TSL2561_LUX_M6C           (0x0127)  // 0.0180 * 2^LUX_SCALE
+#define TSL2561_LUX_K7C           (0x029a)  // 1.3 * 2^RATIO_SCALE
+#define TSL2561_LUX_B7C           (0x0037)  // 0.00338 * 2^LUX_SCALE
+#define TSL2561_LUX_M7C           (0x002b)  // 0.00260 * 2^LUX_SCALE
+#define TSL2561_LUX_K8C           (0x029a)  // 1.3 * 2^RATIO_SCALE
+#define TSL2561_LUX_B8C           (0x0000)  // 0.000 * 2^LUX_SCALE
+#define TSL2561_LUX_M8C           (0x0000)  // 0.000 * 2^LUX_SCALE
+
+// Auto-gain thresholds
+#define TSL2561_AGC_THI_13MS      (4850)    // Max value at Ti 13ms = 5047
+#define TSL2561_AGC_TLO_13MS      (100)
+#define TSL2561_AGC_THI_101MS     (36000)   // Max value at Ti 101ms = 37177
+#define TSL2561_AGC_TLO_101MS     (200)
+#define TSL2561_AGC_THI_402MS     (63000)   // Max value at Ti 402ms = 65535
+#define TSL2561_AGC_TLO_402MS     (500)
+
+// Clipping thresholds
+#define TSL2561_CLIPPING_13MS     (4900)
+#define TSL2561_CLIPPING_101MS    (37000)
+#define TSL2561_CLIPPING_402MS    (65000)
+
+enum
+{
+  TSL2561_REGISTER_CONTROL          = 0x00,
+  TSL2561_REGISTER_TIMING           = 0x01,
+  TSL2561_REGISTER_THRESHHOLDL_LOW  = 0x02,
+  TSL2561_REGISTER_THRESHHOLDL_HIGH = 0x03,
+  TSL2561_REGISTER_THRESHHOLDH_LOW  = 0x04,
+  TSL2561_REGISTER_THRESHHOLDH_HIGH = 0x05,
+  TSL2561_REGISTER_INTERRUPT        = 0x06,
+  TSL2561_REGISTER_CRC              = 0x08,
+  TSL2561_REGISTER_ID               = 0x0A,
+  TSL2561_REGISTER_CHAN0_LOW        = 0x0C,
+  TSL2561_REGISTER_CHAN0_HIGH       = 0x0D,
+  TSL2561_REGISTER_CHAN1_LOW        = 0x0E,
+  TSL2561_REGISTER_CHAN1_HIGH       = 0x0F
+};
+
+typedef enum
+{
+  TSL2561_INTEGRATIONTIME_13MS      = 0x00,    // 13.7ms
+  TSL2561_INTEGRATIONTIME_101MS     = 0x01,    // 101ms
+  TSL2561_INTEGRATIONTIME_402MS     = 0x02     // 402ms
+}
+tsl2561IntegrationTime_t;
+
+typedef enum
+{
+  TSL2561_GAIN_1X                   = 0x00,    // No gain
+  TSL2561_GAIN_16X                  = 0x10,    // 16x gain
+}
+tsl2561Gain_t;
+
+err_t  tsl2561Init(void);
+void     tsl2561EnableAutoGain(bool enable);
+err_t  tsl2561SetIntegrationTime(tsl2561IntegrationTime_t time);
+err_t  tsl2561SetGain(tsl2561Gain_t gain);
+err_t  tsl2561GetLuminosity (uint16_t *broadband, uint16_t *ir);
+uint32_t tsl2561CalculateLux(uint16_t ch0, uint16_t ch1);
+void     tsl2561GetSensor(sensor_t *sensor);
+err_t  tsl2561GetSensorEvent(sensors_event_t *event);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/sensors/magnetometers/lsm303mag.c b/reform2-lpc-fw/src/drivers/sensors/magnetometers/lsm303mag.c
new file mode 100644
index 0000000000000000000000000000000000000000..c4301d9d89b4c3555c68081e7f51dc611857a40a
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/magnetometers/lsm303mag.c
@@ -0,0 +1,303 @@
+/**************************************************************************/
+/*!
+    @file     lsm303mag.c
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @brief    Driver for the ST LSM303DLHC I2C magnetometer
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+#include "lsm303mag.h"
+#include "core/delay/delay.h"
+#include <string.h>
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+static bool               _lsm303magInitialised = false;
+static int32_t            _lsm303magSensorID = 0;
+static lsm303MagData_t    _lsm303magData;
+static lsm303MagGain_t    _lsm303magGain = LSM303_MAGGAIN_1_3;
+static float              _lsm303mag_Gauss_LSB_XY = 1100.0F; // Varies with gain
+static float              _lsm303mag_Gauss_LSB_Z = 980.0F;   // Varies with gain
+
+/**************************************************************************/
+/*!
+    @brief  Writes an unsigned 8 bit values over I2C
+*/
+/**************************************************************************/
+err_t lsm303magWrite8(uint8_t addr, uint8_t reg, uint8_t value)
+{
+  I2CWriteLength = 3;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = addr;
+  I2CMasterBuffer[1] = reg;
+  I2CMasterBuffer[2] = (value);
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads an unsigned 8 bit value over I2C
+*/
+/**************************************************************************/
+err_t lsm303magRead8(uint8_t addr, uint8_t reg, uint8_t *value)
+{
+  /* Write transaction */
+  I2CWriteLength = 2;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = addr;
+  I2CMasterBuffer[1] = reg;
+  i2cEngine();
+
+  /* Read transaction */
+  I2CWriteLength = 0;
+  I2CReadLength = 1;
+  I2CMasterBuffer[0] = addr | 0x01;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  /* Send received value back to the caller */
+  *value = I2CSlaveBuffer[0];
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads three signed 16 bit values over I2C
+*/
+/**************************************************************************/
+err_t lsm303magRead48(uint8_t addr, uint8_t reg, uint8_t buffer[6])
+{
+  /* Write transaction */
+  I2CWriteLength = 2;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = addr;
+  I2CMasterBuffer[1] = reg | (0x80);
+  i2cEngine();
+
+  /* Read transaction */
+  I2CWriteLength = 0;
+  I2CReadLength = 6;
+  I2CMasterBuffer[0] = addr | 0x01;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  uint8_t i;
+  for (i = 0; i < 6; i++)
+  {
+    buffer[i] = I2CSlaveBuffer[i];
+  }
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Initialises the I2C block
+*/
+/**************************************************************************/
+err_t lsm303magInit(void)
+{
+  // Initialise I2C
+  i2cInit(I2CMASTER);
+
+  /* Ping the I2C device first to see if it exists! */
+  ASSERT(i2cCheckAddress(LSM303_ADDRESS_MAG), ERROR_I2C_DEVICENOTFOUND);
+
+  /* Enable the magnetometer (continuous conversion) */
+  ASSERT_STATUS(lsm303magWrite8(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_MR_REG_M, 0x00));
+
+  _lsm303magInitialised = true;
+
+  /* Set default gain */
+  ASSERT_STATUS(lsm303magSetGain(_lsm303magGain));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the gain on the magnetometer (controls sensitivity)
+*/
+/**************************************************************************/
+err_t lsm303magSetGain(lsm303MagGain_t gain)
+{
+  if (!_lsm303magInitialised)
+  {
+    ASSERT_STATUS(lsm303magInit());
+  }
+
+  // Enable the device by setting the control bit to 0x03
+  ASSERT_STATUS(lsm303magWrite8(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_CRB_REG_M, (uint8_t)gain));
+
+  _lsm303magGain = gain;
+
+  switch(gain)
+  {
+    case LSM303_MAGGAIN_1_3:
+      _lsm303mag_Gauss_LSB_XY = 1100;
+      _lsm303mag_Gauss_LSB_Z = 980;
+      break;
+    case LSM303_MAGGAIN_1_9:
+      _lsm303mag_Gauss_LSB_XY = 855;
+      _lsm303mag_Gauss_LSB_Z = 760;
+      break;
+    case LSM303_MAGGAIN_2_5:
+      _lsm303mag_Gauss_LSB_XY = 670;
+      _lsm303mag_Gauss_LSB_Z = 600;
+      break;
+    case LSM303_MAGGAIN_4_0:
+      _lsm303mag_Gauss_LSB_XY = 450;
+      _lsm303mag_Gauss_LSB_Z = 400;
+      break;
+    case LSM303_MAGGAIN_4_7:
+      _lsm303mag_Gauss_LSB_XY = 400;
+      _lsm303mag_Gauss_LSB_Z = 255;
+      break;
+    case LSM303_MAGGAIN_5_6:
+      _lsm303mag_Gauss_LSB_XY = 330;
+      _lsm303mag_Gauss_LSB_Z = 295;
+      break;
+    case LSM303_MAGGAIN_8_1:
+      _lsm303mag_Gauss_LSB_XY = 230;
+      _lsm303mag_Gauss_LSB_Z = 205;
+      break;
+  }
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the current magnetometer values
+*/
+/**************************************************************************/
+err_t  lsm303magReadRaw(int16_t *x, int16_t *y, int16_t *z)
+{
+  uint8_t buffer[6] = { 0, 0, 0, 0, 0, 0 };
+
+  if (!_lsm303magInitialised)
+  {
+    ASSERT_STATUS(lsm303magInit());
+  }
+
+  /* Read the magnetometer */
+  ASSERT_STATUS(lsm303magRead48(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_OUT_X_H_M, buffer));
+
+  /* Shift values to create properly formed integer (low byte first) */
+  /* Note: Magnetometer is X/Z/Y, high byte then low */
+  *x = (int16_t)(buffer[1] | (buffer[0] << 8));
+  *z = (int16_t)(buffer[3] | (buffer[2] << 8));
+  *y = (int16_t)(buffer[5] | (buffer[4] << 8));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the current magnetometer values
+*/
+/**************************************************************************/
+err_t lsm303magRead(void)
+{
+  uint8_t buffer[6] = { 0, 0, 0, 0, 0, 0 };
+
+  if (!_lsm303magInitialised)
+  {
+    ASSERT_STATUS(lsm303magInit());
+  }
+
+  /* Read the magnetometer */
+  ASSERT_STATUS(lsm303magRead48(LSM303_ADDRESS_MAG, LSM303_REGISTER_MAG_OUT_X_H_M, buffer));
+
+  /* Shift values to create properly formed integer (low byte first) */
+  /* Note: Magnetometer is X/Z/Y, high byte then low */
+  _lsm303magData.x = (int16_t)(buffer[1] | (buffer[0] << 8));
+  _lsm303magData.z = (int16_t)(buffer[3] | (buffer[2] << 8));
+  _lsm303magData.y = (int16_t)(buffer[5] | (buffer[4] << 8));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Provides the sensor_t data for this sensor
+*/
+/**************************************************************************/
+void lsm303magGetSensor(sensor_t *sensor)
+{
+  /* Clear the sensor_t object */
+  memset(sensor, 0, sizeof(sensor_t));
+
+  /* Insert the sensor name in the fixed length char array */
+  strncpy (sensor->name, "LSM303DLHC", sizeof(sensor->name) - 1);
+  sensor->name[sizeof(sensor->name)- 1] = 0;
+  sensor->version     = 1;
+  sensor->sensor_id   = _lsm303magSensorID;
+  sensor->type        = SENSOR_TYPE_MAGNETIC_FIELD;
+  sensor->min_delay   = 0;
+  sensor->max_value   = 1.0;                  // TBD
+  sensor->min_value   = 1.0;                  // TBD
+  sensor->resolution  = 1.0;                  // TBD
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the sensor and returns the data as a sensors_event_t
+*/
+/**************************************************************************/
+err_t lsm303magGetSensorEvent(sensors_event_t *event)
+{
+  /* Clear the event */
+  memset(event, 0, sizeof(sensors_event_t));
+
+  event->version   = sizeof(sensors_event_t);
+  event->sensor_id = _lsm303magSensorID;
+  event->type      = SENSOR_TYPE_MAGNETIC_FIELD;
+  event->timestamp = delayGetTicks();
+
+  /* Convert units to micro-Tesla (1 Gauss = 1 micro-Tesla) */
+  ASSERT_STATUS(lsm303magRead());
+  event->magnetic.x = _lsm303magData.x / _lsm303mag_Gauss_LSB_XY * SENSORS_GAUSS_TO_MICROTESLA;
+  event->magnetic.y = _lsm303magData.y / _lsm303mag_Gauss_LSB_XY * SENSORS_GAUSS_TO_MICROTESLA;
+  event->magnetic.z = _lsm303magData.z / _lsm303mag_Gauss_LSB_Z * SENSORS_GAUSS_TO_MICROTESLA;
+
+  return ERROR_NONE;
+}
+
diff --git a/reform2-lpc-fw/src/drivers/sensors/magnetometers/lsm303mag.h b/reform2-lpc-fw/src/drivers/sensors/magnetometers/lsm303mag.h
new file mode 100644
index 0000000000000000000000000000000000000000..52c7d7c9c112fffe1d89dbf92031c325a5e714f4
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/magnetometers/lsm303mag.h
@@ -0,0 +1,96 @@
+/**************************************************************************/
+/*!
+    @file     lsm303mag.h
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _LSM303DLHC_MAG_H_
+#define _LSM303DLHC_MAG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "core/i2c/i2c.h"
+#include "drivers/sensors/sensors.h"
+
+#define LSM303_ADDRESS_MAG        (0x1E<<1) // 0011110
+
+enum {
+  LSM303_REGISTER_MAG_CRA_REG_M             = 0x00,
+  LSM303_REGISTER_MAG_CRB_REG_M             = 0x01,
+  LSM303_REGISTER_MAG_MR_REG_M              = 0x02,
+  LSM303_REGISTER_MAG_OUT_X_H_M             = 0x03,
+  LSM303_REGISTER_MAG_OUT_X_L_M             = 0x04,
+  LSM303_REGISTER_MAG_OUT_Z_H_M             = 0x05,
+  LSM303_REGISTER_MAG_OUT_Z_L_M             = 0x06,
+  LSM303_REGISTER_MAG_OUT_Y_H_M             = 0x07,
+  LSM303_REGISTER_MAG_OUT_Y_L_M             = 0x08,
+  LSM303_REGISTER_MAG_SR_REG_Mg             = 0x09,
+  LSM303_REGISTER_MAG_IRA_REG_M             = 0x0A,
+  LSM303_REGISTER_MAG_IRB_REG_M             = 0x0B,
+  LSM303_REGISTER_MAG_IRC_REG_M             = 0x0C,
+  LSM303_REGISTER_MAG_TEMP_OUT_H_M          = 0x31,
+  LSM303_REGISTER_MAG_TEMP_OUT_L_M          = 0x32
+};
+
+typedef enum
+{
+  LSM303_MAGGAIN_1_3                        = 0x20,  // +/- 1.3
+  LSM303_MAGGAIN_1_9                        = 0x40,  // +/- 1.9
+  LSM303_MAGGAIN_2_5                        = 0x60,  // +/- 2.5
+  LSM303_MAGGAIN_4_0                        = 0x80,  // +/- 4.0
+  LSM303_MAGGAIN_4_7                        = 0xA0,  // +/- 4.7
+  LSM303_MAGGAIN_5_6                        = 0xC0,  // +/- 5.6
+  LSM303_MAGGAIN_8_1                        = 0xE0   // +/- 8.1
+} lsm303MagGain_t;
+
+typedef struct lsm303MagData_s
+{
+  float x;
+  float y;
+  float z;
+} lsm303MagData_t;
+
+err_t  lsm303magInit(void);
+err_t  lsm303magReadRaw(int16_t *x, int16_t *y, int16_t *z);
+err_t  lsm303magSetGain(lsm303MagGain_t gain);
+err_t  lsm303magGetSensorEvent(sensors_event_t *event);
+void     lsm303magGetSensor(sensor_t *sensor);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/sensors/magnetometers/magnetometers.c b/reform2-lpc-fw/src/drivers/sensors/magnetometers/magnetometers.c
new file mode 100644
index 0000000000000000000000000000000000000000..940e2e4d95a197f9e28153138d59fb1f98a59bd7
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/magnetometers/magnetometers.c
@@ -0,0 +1,217 @@
+/**************************************************************************/
+/*!
+    @file     magnetometers.c
+    @author   Nguyen Quang Huy, Nguyen Thien Tin
+    @ingroup  Sensors
+
+    @brief    Helper functions for magnetometers
+
+    @code
+
+    err_t error;
+    sensors_event_t mag_event;
+    sensors_vec_t orientation;
+
+    // Initialise the magnetometer
+    error = lsm303magInit();
+
+    while (1)
+    {
+      if (!error)
+      {
+        // Get sensor data
+        error = lsm303magGetSensorEvent(&mag_event);
+        if (!error)
+        {
+          // Calculate the heading (in degrees)
+          magGetOrientation(&mag_event, &orientation);
+
+          // Display the mag and orientation data
+          printf("Mag X: %f, Y: %f, Z: %f, Heading: %d\r\n",
+            magEvent.magnetic.x,
+            magEvent.magnetic.y,
+            magEvent.magnetic.z,
+            (int)orientation.heading);
+        }
+        // Wait a bit between sensor updates
+        delay(100);
+      }
+    }
+
+    @endcode
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+#include "magnetometers.h"
+#include "core/delay/delay.h"
+#include <math.h>
+
+/**************************************************************************/
+/*!
+    @brief  Utilize the sensor data from an accelerometer to compensate
+            the magnetic sensor measurements when the sensor is tilted
+            (the pitch and roll angles are not equal 0°)
+
+    @param  axis          The given axis (SENSOR_AXIS_X/Y/Z) that is
+                          parallel to the gravity of the Earth
+
+    @param  mag_event     The raw magnetometer data to adjust for tilt
+
+    @param  accel_event   The accelerometer event data to use to determine
+                          the tilt when compensating the mag_event values
+
+    @code
+
+    // Perform tilt compensation with matching accelerometer data
+    sensors_event_t accel_event;
+    error = lsm303accelGetSensorEvent(&accel_event);
+    if (!error)
+    {
+      magTiltCompensation(SENSOR_AXIS_Z, &mag_event, &accel_event);
+    }
+
+    @endcode
+*/
+/**************************************************************************/
+void magTiltCompensation(sensors_axis_t axis, sensors_event_t *mag_event, sensors_event_t *accel_event)
+{
+  float accel_X, accel_Y, accel_Z;
+  float *mag_X, *mag_Y, *mag_Z;
+
+  switch (axis)
+  {
+    case SENSOR_AXIS_X:
+      /* The X-axis is parallel to the gravity */
+      accel_X = accel_event->acceleration.y;
+      accel_Y = accel_event->acceleration.z;
+      accel_Z = accel_event->acceleration.x;
+      mag_X = &(mag_event->magnetic.y);
+      mag_Y = &(mag_event->magnetic.z);
+      mag_Z = &(mag_event->magnetic.x);
+      break;
+
+    case SENSOR_AXIS_Y:
+      /* The Y-axis is parallel to the gravity */
+      accel_X = accel_event->acceleration.z;
+      accel_Y = accel_event->acceleration.x;
+      accel_Z = accel_event->acceleration.y;
+      mag_X = &(mag_event->magnetic.z);
+      mag_Y = &(mag_event->magnetic.x);
+      mag_Z = &(mag_event->magnetic.y);
+      break;
+
+    case SENSOR_AXIS_Z:
+    default:
+      /* The Z-axis is parallel to the gravity */
+      accel_X = accel_event->acceleration.x;
+      accel_Y = accel_event->acceleration.y;
+      accel_Z = accel_event->acceleration.z;
+      mag_X = &(mag_event->magnetic.x);
+      mag_Y = &(mag_event->magnetic.y);
+      mag_Z = &(mag_event->magnetic.z);
+      break;
+  }
+
+  float t_roll = accel_X * accel_X + accel_Z * accel_Z;
+  float rollRadians = (float)atan2(accel_Y, sqrt(t_roll));
+
+  float t_pitch = accel_Y * accel_Y + accel_Z * accel_Z;
+  float pitchRadians = (float)atan2(accel_X, sqrt(t_pitch));
+
+  float cosRoll = (float)cos(rollRadians);
+  float sinRoll = (float)sin(rollRadians);
+  float cosPitch = (float)cos(pitchRadians);
+  float sinPitch = (float)sin(pitchRadians);
+
+  /* The tilt compensation algorithm                            */
+  /* Xh = X.cosPitch + Z.sinPitch                               */
+  /* Yh = X.sinRoll.sinPitch + Y.cosRoll - Z.sinRoll.cosPitch   */
+  *mag_X = (*mag_X) * cosPitch + (*mag_Z) * sinPitch;
+  *mag_Y = (*mag_X) * sinRoll * sinPitch + (*mag_Y) * cosRoll - (*mag_Z) * sinRoll * cosPitch;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Populates the .heading fields in the sensors_vec_t
+            struct with the right angular data (0-359°)
+
+            Heading increases when measuring clockwise
+
+    @param  axis          The given axis (SENSOR_AXIS_X/Y/Z) that is
+                          parallel to the gravity of the Earth
+
+    @param  event         The raw magnetometer sensor data to use when
+                          calculating out heading
+
+    @param  orientation   The sensors_vec_t object where we will
+                          assign an 'orientation.heading' value
+
+    @code
+
+    magGetOrientation(SENSOR_AXIS_Z, &mag_event, &orientation);
+
+    @endcode
+*/
+/**************************************************************************/
+void magGetOrientation(sensors_axis_t axis, sensors_event_t *event, sensors_vec_t *orientation)
+{
+  float const PI = 3.14159265F;
+
+  switch (axis)
+  {
+    case SENSOR_AXIS_X:
+      /* Sensor rotates around X-axis                                                                 */
+      /* "heading" is the angle between the 'Y axis' and magnetic north on the horizontal plane (Oyz) */
+      /* heading = atan(Mz / My)                                                                      */
+      orientation->heading = (float)atan2(event->magnetic.z, event->magnetic.y) * 180 / PI;
+      break;
+    case SENSOR_AXIS_Y:
+      /* Sensor rotates around Y-axis                                                                 */
+      /* "heading" is the angle between the 'Z axis' and magnetic north on the horizontal plane (Ozx) */
+      /* heading = atan(Mx / Mz)                                                                      */
+      orientation->heading = (float)atan2(event->magnetic.x, event->magnetic.z) * 180 / PI;
+      break;
+    case SENSOR_AXIS_Z:
+    default:
+      /* Sensor rotates around Z-axis                                                                 */
+      /* "heading" is the angle between the 'X axis' and magnetic north on the horizontal plane (Oxy) */
+      /* heading = atan(My / Mx)                                                                      */
+      orientation->heading = (float)atan2(event->magnetic.y, event->magnetic.x) * 180 / PI;
+      break;
+    }
+
+  /* Normalize to 0-359° */
+  if (orientation->heading < 0)
+  {
+    orientation->heading = 360 + orientation->heading;
+  }
+}
diff --git a/reform2-lpc-fw/src/drivers/sensors/magnetometers/magnetometers.h b/reform2-lpc-fw/src/drivers/sensors/magnetometers/magnetometers.h
new file mode 100644
index 0000000000000000000000000000000000000000..30432014d1cac8981062f7456f2aa4f7f2642f49
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/magnetometers/magnetometers.h
@@ -0,0 +1,55 @@
+/**************************************************************************/
+/*!
+    @file     magnetometers.h
+    @author   Nguyen Quang Huy, Nguyen Thien Tin
+    @ingroup  Sensors
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _MAGNETOMETERS_H_
+#define _MAGNETOMETERS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "drivers/sensors/sensors.h"
+
+void magTiltCompensation(sensors_axis_t axis, sensors_event_t *mag_event, sensors_event_t *accel_event);
+void magGetOrientation(sensors_axis_t axis, sensors_event_t *event, sensors_vec_t *mag_orientation);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _MAGNETOMETERS_H_
+
diff --git a/reform2-lpc-fw/src/drivers/sensors/pressure/bmp085.c b/reform2-lpc-fw/src/drivers/sensors/pressure/bmp085.c
new file mode 100644
index 0000000000000000000000000000000000000000..b1f327dc2f6cd641334d11107f8053ffbf5ef231
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/pressure/bmp085.c
@@ -0,0 +1,388 @@
+/**************************************************************************/
+/*!
+    @file     bmp085.c
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @brief    Driver for the Bosch BMP085 barometric pressure sensor
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+#include "bmp085.h"
+#include "core/delay/delay.h"
+#include <string.h>
+#include <math.h>
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+static bool               _bmp085Initialised = false;
+static int32_t            _bmp085SensorID = 0;
+static uint8_t            _bmp085Mode = BMP085_MODE_HIGHRES;
+static bmp085_calib_data  _bmp085_coeffs;
+
+#define BMP085_USE_DATASHEET_VALS (0) /* Set to 1 for sanity check */
+
+/**************************************************************************/
+/*!
+    @brief  Writes an 8 bit value over I2C
+*/
+/**************************************************************************/
+err_t bmp085WriteCommand(uint8_t reg, uint8_t value)
+{
+  I2CWriteLength = 3;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = BMP085_ADDRESS;
+  I2CMasterBuffer[1] = reg;
+  I2CMasterBuffer[2] = value;
+  ASSERT_I2C_STATUS(i2cEngine());
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads an 8 bit value over I2C
+*/
+/**************************************************************************/
+err_t bmp085Read8(uint8_t reg, uint8_t *value)
+{
+  I2CWriteLength = 2;
+  I2CReadLength = 1;
+  I2CMasterBuffer[0] = BMP085_ADDRESS;
+  I2CMasterBuffer[1] = reg;
+  I2CMasterBuffer[2] = BMP085_ADDRESS | BMP085_READBIT;
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  *value = I2CSlaveBuffer[0];
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads a 16 bit value over I2C
+*/
+/**************************************************************************/
+err_t bmp085Read16(uint8_t reg, uint16_t *value)
+{
+  I2CWriteLength = 2;
+  I2CReadLength = 2;
+  I2CMasterBuffer[0] = BMP085_ADDRESS;
+  I2CMasterBuffer[1] = reg;
+  I2CMasterBuffer[2] = BMP085_ADDRESS | BMP085_READBIT;
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  *value = I2CSlaveBuffer[0] << 8 | I2CSlaveBuffer[1];
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads a signed 16 bit value over I2C
+*/
+/**************************************************************************/
+err_t bmp085ReadS16(uint16_t reg, int16_t *value)
+{
+  uint16_t i;
+  ASSERT_STATUS(bmp085Read16(reg, &i));
+  *value = (int16_t)i;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the factory-set coefficients
+*/
+/**************************************************************************/
+err_t bmp085ReadCoefficients(void)
+{
+  #if BMP085_USE_DATASHEET_VALS
+    _bmp085_coeffs.ac1 = 408;
+    _bmp085_coeffs.ac2 = -72;
+    _bmp085_coeffs.ac3 = -14383;
+    _bmp085_coeffs.ac4 = 32741;
+    _bmp085_coeffs.ac5 = 32757;
+    _bmp085_coeffs.ac6 = 23153;
+    _bmp085_coeffs.b1  = 6190;
+    _bmp085_coeffs.b2  = 4;
+    _bmp085_coeffs.mb  = -32768;
+    _bmp085_coeffs.mc  = -8711;
+    _bmp085_coeffs.md  = 2868;
+    _bmp085Mode        = 0;
+  #else
+    ASSERT_STATUS(bmp085ReadS16(BMP085_REGISTER_CAL_AC1, &_bmp085_coeffs.ac1));
+    ASSERT_STATUS(bmp085ReadS16(BMP085_REGISTER_CAL_AC2, &_bmp085_coeffs.ac2));
+    ASSERT_STATUS(bmp085ReadS16(BMP085_REGISTER_CAL_AC3, &_bmp085_coeffs.ac3));
+    ASSERT_STATUS(bmp085Read16(BMP085_REGISTER_CAL_AC4, &_bmp085_coeffs.ac4));
+    ASSERT_STATUS(bmp085Read16(BMP085_REGISTER_CAL_AC5, &_bmp085_coeffs.ac5));
+    ASSERT_STATUS(bmp085Read16(BMP085_REGISTER_CAL_AC6, &_bmp085_coeffs.ac6));
+    ASSERT_STATUS(bmp085ReadS16(BMP085_REGISTER_CAL_B1, &_bmp085_coeffs.b1));
+    ASSERT_STATUS(bmp085ReadS16(BMP085_REGISTER_CAL_B2, &_bmp085_coeffs.b2));
+    ASSERT_STATUS(bmp085ReadS16(BMP085_REGISTER_CAL_MB, &_bmp085_coeffs.mb));
+    ASSERT_STATUS(bmp085ReadS16(BMP085_REGISTER_CAL_MC, &_bmp085_coeffs.mc));
+    ASSERT_STATUS(bmp085ReadS16(BMP085_REGISTER_CAL_MD, &_bmp085_coeffs.md));
+  #endif
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+err_t bmp085ReadRawTemperature(int32_t *temperature)
+{
+  #if BMP085_USE_DATASHEET_VALS
+    *temperature = 27898;
+  #else
+    uint16_t t;
+    ASSERT_STATUS(bmp085WriteCommand(BMP085_REGISTER_CONTROL, BMP085_REGISTER_READTEMPCMD));
+    delay(5);
+    ASSERT_STATUS(bmp085Read16(BMP085_REGISTER_TEMPDATA, &t));
+    *temperature = t;
+  #endif
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+err_t bmp085ReadRawPressure(int32_t *pressure)
+{
+  #if BMP085_USE_DATASHEET_VALS
+    *pressure = 23843;
+  #else
+    uint8_t  p8;
+    uint16_t p16;
+    int32_t  p32;
+
+    ASSERT_STATUS(bmp085WriteCommand(BMP085_REGISTER_CONTROL, BMP085_REGISTER_READPRESSURECMD + (_bmp085Mode << 6)));
+    switch(_bmp085Mode)
+    {
+      case BMP085_MODE_ULTRALOWPOWER:
+        delay(5);
+        break;
+      case BMP085_MODE_STANDARD:
+        delay(8);
+        break;
+      case BMP085_MODE_HIGHRES:
+        delay(14);
+        break;
+      case BMP085_MODE_ULTRAHIGHRES:
+      default:
+        delay(26);
+        break;
+    }
+
+    ASSERT_STATUS(bmp085Read16(BMP085_REGISTER_PRESSUREDATA, &p16));
+    p32 = (uint32_t)p16 << 8;
+    ASSERT_STATUS(bmp085Read8(BMP085_REGISTER_PRESSUREDATA+2, &p8));
+    p32 += p8;
+    p32 >>= (8 - _bmp085Mode);
+
+    *pressure = p32;
+  #endif
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Initialises the I2C block
+*/
+/**************************************************************************/
+err_t bmp085Init(bmp085_mode_t mode)
+{
+  /* Mode boundary check */
+  if ((mode > BMP085_MODE_ULTRAHIGHRES) || (mode < 0))
+  {
+    mode = BMP085_MODE_ULTRAHIGHRES;
+  }
+
+  /* Initialise I2C */
+  i2cInit(I2CMASTER);
+
+  /* Ping the I2C device first to see if it exists! */
+  ASSERT(i2cCheckAddress(BMP085_ADDRESS), ERROR_I2C_DEVICENOTFOUND);
+
+  /* Make sure we have the right device */
+  uint8_t id;
+  ASSERT_STATUS(bmp085Read8(BMP085_REGISTER_CHIPID, &id));
+  ASSERT(id == 0x55, ERROR_I2C_DEVICENOTFOUND);
+
+  /* Set the mode indicator */
+  _bmp085Mode = mode;
+
+  /* Coefficients need to be read once */
+  ASSERT_STATUS(bmp085ReadCoefficients());
+
+  _bmp085Initialised = true;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the compensated pressure level in kPa
+*/
+/**************************************************************************/
+err_t bmp085GetPressure(float *pressure)
+{
+  int32_t  ut = 0, up = 0, compp = 0;
+  int32_t  x1, x2, b5, b6, x3, b3, p;
+  uint32_t b4, b7;
+
+  /* Make sure the coefficients have been read, etc. */
+  if (!_bmp085Initialised)
+  {
+    ASSERT_STATUS(bmp085Init(BMP085_MODE_STANDARD));
+  }
+
+  /* Get the raw pressure and temperature values */
+  ASSERT_STATUS(bmp085ReadRawTemperature(&ut));
+  ASSERT_STATUS(bmp085ReadRawPressure(&up));
+
+  /* Temperature compensation */
+  x1 = (ut - _bmp085_coeffs.ac6) * _bmp085_coeffs.ac5 >> 15;
+  x2 = (_bmp085_coeffs.mc << 11) / (x1 + _bmp085_coeffs.md);
+  b5 = x1 + x2;
+
+  /* Pressure compensation */
+  b6 = b5 - 4000;
+  x1 = (_bmp085_coeffs.b2 * ((b6 * b6) >> 12)) >> 11;
+  x2 = (_bmp085_coeffs.ac2 * b6) >> 11;
+  x3 = x1 + x2;
+  b3 = (((((int32_t) _bmp085_coeffs.ac1) * 4 + x3) << _bmp085Mode) + 2) >> 2;
+  x1 = (_bmp085_coeffs.ac3 * b6) >> 13;
+  x2 = (_bmp085_coeffs.b1 * ((b6 * b6) >> 12)) >> 16;
+  x3 = ((x1 + x2) + 2) >> 2;
+  b4 = (_bmp085_coeffs.ac4 * (uint32_t) (x3 + 32768)) >> 15;
+  b7 = ((uint32_t) (up - b3) * (50000 >> _bmp085Mode));
+
+  if (b7 < 0x80000000)
+  {
+    p = (b7 << 1) / b4;
+  }
+  else
+  {
+    p = (b7 / b4) << 1;
+  }
+
+  x1 = (p >> 8) * (p >> 8);
+  x1 = (x1 * 3038) >> 16;
+  x2 = (-7357 * p) >> 16;
+  compp = p + ((x1 + x2 + 3791) >> 4);
+
+  /* Assign compensated pressure value */
+  *pressure = compp;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the temperatures in degrees Celsius
+*/
+/**************************************************************************/
+err_t bmp085GetTemperature(float *temp)
+{
+  int32_t ut, x1, x2, b5;
+  float t;
+
+  if (!_bmp085Initialised)
+  {
+    ASSERT_STATUS(bmp085Init(BMP085_MODE_STANDARD));
+  }
+
+  ASSERT_STATUS(bmp085ReadRawTemperature(&ut));
+
+  x1 = (ut - (int32_t)_bmp085_coeffs.ac6) * ((int32_t)_bmp085_coeffs.ac5) / pow(2,15);
+  x2 = ((int32_t)_bmp085_coeffs.mc * pow(2,11)) / (x1+(int32_t)_bmp085_coeffs.md);
+  b5 = x1 + x2;
+  t = (b5+8)/pow(2,4);
+  t /= 10;
+
+  *temp = t;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Provides the sensor_t data for this sensor
+*/
+/**************************************************************************/
+void bmp085GetSensor(sensor_t *sensor)
+{
+  /* Clear the sensor_t object */
+  memset(sensor, 0, sizeof(sensor_t));
+
+  /* Insert the sensor name in the fixed length char array */
+  strncpy (sensor->name, "BMP085", sizeof(sensor->name) - 1);
+  sensor->name[sizeof(sensor->name)- 1] = 0;
+  sensor->version     = 1;
+  sensor->sensor_id   = _bmp085SensorID;
+  sensor->type        = SENSOR_TYPE_PRESSURE;
+  sensor->min_delay   = 0;
+  sensor->max_value   = 300.0F;               // 300..1100 hPa
+  sensor->min_value   = 1100.0F;
+  sensor->resolution  = 0.01F;                // Datasheet states 0.01 hPa resolution
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the sensor and returns the data as a sensors_event_t
+*/
+/**************************************************************************/
+err_t bmp085GetSensorEvent(sensors_event_t *event)
+{
+  float pressure_kPa;
+
+  /* Clear the event */
+  memset(event, 0, sizeof(sensors_event_t));
+
+  event->version   = sizeof(sensors_event_t);
+  event->sensor_id = _bmp085SensorID;
+  event->type      = SENSOR_TYPE_PRESSURE;
+  event->timestamp = delayGetTicks();
+  ASSERT_STATUS(bmp085GetPressure(&pressure_kPa));
+  event->pressure = pressure_kPa / 100.0F; /* kPa to hPa */
+
+  return ERROR_NONE;
+}
diff --git a/reform2-lpc-fw/src/drivers/sensors/pressure/bmp085.h b/reform2-lpc-fw/src/drivers/sensors/pressure/bmp085.h
new file mode 100644
index 0000000000000000000000000000000000000000..4994066b2fc561c527a6e7c2c7c76c20a7d48b92
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/pressure/bmp085.h
@@ -0,0 +1,107 @@
+/**************************************************************************/
+/*!
+    @file     bmp085.h
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _BMP085_H_
+#define _BMP085_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "core/i2c/i2c.h"
+#include "drivers/sensors/sensors.h"
+
+#define BMP085_ADDRESS                (0x77 << 1)
+#define BMP085_READBIT                (0x01)
+
+typedef enum
+{
+  BMP085_MODE_ULTRALOWPOWER          = 0,
+  BMP085_MODE_STANDARD               = 1,
+  BMP085_MODE_HIGHRES                = 2,
+  BMP085_MODE_ULTRAHIGHRES           = 3
+} bmp085_mode_t;
+
+enum
+{
+  BMP085_REGISTER_CAL_AC1            = 0xAA,  // R   Calibration data (16 bits)
+  BMP085_REGISTER_CAL_AC2            = 0xAC,  // R   Calibration data (16 bits)
+  BMP085_REGISTER_CAL_AC3            = 0xAE,  // R   Calibration data (16 bits)
+  BMP085_REGISTER_CAL_AC4            = 0xB0,  // R   Calibration data (16 bits)
+  BMP085_REGISTER_CAL_AC5            = 0xB2,  // R   Calibration data (16 bits)
+  BMP085_REGISTER_CAL_AC6            = 0xB4,  // R   Calibration data (16 bits)
+  BMP085_REGISTER_CAL_B1             = 0xB6,  // R   Calibration data (16 bits)
+  BMP085_REGISTER_CAL_B2             = 0xB8,  // R   Calibration data (16 bits)
+  BMP085_REGISTER_CAL_MB             = 0xBA,  // R   Calibration data (16 bits)
+  BMP085_REGISTER_CAL_MC             = 0xBC,  // R   Calibration data (16 bits)
+  BMP085_REGISTER_CAL_MD             = 0xBE,  // R   Calibration data (16 bits)
+  BMP085_REGISTER_CHIPID             = 0xD0,
+  BMP085_REGISTER_VERSION            = 0xD1,
+  BMP085_REGISTER_SOFTRESET          = 0xE0,
+  BMP085_REGISTER_CONTROL            = 0xF4,
+  BMP085_REGISTER_TEMPDATA           = 0xF6,
+  BMP085_REGISTER_PRESSUREDATA       = 0xF6,
+  BMP085_REGISTER_READTEMPCMD        = 0x2E,
+  BMP085_REGISTER_READPRESSURECMD    = 0x34
+};
+
+typedef struct
+{
+  int16_t  ac1;
+  int16_t  ac2;
+  int16_t  ac3;
+  uint16_t ac4;
+  uint16_t ac5;
+  uint16_t ac6;
+  int16_t  b1;
+  int16_t  b2;
+  int16_t  mb;
+  int16_t  mc;
+  int16_t  md;
+} bmp085_calib_data;
+
+err_t bmp085Init(bmp085_mode_t mode);
+err_t bmp085GetTemperature(float *temp);
+err_t bmp085GetPressure(float *pressure);
+void    bmp085GetSensor(sensor_t *sensor);
+err_t bmp085GetSensorEvent(sensors_event_t *event);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/sensors/pressure/mpl115a2.c b/reform2-lpc-fw/src/drivers/sensors/pressure/mpl115a2.c
new file mode 100644
index 0000000000000000000000000000000000000000..d7d82c9e68d318294c9c11a329b46f79ece550eb
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/pressure/mpl115a2.c
@@ -0,0 +1,224 @@
+/**************************************************************************/
+/*!
+    @file     mpl115a2.c
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @brief    Driver for the Freescale MPL115A2 I2C Digital Barometer
+
+    @details
+
+    The MPL115A2 is an I2C absolute pressure sensor, employing a MEMS
+    pressure sensor with a conditioning IC to provide accurate pressure
+    measurements from 50 to 115 kPa.
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+#include "mpl115a2.h"
+#include "core/delay/delay.h"
+#include <string.h>
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+static float _mpl115a2_a0;
+static float _mpl115a2_b1;
+static float _mpl115a2_b2;
+static float _mpl115a2_c12;
+
+static bool    _mpl115a2Initialised = false;
+static int32_t _mpl115a2SensorID = 0;
+
+/**************************************************************************/
+/*!
+    @brief  Reads an 8 bit value over I2C
+*/
+/**************************************************************************/
+err_t mpl115a2ReadPressureTemp(uint16_t *pressure, uint16_t *temp)
+{
+  I2CWriteLength = 3;
+  I2CReadLength = 1;
+  I2CMasterBuffer[0] = MPL115A2_ADDRESS;
+  I2CMasterBuffer[1] = MPL115A2_REGISTER_STARTCONVERSION;
+  I2CMasterBuffer[2] = 0x00;  // Why is this necessary to get results?
+  i2cEngine();
+
+  /* Wait a bit for the conversion to complete (3ms max) */
+  delay(4);
+
+  I2CWriteLength = 2;
+  I2CReadLength = 4;
+  I2CMasterBuffer[0] = MPL115A2_ADDRESS;
+  I2CMasterBuffer[1] = MPL115A2_REGISTER_PRESSURE_MSB;
+  I2CMasterBuffer[2] = MPL115A2_ADDRESS | MPL115A2_READBIT;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  /* Shift values to create properly formed integers */
+  *pressure = ((I2CSlaveBuffer[0] << 8) | (I2CSlaveBuffer[1])) >> 6;
+  *temp = ((I2CSlaveBuffer[2] << 8) | (I2CSlaveBuffer[3])) >> 6;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the factory-set coefficients
+*/
+/**************************************************************************/
+err_t mpl115a2ReadCoefficients(void)
+{
+  int16_t a0coeff;
+  int16_t b1coeff;
+  int16_t b2coeff;
+  int16_t c12coeff;
+
+  I2CWriteLength = 2;
+  I2CReadLength = 8;
+  I2CMasterBuffer[0] = MPL115A2_ADDRESS;
+  I2CMasterBuffer[1] = MPL115A2_REGISTER_A0_COEFF_MSB;
+  I2CMasterBuffer[2] = MPL115A2_ADDRESS | MPL115A2_READBIT;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  a0coeff = (I2CSlaveBuffer[0] << 8 ) | I2CSlaveBuffer[1];
+  b1coeff = (I2CSlaveBuffer[2] << 8 ) | I2CSlaveBuffer[3];
+  b2coeff = (I2CSlaveBuffer[4] << 8 ) | I2CSlaveBuffer[5];
+  c12coeff = ((I2CSlaveBuffer[6] << 8 ) | I2CSlaveBuffer[7]) >> 2;
+
+  _mpl115a2_a0 = (float)a0coeff / 8;
+  _mpl115a2_b1 = (float)b1coeff / 8192;
+  _mpl115a2_b2 = (float)b2coeff / 16384;
+  _mpl115a2_c12 = (float)c12coeff / 4194304;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Initialises the I2C block
+*/
+/**************************************************************************/
+err_t mpl115a2Init(void)
+{
+  /* Initialise I2C */
+  i2cInit(I2CMASTER);
+
+  /* Ping the I2C device first to see if it exists! */
+  ASSERT(i2cCheckAddress(MPL115A2_ADDRESS), ERROR_I2C_DEVICENOTFOUND);
+
+  /* Coefficients need to be read once */
+  ASSERT_STATUS(mpl115a2ReadCoefficients());
+
+  _mpl115a2Initialised = true;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the compensated pressure level in kPa
+*/
+/**************************************************************************/
+err_t mpl115a2GetPressure(float *pressure)
+{
+  uint16_t  Padc, Tadc;
+  float     Pcomp;
+
+  /* Make sure the coefficients have been read, etc. */
+  if (!_mpl115a2Initialised)
+  {
+    ASSERT_STATUS(mpl115a2Init());
+  }
+
+  /* Get raw pressure and temperature settings */
+  ASSERT_STATUS(mpl115a2ReadPressureTemp(&Padc, &Tadc));
+
+  /* See datasheet p.6 for evaluation sequence */
+  Pcomp = _mpl115a2_a0 + (_mpl115a2_b1 + _mpl115a2_c12 * Tadc ) * Padc + _mpl115a2_b2 * Tadc;
+
+  /* Return pressure as floating point value */
+  *pressure = ((65.0F / 1023.0F)*(float)Pcomp) + 50;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Provides the sensor_t data for this sensor
+*/
+/**************************************************************************/
+void mpl115a2GetSensor(sensor_t *sensor)
+{
+  /* Clear the sensor_t object */
+  memset(sensor, 0, sizeof(sensor_t));
+
+  /* Insert the sensor name in the fixed length char array */
+  strncpy (sensor->name, "MLP115A2", sizeof(sensor->name) - 1);
+  sensor->name[sizeof(sensor->name)- 1] = 0;
+  sensor->version     = 1;
+  sensor->sensor_id   = _mpl115a2SensorID;
+  sensor->type        = SENSOR_TYPE_PRESSURE;
+  sensor->min_delay   = 0;
+  sensor->max_value   = 1150.0F;    //  115 kPa = 1150 hPa
+  sensor->min_value   = 500.0F;     //   50 kPa =  500 hPa
+  sensor->resolution  = 1.5F;       // 0.15 kPa
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the sensor and returns the data as a sensors_event_t
+*/
+/**************************************************************************/
+err_t mpl115a2GetSensorEvent(sensors_event_t *event)
+{
+  float pressure_kPa;
+
+  /* Clear the event */
+  memset(event, 0, sizeof(sensors_event_t));
+
+  event->version   = sizeof(sensors_event_t);
+  event->sensor_id = _mpl115a2SensorID;
+  event->type      = SENSOR_TYPE_PRESSURE;
+  event->timestamp = delayGetTicks();
+
+  /* Retrieve values from the sensor */
+  ASSERT_STATUS(mpl115a2GetPressure(&pressure_kPa));
+
+  /* The MPL115A2 returns a value from 50..115 kPa using a 10-bit range.
+   * To convert this to the hPa value sensor_event_t is expecitng simply
+   * multiply by 10. */
+  event->pressure = pressure_kPa * 10;
+
+  return ERROR_NONE;
+}
diff --git a/reform2-lpc-fw/src/drivers/sensors/pressure/mpl115a2.h b/reform2-lpc-fw/src/drivers/sensors/pressure/mpl115a2.h
new file mode 100644
index 0000000000000000000000000000000000000000..b325af7788b429bb3d6c1e4d0713dc4ee3763452
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/pressure/mpl115a2.h
@@ -0,0 +1,77 @@
+/**************************************************************************/
+/*! 
+    @file     mpl115a2.h
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _MPL115A2_H_
+#define _MPL115A2_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "core/i2c/i2c.h"
+#include "drivers/sensors/sensors.h"
+
+#define MPL115A2_ADDRESS              (0x60 << 1)    // 1100 000
+#define MPL115A2_READBIT              (0x01)
+
+enum
+{
+  MPL115A2_REGISTER_PRESSURE_MSB     = 0x00,
+  MPL115A2_REGISTER_PRESSURE_LSB     = 0x01,
+  MPL115A2_REGISTER_TEMP_MSB         = 0x02,
+  MPL115A2_REGISTER_TEMP_LSB         = 0x03,
+  MPL115A2_REGISTER_A0_COEFF_MSB     = 0x04,
+  MPL115A2_REGISTER_A0_COEFF_LSB     = 0x05,
+  MPL115A2_REGISTER_B1_COEFF_MSB     = 0x06,
+  MPL115A2_REGISTER_B1_COEFF_LSB     = 0x07,
+  MPL115A2_REGISTER_B2_COEFF_MSB     = 0x08,
+  MPL115A2_REGISTER_B2_COEFF_LSB     = 0x09,
+  MPL115A2_REGISTER_C12_COEFF_MSB    = 0x0A,
+  MPL115A2_REGISTER_C12_COEFF_LSB    = 0x0B,
+  MPL115A2_REGISTER_STARTCONVERSION  = 0x12
+};
+
+err_t mpl115a2Init(void);
+err_t mpl115a2GetPressure(float *pressure);
+void    mpl115a2GetSensor(sensor_t *sensor);
+err_t mpl115a2GetSensorEvent(sensors_event_t *event);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/sensors/pressure/pressure.c b/reform2-lpc-fw/src/drivers/sensors/pressure/pressure.c
new file mode 100644
index 0000000000000000000000000000000000000000..760f2313a3c2a946f6583ef178910ac3d1958198
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/pressure/pressure.c
@@ -0,0 +1,158 @@
+/**************************************************************************/
+/*!
+    @file     pressure.c
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @brief    Helpers functions for working with pressure sensors
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#include <math.h>
+#include "drivers/sensors/sensors.h"
+#include "pressure.h"
+
+/**************************************************************************/
+/*!
+    Calculates the altitude (in meters) from the specified atmospheric
+    pressure (in hPa), sea-level pressure (in hPa), and temperature (in °C)
+
+    @param  seaLevel      Sea-level pressure in hPa
+    @param  atmospheric   Atmospheric pressure in hPa
+    @param  temp          Temperature in degrees Celsius
+*/
+/**************************************************************************/
+float pressureToAltitude(float seaLevel, float atmospheric, float temp)
+{
+  /* Hyposometric formula:                      */
+  /*                                            */
+  /*     ((P0/P)^(1/5.257) - 1) * (T + 273.15)  */
+  /* h = -------------------------------------  */
+  /*                   0.0065                   */
+  /*                                            */
+  /* where: h   = height (in meters)            */
+  /*        P0  = sea-level pressure (in hPa)   */
+  /*        P   = atmospheric pressure (in hPa) */
+  /*        T   = temperature (in °C)           */
+
+  return (((float)pow((seaLevel/atmospheric), 0.190223F) - 1.0F)
+         * (temp + 273.15F)) / 0.0065F;
+}
+
+/**************************************************************************/
+/*!
+    Calculates the sea-level pressure (in hPa) based on the current
+    altitude (in meters), atmospheric pressure (in hPa), and temperature
+    (in °C)
+
+    @param  altitude      altitude in meters
+    @param  atmospheric   Atmospheric pressure in hPa
+    @param  temp          Temperature in degrees Celsius
+*/
+/**************************************************************************/
+float pressureSeaLevelFromAltitude(float altitude, float atmospheric, float temp)
+{
+  /* Sea-level pressure:                        */
+  /*                                            */
+  /*                   0.0065*h                 */
+  /* P0 = P * (1 - ----------------- ) ^ -5.257 */
+  /*               T+0.0065*h+273.15            */
+  /*                                            */
+  /* where: P0  = sea-level pressure (in hPa)   */
+  /*        P   = atmospheric pressure (in hPa) */
+  /*        h   = altitude (in meters)          */
+  /*        T   = Temperature (in °C)           */
+
+  return atmospheric * (float)pow((1.0F - (0.0065 * altitude) /
+          (temp + 0.0065 * altitude + 273.15F)), -5.257F);
+}
+
+/**************************************************************************/
+/*!
+    Calculates the temperature (in °C) at the destination altitude based
+    on the current seal-level pressure (in hPa), altitude
+    (in meters) and temperature (in C)
+
+    @param  currTemp        Temperature at current altitude (in °C)
+    @param  currAltitude    Current altitude (in meters)
+    @param  destAltitude    Destination altitude (in meters)
+*/
+/**************************************************************************/
+float pressureTempAtDestination(float currTemp, float currAltitude, float destAltitude)
+{
+  /* Temperature at destination:                */
+  /*                                            */
+  /* T = Ta - 0.0065(h - ha)                    */
+  /*                                            */
+  /* where: T   = Temp at destination (in °C)   */
+  /*        Ta  = Temp at current location (°C) */
+  /*        ha  = Current altitude (in meters)  */
+  /*        h   = Target altitude (in meters)   */
+
+  return currTemp - 0.0065F * (destAltitude - currAltitude);
+}
+
+/**************************************************************************/
+/*!
+    Calculates the atmospheric pressure (in hPa) at the destination
+    altitude based on the current seal-level pressure (in hPa), altitude
+    (in meters) and temperature (in C)
+
+    @param  seaLevel        Sea-level pressure (in hPa)
+    @param  destTemp        Temperature at the destination altitude (°C)
+    @param  destAltitude    Destination altitude (in meters)
+
+    @note Normally you will need to calculate the temperature at
+          destination with pressureTempAtDestination() before running
+          this function!
+*/
+/**************************************************************************/
+float pressureAtDestination(float seaLevel, float destTemp, float destAltitude)
+{
+  /* Atmospheric pressure at destination:       */
+  /*                                            */
+  /*                0.0065 * h                  */
+  /* P = P0 (1 - -----------------) ^ 5.257     */
+  /*             T+0.0065*h+273.15              */
+  /*                                            */
+  /* where: P   = Pressure at destination (hPa) */
+  /*        P0  = Sea-level pressure (hPa)      */
+  /*        h   = Destination altitude (meters) */
+  /*        T   = Destination temperature (°C)  */
+
+  return seaLevel * (float)pow(1.0F - (0.0065F * destAltitude) /
+          (destTemp + 0.0065F * destAltitude + 273.15F), 5.257F);
+}
+
+// ToDo: Calculate vertical speed over fixed delay
+// float vertical_speed = ( pressureToAltitude(sea level pressure, pressure at t0, temp) – pressureToAltitude(sea level pressure, pressure at t1, temp) / ( t1 – t0 );
\ No newline at end of file
diff --git a/reform2-lpc-fw/src/drivers/sensors/pressure/pressure.h b/reform2-lpc-fw/src/drivers/sensors/pressure/pressure.h
new file mode 100644
index 0000000000000000000000000000000000000000..bebeb4fc21e7789b8acca854cceba133ed0111ee
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/pressure/pressure.h
@@ -0,0 +1,55 @@
+/**************************************************************************/
+/*!
+    @file     pressure.h
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _PRESSURE_H_
+#define _PRESSURE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+float pressureToAltitude(float seaLevel, float atmospheric, float temp);
+float pressureSLPFromAltitude(float altitude, float atmospheric, float temp);
+float pressureTempAtDestination(float currTemp, float currAltitude, float destAltitude);
+float pressureAtDestination(float seaLevel, float destTemp, float destAltitude);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/sensors/sensorpoll.c b/reform2-lpc-fw/src/drivers/sensors/sensorpoll.c
new file mode 100644
index 0000000000000000000000000000000000000000..290db020218ccea32ed802bb593ed1c3032a4a80
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/sensorpoll.c
@@ -0,0 +1,283 @@
+/**************************************************************************/
+/*!
+    @file     sensorpoll.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "sensorpoll.h"
+
+#if defined CFG_MCU_FAMILY_LPC13UXX
+#include "core/dwt/dwt.h"
+volatile uint32_t sensorpoll_overruns = 0;
+#endif
+
+volatile uint32_t sensorpoll_counter = 0;
+
+/**************************************************************************/
+/*!
+    @brief      Weak ISR handler for timer tick event.
+
+    @note       Since this is a 'weak' function, to override it you
+                simply need to declare a new function with the same name
+                somewhere else in your code.
+
+    @code
+    #include "drivers/sensors/sensorpoll.h"
+
+    volatile uint32_t counter;
+
+    int main(void)
+    {
+      boardInit();
+      sensorpollInit();
+      sensorpollEnable();
+
+      while(1)
+      {
+        // ... do something, enter WFI mode, etc. ...
+        // With a 5ms sensorpoll delay this should increment 200 every second
+        printf("%d\r\n", counter);
+        delay(1000);
+      }
+    }
+
+    // This function will fire every 5ms via the sensorpoll timer ISR
+    void sensorpoll_tick_isr(void)
+    {
+      // Retrieve the sensor data here or do something inside the tick,
+      // but be sure that you finish the processing before the next tick,
+      // which is 5ms by default!
+
+      // For now, just increment a counter to prove the callback works
+      counter++;
+    }
+    @endcode
+*/
+/**************************************************************************/
+void sensorpoll_tick_isr(void) __attribute__((weak));
+
+/**************************************************************************/
+/*!
+    @brief Interrupt handler for 16-bit timer 1
+
+    @desc  This interrupt handler can be used to schedule sensor reads at
+           a specific interval.  By default, the timer is setup for a 5 ms
+           delay, which should give enough time to read more slow I2C
+           sensors safely, but care should always be taken when doing any
+           extended task inside an interrupt handler.
+
+           By default, this interrupt handler will be set to the lowest
+           priority to avoid any problems with other interrupt-based
+           functions like 'delay' which may be used by the sensor
+           drivers!
+
+           This code is not *safe* and shouldn't be used carelessly, but
+           when properly implemented can provide regularly scheduled
+           sensor data without the need for a complex RTOS and task
+           scheduler.
+
+    @note  Use this interupt handler with care and caution!
+*/
+/**************************************************************************/
+#if defined CFG_MCU_FAMILY_LPC11UXX
+void TIMER16_1_IRQHandler(void)
+#elif defined CFG_MCU_FAMILY_LPC13UXX
+void CT16B1_IRQHandler(void)
+#else
+  #error "sensorpoll.c: No MCU defined"
+#endif
+{
+  #if defined CFG_MCU_FAMILY_LPC13UXX
+    /* Use the DWT timer to make sure we don't exceed the 5ms delay */
+    DWT_RESET_CYCLECOUNTER;
+  #endif
+
+  /* Handle MAT0 event (MAT0 controls the tick period) */
+  if (LPC_CT16B1->IR & (0x01 << 0))
+  {
+    /* Clear the interrupt flag */
+    LPC_CT16B1->IR = 0x1 << 0;
+
+    /* Increment the sensorpoll tick counter */
+    sensorpoll_counter++;
+
+    /* Call the sensorpoll_tick_isr callback so that we can pull    *
+     * our sensor data and do something with it elsewhere rather    *
+     * than putting board or project specific code here.            */
+    sensorpoll_tick_isr();
+  }
+
+  /* ToDo: Handle capture events, which you might want to use to    *
+   * capture sensor data only when a specific CAP event/pin is      *
+   * triggered                                                      */
+
+  #if defined CFG_MCU_FAMILY_LPC13UXX
+    /* Check how many clock cycles the ISR actually took */
+    int count = DWT->CYCCNT;
+    if (count >= LPC_CT16B1->MR0 * 8)
+    {
+      /* We overran the timer delay ... increment the overrun counter! */
+      sensorpoll_overruns++;
+    }
+  #endif
+
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Initialises the timer with a default 5ms tick rate
+
+    @code
+    extern volatile uint32_t sensorpoll_counter = 0;
+
+    // Initialise the sensor poller (setup the timer, etc.)
+    sensorpollInit();
+
+    // Enable the timer (start polling for data!)
+    sensorpollEnable();
+
+    while(1)
+    {
+      // If everything is setup properly this should increment by ~200
+      // every second (sensorpoll.c has a 5 ms default tick rate)
+      printf("%d\r\n", sensorpoll_counter);
+      delay(1000);
+    }
+    @endcode
+*/
+/**************************************************************************/
+void sensorpollInit()
+{
+  /* Initialise 16-bit timer 1 */
+  LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 8);
+
+  /* Reset the counter variables */
+  sensorpoll_counter = 0;
+
+  /* Configure the timer */
+  LPC_CT16B1->TCR  = 0x02;            /* Reset the timer               */
+  LPC_CT16B1->PR   = 0x07;            /* Set prescaler to eight        */
+  LPC_CT16B1->IR   = 0xff;            /* Reset all interrrupts         */
+  LPC_CT16B1->PWMC = 0x00;            /* Disable PWM mode              */
+  LPC_CT16B1->MR0  = (SystemCoreClock / 200) >> 3; /* 5 ms w/prescalar */
+  LPC_CT16B1->MCR  = (0x3<<0);        /* Interrupt and Reset on MR0    */
+
+  /* Set this IRQ to lowest priority to avoid problems with delay.c    */
+  #if defined CFG_MCU_FAMILY_LPC11UXX
+    NVIC_SetPriority(TIMER_16_1_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
+  #elif defined CFG_MCU_FAMILY_LPC13UXX
+    NVIC_SetPriority(CT16B1_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
+  #endif
+
+  /* Enable the IRQ */
+  #if defined CFG_MCU_FAMILY_LPC11UXX
+    NVIC_EnableIRQ(TIMER_16_1_IRQn);
+  #elif defined CFG_MCU_FAMILY_LPC13UXX
+    NVIC_EnableIRQ(CT16B1_IRQn);
+  #endif
+
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Enables the timer
+*/
+/**************************************************************************/
+void sensorpollEnable(void)
+{
+  LPC_CT16B1->TCR = 1;
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Disables the timer
+*/
+/**************************************************************************/
+void sensorpollDisable(void)
+{
+  LPC_CT16B1->TCR = 0;
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Configures the match register for the timer, which will set
+           the 'delay' between each tick on the timer.
+
+    @param[in]  value
+                The value to assign to the match register
+
+    @code
+    // Set the timer to trigger every 12000 ticks, which is equal to 96000
+    // ticks of the system clock since the timer is set to run at 1/8 the
+    // speed of the system clock.
+    sensorpollSetMatch(12000);
+
+    // Alternatively, we can do the following, but you need to make sure
+    // that the final value is within a 16-bit range (0..65535)
+    // 5ms @ 48MHz = 30,000 ticks / 5ms @ 72MHz = 45,000 ticks, so this
+    // is a safe value on either the LPC11U or LPC13U at maximum speed
+    sensorpollSetMatch((SystemCoreClock / 200) >> 3);
+    @endcode
+
+    @note Note that by default the 16-bit timer is setup with a prescalar
+          value of 8, meaning that the timer clock is 1/8 the speed of the
+          system clock.  For example, a 48MHz system clock = a 6MHz
+          peripheral clock.  Each 'tick' for the match register is based
+          on this 1/8 peripheral clock, not the faster system clock.
+*/
+/**************************************************************************/
+void sensorpollSetMatch(uint16_t value)
+{
+  LPC_CT16B1->MR0 = value;
+  return;
+}
+
+/**************************************************************************/
+/*!
+    @brief Gets the match register value for the timer, which controls
+           the 'delay' between each tick on the timer.
+
+    @note Note that by default the 16-bit timer is setup with a prescalar
+          value of 8, meaning that the timer clock is 1/8 the speed of the
+          system clock.  For example, a 48MHz system clock = a 6MHz
+          peripheral clock.  Each 'tick' for the match register is based
+          on this 1/8 peripheral clock, not the faster system clock.
+*/
+/**************************************************************************/
+uint16_t sensorpollGetMatch(void)
+{
+  return LPC_CT16B1->MR0;
+}
diff --git a/reform2-lpc-fw/src/drivers/sensors/sensorpoll.h b/reform2-lpc-fw/src/drivers/sensors/sensorpoll.h
new file mode 100644
index 0000000000000000000000000000000000000000..1174ce04175ad280b7135a11bbf5721e463f55b7
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/sensorpoll.h
@@ -0,0 +1,55 @@
+/**************************************************************************/
+/*!
+    @file     sensorpoll.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _SENSORPOLL_H_
+#define _SENSORPOLL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+void     sensorpollInit     ( void );
+void     sensorpollEnable   ( void );
+void     sensorpollDisable  ( void );
+void     sensorpollSetMatch ( uint16_t value );
+uint16_t sensorpollGetMatch ( void );
+
+#ifdef __cplusplus0
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/sensors/sensors.c b/reform2-lpc-fw/src/drivers/sensors/sensors.c
new file mode 100644
index 0000000000000000000000000000000000000000..72fb8193143f52d32721b32d0c9ca4b3c6253156
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/sensors.c
@@ -0,0 +1,239 @@
+/**************************************************************************/
+/*!
+    @file     sensors.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "sensors.h"
+#include <string.h>
+#include <math.h>
+
+/**************************************************************************/
+/*!
+    @brief  Serializes a sensor_t object as a byte array
+
+    @code
+
+    sensor_t sensor;
+
+    // Get the sensor_t data
+    mpl115a2GetSensor(&sensor);
+
+    // Create a serialisation buffer
+    uint8_t buf[sizeof(event)];
+
+    // Serialize sensor data into a byte array
+    sensorsSerializeSensor(buf, &sensor);
+
+    // Broadcast the event data over the air
+    msgSend(0xFFFF, MSG_MESSAGETYPE_SENSORDETAILS, buf, sizeof(sensor));
+
+    @endcode
+*/
+/**************************************************************************/
+size_t sensorsSerializeSensor(uint8_t *buffer, const sensor_t *sensor)
+{
+   size_t i = 0;
+
+   memcpy(&buffer[i], &sensor->name, sizeof sensor->name);
+   i += sizeof sensor->name;
+   memcpy(&buffer[i], &sensor->version, sizeof sensor->version);
+   i += sizeof sensor->version;
+   memcpy(&buffer[i], &sensor->sensor_id, sizeof sensor->sensor_id);
+   i += sizeof sensor->sensor_id;
+   memcpy(&buffer[i], &sensor->type, sizeof sensor->type);
+   i += sizeof sensor->type;
+   memcpy(&buffer[i], &sensor->max_value, sizeof sensor->max_value);
+   i += sizeof sensor->max_value;
+   memcpy(&buffer[i], &sensor->min_value, sizeof sensor->min_value);
+   i += sizeof sensor->min_value;
+   memcpy(&buffer[i], &sensor->resolution, sizeof sensor->resolution);
+   i += sizeof sensor->resolution;
+   memcpy(&buffer[i], &sensor->min_delay, sizeof sensor->min_delay);
+   i += sizeof sensor->min_delay;
+
+   return i;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Serializes a sensors_event_t object as a byte array
+
+    @code
+
+    err_t error;
+    sensors_event_t event;
+
+    error = mpl115a2GetSensorEvent(&event);
+    if (!error)
+    {
+      // Serialization buffer
+      uint8_t msgbuf[sizeof(event)];
+
+      // Serialize event data into a byte array
+      sensorsSerializeSensorsEvent(msgbuf, &event);
+
+      // Broadcast the event data over the air
+      msgSend(0xFFFF, MSG_MESSAGETYPE_SENSOREVENT, msgbuf, sizeof(event));
+    }
+
+    @endcode
+*/
+/**************************************************************************/
+size_t sensorsSerializeSensorsEvent(uint8_t *buffer,
+    const sensors_event_t *event)
+{
+   size_t i = 0;
+
+   memcpy(&buffer[i], &event->version, sizeof event->version);
+   i += sizeof event->version;
+   memcpy(&buffer[i], &event->sensor_id, sizeof event->sensor_id);
+   i += sizeof event->sensor_id;
+   memcpy(&buffer[i], &event->type, sizeof event->type);
+   i += sizeof event->type;
+   memcpy(&buffer[i], &event->reserved0, sizeof event->reserved0);
+   i += sizeof event->reserved0;
+   memcpy(&buffer[i], &event->timestamp, sizeof event->timestamp);
+   i += sizeof event->timestamp;
+   memcpy(&buffer[i], &event->data, sizeof event->data);
+   i += sizeof event->data;
+
+   return i;
+}
+
+/**************************************************************************/
+/*!
+    Places the sensor details in a text buffer for data logging purposes
+*/
+/**************************************************************************/
+size_t sensorsLogSensor(char *buffer, const size_t len, const sensor_t *sensor)
+{
+  size_t written;
+
+  /* Clear the buffer */
+  memset(buffer, 0x00, len);
+
+  written = snprintf(buffer, len, "%d,%s,%d,%d,%f,%f,%f%s",
+        (int)sensor->sensor_id,
+        sensor->name,
+        (int)sensor->type,
+        (int)sensor->version,
+        sensor->max_value,
+        sensor->min_value,
+        sensor->resolution,
+        CFG_PRINTF_NEWLINE);
+
+  return written;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Places the sensor event in a text buffer for data logging
+            purposes, with the following comma-separated format:
+            SENSOR ID, SENSOR TYPE, TIMESTAMP (ms), D0, D1, D2, D3
+
+    @code
+
+    // Read 1000 samples from an accelerometer and log them to an SD card
+    // using 'drivers/storage/logger.c' (CFG_SDCARD must be enabled)
+
+    err_t error;
+    sensors_event_t event;
+    char buffer[128];
+    size_t len;
+    volatile size_t count = 0;
+
+    // Initialise the accelerometer
+    error = lsm303accelInit();
+
+    if (!error)
+    {
+      // Initialise the logger using the file 'sensors.txt'
+      error = loggerInit("sensors.txt", LOGGER_FILEACTION_ALWAYSCREATE);
+
+      if (!error)
+      {
+        // Read 1000 sensor events and log them to the SD card
+        while(count < 1000)
+        {
+          // Increment the sample counter
+          count++;
+
+          // Get fresh sensor data to log
+          error = lsm303accelGetSensorEvent(&event);
+
+          // Try to log the data to disk
+          if (!error)
+          {
+            // Fill 'buffer' with the data, returning the string length
+            len = sensorsLogSensorsEvent(buffer, 128, &event);
+
+            // Write the buffer out to the log file
+            error = loggerWrite(buffer, len);
+            if (error)
+            {
+              // Something went wrong writing to the file ...
+              // This will cause us to exit the loop, and the file
+              // will be closed further down
+              count = 1000;
+            }
+          }
+        }
+      }
+
+      // Make sure the file is closed and we unmount the drive
+      loggerClose();
+    }
+
+    @endcode
+*/
+/**************************************************************************/
+size_t sensorsLogSensorsEvent(char *buffer, const size_t len,
+    const sensors_event_t *event)
+{
+  size_t written;
+
+  /* Clear the buffer */
+  memset(buffer, 0x00, len);
+
+  written = snprintf(buffer, len, "%d,%d,%d,%f,%f,%f,%f%s",
+    (int)event->sensor_id,
+    (int)event->type,
+    (int)event->timestamp,
+    event->data[0],
+    event->data[1],
+    event->data[2],
+    event->data[3],
+    CFG_PRINTF_NEWLINE);
+
+  return written;
+}
diff --git a/reform2-lpc-fw/src/drivers/sensors/sensors.h b/reform2-lpc-fw/src/drivers/sensors/sensors.h
new file mode 100644
index 0000000000000000000000000000000000000000..a99f97aadec145bcf991f22df611be8a1f5d26f6
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/sensors.h
@@ -0,0 +1,204 @@
+/**************************************************************************/
+/*!
+    @defgroup Sensors Sensors
+
+    @brief    Sensor API to abstract basic sensor parameters and sensor
+              data (sensor 'events') into a common type using standardized
+              SI units for measurements.
+
+    @details
+
+    Basic sensor properties are defined by \ref sensor_t, and sensor
+    readings are defined as 'events' using \ref sensors_event_t.
+
+    Some common helper functions to work with sensors and sensor events
+    like serializing data are provided in sensors.c.
+*/
+/**************************************************************************/
+
+/**************************************************************************/
+/*!
+    @file     sensors.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Shared types and helper functions for working with sensors
+    @ingroup  Sensors
+
+    @details
+
+    This module is responsible for defining a common type for sensors
+    (\ref sensor_t) and sensor data (\ref sensors_event_t).
+
+    By using a common type for any sensor or sensor event that data can
+    easily be logged in a universal way, without having to understand the
+    specific properties and limitations of the sensor(s) being used.
+
+    All sensor event units are also standardized on specific SI units to
+    make comparing data across different sensor models easier.
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, Kevin Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _SENSORS_H_
+#define _SENSORS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+/* Intentionally modeled after sensors.h in the Android API:
+ * https://github.com/android/platform_hardware_libhardware/blob/master/include/hardware/sensors.h */
+
+/* Constants */
+#define SENSORS_GRAVITY_EARTH             (9.80665F)              /**< Earth's gravity in m/s^2 */
+#define SENSORS_GRAVITY_MOON              (1.6F)                  /**< The moon's gravity in m/s^2 */
+#define SENSORS_GRAVITY_SUN               (275.0F)                /**< The sun's gravity in m/s^2 */
+#define SENSORS_GRAVITY_STANDARD          (SENSORS_GRAVITY_EARTH)
+#define SENSORS_MAGFIELD_EARTH_MAX        (60.0F)                 /**< Maximum magnetic field on Earth's surface */
+#define SENSORS_MAGFIELD_EARTH_MIN        (30.0F)                 /**< Minimum magnetic field on Earth's surface */
+#define SENSORS_PRESSURE_SEALEVELHPA      (1013.25F)              /**< Average sea level pressure is 1013.25 hPa */
+#define SENSORS_DPS_TO_RADS               (0.017453293F)          /**< Degrees/s to rad/s multiplier */
+#define SENSORS_GAUSS_TO_MICROTESLA       (100)                   /**< Gauss to micro-Tesla multiplier */
+
+/** Sensor types */
+typedef enum
+{
+  SENSOR_TYPE_ACCELEROMETER         = (1),   /**< Gravity + linear acceleration */
+  SENSOR_TYPE_MAGNETIC_FIELD        = (2),
+  SENSOR_TYPE_ORIENTATION           = (3),
+  SENSOR_TYPE_GYROSCOPE             = (4),
+  SENSOR_TYPE_LIGHT                 = (5),
+  SENSOR_TYPE_PRESSURE              = (6),
+  SENSOR_TYPE_PROXIMITY             = (8),
+  SENSOR_TYPE_GRAVITY               = (9),
+  SENSOR_TYPE_LINEAR_ACCELERATION   = (10),  /**< Acceleration not including gravity */
+  SENSOR_TYPE_ROTATION_VECTOR       = (11),
+  SENSOR_TYPE_RELATIVE_HUMIDITY     = (12),
+  SENSOR_TYPE_AMBIENT_TEMPERATURE   = (13),
+  SENSOR_TYPE_VOLTAGE               = (15),
+  SENSOR_TYPE_CURRENT               = (16),
+  SENSOR_TYPE_COLOR                 = (17)
+} sensors_type_t;
+
+/** struct sensors_vec_s is used to return a vector in a common format. */
+typedef struct {
+    union {
+        float v[3];
+        struct {
+            float x;
+            float y;
+            float z;
+        };
+        /* Orientation sensors */
+        struct {
+            float roll;    /**< Rotation around the longitudinal axis (the plane body, 'X axis'). Roll is positive and increasing when moving downward. -180°<=roll<=180° */
+            float pitch;   /**< Rotation around the lateral axis (the wing span, 'Y axis'). Pitch is positive and increasing when moving upwards. -180°<=pitch<=180°) */
+            float heading; /**< Angle between the longitudinal axis (the plane body) and magnetic north, measured clockwise when viewing from the top of the device. 0-359° */
+        };
+    };
+    int8_t status;
+    uint8_t reserved[3];
+} sensors_vec_t;
+
+/** Sensor axis */
+typedef enum
+{
+  SENSOR_AXIS_X  = (1),
+  SENSOR_AXIS_Y  = (2),
+  SENSOR_AXIS_Z  = (3)
+} sensors_axis_t;
+
+/** struct sensors_color_s is used to return color data in a common format. */
+typedef struct {
+    union {
+        float c[3];
+        /* RGB color space */
+        struct {
+            float r;       /**< Red component */
+            float g;       /**< Green component */
+            float b;       /**< Blue component */
+        };
+    };
+    uint32_t rgba;         /**< 24-bit RGBA value */
+} sensors_color_t;
+
+/* Sensor event (36 bytes) */
+/** struct sensor_event_s is used to provide a single sensor event in a common format. */
+typedef struct
+{
+    int32_t version;                          /**< must be sizeof(struct sensors_event_t) */
+    int32_t sensor_id;                        /**< unique sensor identifier */
+    int32_t type;                             /**< sensor type */
+    int32_t reserved0;                        /**< reserved */
+    int32_t timestamp;                        /**< time is in milliseconds */
+    union
+    {
+        float           data[4];
+        sensors_vec_t   acceleration;         /**< acceleration values are in meter per second per second (m/s^2) */
+        sensors_vec_t   magnetic;             /**< magnetic vector values are in micro-Tesla (uT) */
+        sensors_vec_t   orientation;          /**< orientation values are in degrees */
+        sensors_vec_t   gyro;                 /**< gyroscope values are in rad/s */
+        float           temperature;          /**< temperature is in degrees centigrade (Celsius) */
+        float           distance;             /**< distance in centimeters */
+        float           light;                /**< light in SI lux units */
+        float           pressure;             /**< pressure in hectopascal (hPa) */
+        float           relative_humidity;    /**< relative humidity in percent */
+        float           current;              /**< current in milliamps (mA) */
+        float           voltage;              /**< voltage in volts (V) */
+        sensors_color_t color;                /**< color in RGB component values */
+    };
+} sensors_event_t;
+
+/* Sensor details (40 bytes) */
+/** struct sensor_s is used to describe basic information about a specific sensor. */
+typedef struct
+{
+    char     name[12];                        /**< sensor name */
+    int32_t  version;                         /**< version of the hardware + driver */
+    int32_t  sensor_id;                       /**< unique sensor identifier */
+    int32_t  type;                            /**< this sensor's type (ex. SENSOR_TYPE_LIGHT) */
+    float    max_value;                       /**< maximum value of this sensor's value in SI units */
+    float    min_value;                       /**< minimum value of this sensor's value in SI units */
+    float    resolution;                      /**< smallest difference between two values reported by this sensor */
+    int32_t  min_delay;                       /**< min delay in microseconds between events. zero = not a constant rate */
+} sensor_t;
+
+size_t sensorsSerializeSensor(uint8_t *buffer, const sensor_t *sensor);
+size_t sensorsSerializeSensorsEvent(uint8_t *buffer, const sensors_event_t *event);
+size_t sensorsLogSensor(char *buffer, const size_t len, const sensor_t *sensor);
+size_t sensorsLogSensorsEvent(char *buffer, const size_t len, const sensors_event_t *event);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/sensors/temperature/lm75b.c b/reform2-lpc-fw/src/drivers/sensors/temperature/lm75b.c
new file mode 100644
index 0000000000000000000000000000000000000000..251b2260c45dac23092df177190b560e0fc8eacf
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/temperature/lm75b.c
@@ -0,0 +1,253 @@
+/**************************************************************************/
+/*!
+    @file     lm75b.c
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @brief    Driver for NXP's LM75B temperature sensor
+
+    @details
+
+    Driver for NXP's LM75B I2C temperature sensor.  This temperature
+    sensor has an accuracy of 0.125°C, and returns a temperature value
+    in degrees celsius where each unit is equal to 0.125°C.  For example,
+    if the temperature reading is 198, it means that the temperature in
+    degree celsius is: 198 / 8 = 24.75°C.
+
+    @code
+    #include "boards/board.h"
+    #include "drivers/sensors/temperature/lm75b.h"
+
+    int main(void)
+    {
+      boardInit();
+
+      int32_t temp = 0;
+
+      // Initialise the LM75B
+      lm75bInit();
+
+      while (1)
+      {
+        // Get the current temperature (in 0.125°C units)
+        lm75bGetTemperature(&temp);
+
+        // Multiply value by 125 for fixed-point math (0.125°C per unit)
+        temp *= 125;
+
+        // Use modulus operator to display decimal value
+        printf("Current Temperature: %d.%d C\n", temp / 1000, temp % 1000);
+
+        // Alternatively, you could also use floating point math, though
+        // this will result in larger compiled code if you add in floating
+        // point support for printf, etc.
+        //
+        // float tempFloat = 0.0F;
+        // lm75bGetTemperature(&temp);
+        // tempFloat = (float)temp / 8.0F;
+      }
+    }
+    @endcode
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+#include "lm75b.h"
+#include "core/delay/delay.h"
+#include <string.h>
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+static bool    _lm75bInitialised = false;
+static int32_t _lm75bSensorID = 0;
+
+/**************************************************************************/
+/*!
+    @brief  Writes an 8 bit values over I2C
+*/
+/**************************************************************************/
+err_t lm75bWrite8 (uint8_t reg, uint32_t value)
+{
+  I2CWriteLength = 3;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = LM75B_ADDRESS;             // I2C device address
+  I2CMasterBuffer[1] = reg;                       // Command register
+  I2CMasterBuffer[2] = (value & 0xFF);            // Value to write
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads a 16 bit values over I2C
+*/
+/**************************************************************************/
+err_t lm75bRead16(uint8_t reg, int32_t *value)
+{
+  I2CWriteLength = 2;
+  I2CReadLength = 2;
+  I2CMasterBuffer[0] = LM75B_ADDRESS;
+  I2CMasterBuffer[1] = reg;
+  I2CMasterBuffer[2] = LM75B_ADDRESS | LM75B_READBIT;
+  /* Check if we got an ACK or TIMEOUT error */
+  ASSERT_I2C_STATUS(i2cEngine());
+
+  // Shift values to create properly formed integer
+  *value = ((I2CSlaveBuffer[0] << 8) | I2CSlaveBuffer[1]) >> 5;
+
+  //  Sign extend negative numbers
+  if (I2CSlaveBuffer[0] & 0x80)
+  {
+    // Negative number
+    *value |= 0xFFFFFC00;
+  }
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Writes the supplied 8-bit value to the LM75B config register
+*/
+/**************************************************************************/
+err_t lm75bConfigWrite (uint8_t configValue)
+{
+  if (!_lm75bInitialised)
+  {
+    ASSERT_STATUS(lm75bInit());
+  }
+
+  ASSERT_STATUS(lm75bWrite8(LM75B_REGISTER_CONFIGURATION, configValue));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Initialises the I2C block
+*/
+/**************************************************************************/
+err_t lm75bInit(void)
+{
+  /* Initialise I2C */
+  i2cInit(I2CMASTER);
+
+  /* Ping the I2C device first to see if it exists! */
+  ASSERT(i2cCheckAddress(LM75B_ADDRESS), ERROR_I2C_DEVICENOTFOUND);
+
+  _lm75bInitialised = true;
+
+  /* Set device to shutdown mode by default (saves power) */
+  ASSERT_STATUS(lm75bConfigWrite (LM75B_CONFIG_SHUTDOWN_SHUTDOWN));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the current temperature from the LM75B
+
+    @note   This method will assign a signed 32-bit value (int32) to 'temp',
+            where each unit represents +/- 0.125°C.  To convert the numeric
+            value to degrees celsius, you must divide the value of 'temp'
+            by 8.  This conversion is not done automatically, since you may
+            or may not want to use floating point math for the calculations.
+*/
+/**************************************************************************/
+err_t lm75bGetTemperature (int32_t *temp)
+{
+  if (!_lm75bInitialised)
+  {
+    ASSERT_STATUS(lm75bInit());
+  }
+
+  /* Turn device on */
+  ASSERT_STATUS(lm75bConfigWrite (LM75B_CONFIG_SHUTDOWN_POWERON));
+
+  /* Read temperature */
+  ASSERT_STATUS(lm75bRead16 (LM75B_REGISTER_TEMPERATURE, temp));
+
+  /* Shut device back down */
+  ASSERT_STATUS(lm75bConfigWrite (LM75B_CONFIG_SHUTDOWN_SHUTDOWN));
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Provides the sensor_t data for this sensor
+*/
+/**************************************************************************/
+void lm75bGetSensor(sensor_t *sensor)
+{
+  /* Clear the sensor_t object */
+  memset(sensor, 0, sizeof(sensor_t));
+
+  /* Insert the sensor name in the fixed length char array */
+  strncpy (sensor->name, "LM75B", sizeof(sensor->name) - 1);
+  sensor->name[sizeof(sensor->name)- 1] = 0;
+  sensor->version         = 1;
+  sensor->sensor_id       = _lm75bSensorID;
+  sensor->type            = SENSOR_TYPE_AMBIENT_TEMPERATURE;
+  sensor->min_delay       = 0;
+  sensor->max_value       = 125.0F;
+  sensor->min_value       = -55.0F;
+  sensor->resolution      = 0.125F;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Reads the sensor and returns the data as a sensors_event_t
+*/
+/**************************************************************************/
+err_t lm75bGetSensorEvent(sensors_event_t *event)
+{
+  int32_t temp;
+
+  /* Clear the event */
+  memset(event, 0, sizeof(sensors_event_t));
+
+  event->version   = sizeof(sensors_event_t);
+  event->sensor_id = _lm75bSensorID;
+  event->type      = SENSOR_TYPE_AMBIENT_TEMPERATURE;
+  event->timestamp = delayGetTicks();
+
+  /* Retrieve values from the sensor */
+  ASSERT_STATUS(lm75bGetTemperature(&temp));
+
+  event->temperature = temp * 0.125F;  /* 0.125 per lsb */
+
+  return ERROR_NONE;
+}
diff --git a/reform2-lpc-fw/src/drivers/sensors/temperature/lm75b.h b/reform2-lpc-fw/src/drivers/sensors/temperature/lm75b.h
new file mode 100644
index 0000000000000000000000000000000000000000..16c7c963ba97e1336c37592a980203d7176c1dbb
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/temperature/lm75b.h
@@ -0,0 +1,68 @@
+/**************************************************************************/
+/*! 
+    @file     lm75b.h
+    @author   K. Townsend (microBuilder.eu)
+    @ingroup  Sensors
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _LM75B_H_
+#define _LM75B_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+#include "core/i2c/i2c.h"
+#include "drivers/sensors/sensors.h"
+
+#define LM75B_ADDRESS (0x72 << 1)   // 100 1000 shifted left 1 bit = 0x90
+#define LM75B_READBIT (0x01)
+
+#define LM75B_REGISTER_TEMPERATURE      (0x00)
+#define LM75B_REGISTER_CONFIGURATION    (0x01)
+
+#define LM75B_CONFIG_SHUTDOWN_MASK      (0x01)
+#define LM75B_CONFIG_SHUTDOWN_POWERON   (0x00)
+#define LM75B_CONFIG_SHUTDOWN_SHUTDOWN  (0x01)
+
+err_t lm75bInit(void);
+err_t lm75bGetTemperature (int32_t *temp);
+err_t lm75bConfigWrite (uint8_t configValue);
+void    lm75bGetSensor(sensor_t *sensor);
+err_t lm75bGetSensorEvent(sensors_event_t *event);
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/sensors/testscripts/plot_xyz.py b/reform2-lpc-fw/src/drivers/sensors/testscripts/plot_xyz.py
new file mode 100644
index 0000000000000000000000000000000000000000..cfb3e677c1b06a742e3963d8fe709bded8e7c187
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/testscripts/plot_xyz.py
@@ -0,0 +1,54 @@
+#-------------------------------------------------------------------------------
+# Name:        plot_sensors_event.py
+# Purpose:     Plots logged sensors_event_t data from logger.c CSV files
+#
+# Author:      K. Townsend
+#
+# Created:     09/06/2013
+# Copyright:   (c) K. Townsend 2013
+# Licence:     BSD
+#-------------------------------------------------------------------------------
+
+import numpy as np
+import matplotlib.pyplot as plt
+import Tkinter, tkFileDialog
+
+# This program will plot X/Y/Z data logged via drivers/storage/logger.c, and
+# assumes we are getting vector data in CSV format generated using the
+# 'sensorsLogSensorsEvent' helper function in drivers/sensors/sensors.c
+#
+# Data should look similar to the this:
+#
+# 0,1,5714,6.001670,-6.629296,-4.785645,0.000000
+# 0,1,5729,6.001670,-6.629296,-4.785645,0.000000
+# 0,1,5734,5.883990,-6.590069,-4.746419,0.000000
+
+def main():
+    # Request the data file to process
+    root = Tkinter.Tk()
+    root.withdraw()
+    filename = tkFileDialog.askopenfilename()
+
+    # Load the CSV file in 'data'
+    data = np.genfromtxt(filename,
+        delimiter=',',
+        dtype="i32,i32,i32,f32,f32,f32,f32",
+        names=['id','type','timestamp','x','y','z','a'])
+
+    # Display the results
+    plt.title("sensors_event_t Data")
+    plt.xlabel('Timestamp (ms)')
+    plt.ylabel('Value')
+    plt.xlim(data['timestamp'].min(), data['timestamp'].max()*1.1)
+    plt.grid(True)
+    plt.plot(data['timestamp'], data['x'], color='r', alpha = 0.9, label='x')
+    plt.plot(data['timestamp'], data['y'], color='g', alpha = 0.9, label='y')
+    plt.plot(data['timestamp'], data['z'], color='b', alpha = 0.9, label='z')
+    # plt.plot(data['timestamp'], data['a'], color='y', alpha = 0.9, label='a')
+    plt.legend()
+    plt.show()
+
+    pass
+
+if __name__ == '__main__':
+    main()
diff --git a/reform2-lpc-fw/src/drivers/sensors/testscripts/plot_xyz_plus_mag.py b/reform2-lpc-fw/src/drivers/sensors/testscripts/plot_xyz_plus_mag.py
new file mode 100644
index 0000000000000000000000000000000000000000..3c8fa3cd9d6e8b1cf90c0ed860fbf01256c29ee7
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/testscripts/plot_xyz_plus_mag.py
@@ -0,0 +1,65 @@
+#-------------------------------------------------------------------------------
+# Name:        plot_sensors_event.py
+# Purpose:     Plots logged sensors_event_t data from logger.c CSV files
+#
+# Author:      K. Townsend
+#
+# Created:     09/06/2013
+# Copyright:   (c) K. Townsend 2013
+# Licence:     BSD
+#-------------------------------------------------------------------------------
+
+import math
+import numpy as np
+import matplotlib.pyplot as plt
+import Tkinter, tkFileDialog
+
+# This program will plot X/Y/Z data logged via drivers/storage/logger.c, and
+# assumes we are getting vector data in CSV format generated using the
+# 'sensorsLogSensorsEvent' helper function in drivers/sensors/sensors.c
+#
+# Data should look similar to the this:
+#
+# 0,1,5714,6.001670,-6.629296,-4.785645,0.000000
+# 0,1,5729,6.001670,-6.629296,-4.785645,0.000000
+# 0,1,5734,5.883990,-6.590069,-4.746419,0.000000
+#
+# In addition to the raw X/Y/Z data, vector magnitude is also calculated in
+# a fourth data column
+
+def main():
+    # Request the data file to process
+    root = Tkinter.Tk()
+    root.withdraw()
+    filename = tkFileDialog.askopenfilename()
+
+    # Load the CSV file in 'data'
+    data = np.genfromtxt(filename,
+        delimiter=',',
+        dtype="i32,i32,i32,f32,f32,f32,f32",
+        names=['id','type','timestamp','x','y','z','a'])
+
+    # Calculate magnitude in column a
+    for x in np.nditer(data, op_flags=['readwrite']):
+        x['a'] = math.sqrt(
+            math.pow(x['x'], 2) +
+            math.pow(x['y'], 2) +
+            math.pow(x['z'], 2))
+
+    # Display the results
+    plt.title("sensors_event_t Data")
+    plt.xlabel('Timestamp (ms)')
+    plt.ylabel('Value')
+    plt.xlim(data['timestamp'].min(), data['timestamp'].max()*1.1)
+    plt.grid(True)
+    plt.plot(data['timestamp'], data['x'], color='r', alpha = 0.25, label='x')
+    plt.plot(data['timestamp'], data['y'], color='g', alpha = 0.25, label='y')
+    plt.plot(data['timestamp'], data['z'], color='b', alpha = 0.25, label='z')
+    plt.plot(data['timestamp'], data['a'], color='m', alpha = 0.9, label='mag')
+    plt.legend()
+    plt.show()
+
+    pass
+
+if __name__ == '__main__':
+    main()
diff --git a/reform2-lpc-fw/src/drivers/sensors/testscripts/plot_xyz_plus_mag_sma.py b/reform2-lpc-fw/src/drivers/sensors/testscripts/plot_xyz_plus_mag_sma.py
new file mode 100644
index 0000000000000000000000000000000000000000..7144fdd122cafa16dfccd0e69e9f393af2a4cce2
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/testscripts/plot_xyz_plus_mag_sma.py
@@ -0,0 +1,113 @@
+#-------------------------------------------------------------------------------
+# Name:        plot_sensors_event.py
+# Purpose:     Plots logged sensors_event_t data from logger.c CSV files
+#
+# Author:      K. Townsend
+#
+# Created:     09/06/2013
+# Copyright:   (c) K. Townsend 2013
+# Licence:     BSD
+#-------------------------------------------------------------------------------
+
+import math
+import numpy as np
+import matplotlib.pyplot as plt
+import Tkinter, tkFileDialog
+from collections import deque
+
+# This program will plot X/Y/Z data logged via drivers/storage/logger.c, and
+# assumes we are getting vector data in CSV format generated using the
+# 'sensorsLogSensorsEvent' helper function in drivers/sensors/sensors.c
+#
+# Data should look similar to the this:
+#
+# 0,1,5714,6.001670,-6.629296,-4.785645,0.000000
+# 0,1,5729,6.001670,-6.629296,-4.785645,0.000000
+# 0,1,5734,5.883990,-6.590069,-4.746419,0.000000
+#
+# In addition to the raw X/Y/Z data, vector magnitude is also calculated in
+# a fourth data column
+
+class RingBuffer(deque):
+    def __init__(self, size_max):
+        deque.__init__(self)
+        self.size_max = size_max
+    def append(self, datum):
+        deque.append(self, datum)
+        if len(self) > self.size_max:
+            self.popleft( )
+    def tolist(self):
+        return list(self)
+
+def main():
+    # Variables for our moving average filter
+    current = 0
+    avg = 0
+    total = 0
+    mavals = []
+
+    # Get window size (how many 'samples' are averaged together)
+    windowsize = int(input("Windows size (0..65535): "))
+    if (windowsize > 65535):
+        print ('Setting window size to 65535')
+        windowsize = 65535
+    if (windowsize < 1):
+        print ('Setting window size to 1')
+        windowsize = 1
+
+    # Request the data file to process
+    root = Tkinter.Tk()
+    root.withdraw()
+    filename = tkFileDialog.askopenfilename()
+
+    # Load the CSV file in 'data'
+    data = np.genfromtxt(filename,
+        delimiter=',',
+        dtype="i32,i32,i32,f32,f32,f32,f32",
+        names=['id','type','timestamp','x','y','z','a'])
+
+    # Create a circular buffer for our moving average filter
+    window = RingBuffer(size_max=windowsize)
+
+    # Calculate magnitude in column a
+    for x in np.nditer(data, op_flags=['readwrite']):
+        x['a'] = math.sqrt(
+            math.pow(x['x'], 2) +
+            math.pow(x['y'], 2) +
+            math.pow(x['z'], 2))
+        # Perform the moving average filter operations
+        current+=1
+        # Add magnitude into the ringbuffer
+        window.append(x['a'])
+        # Make sure we've reached 'windowlength' samples in the buffer
+        if (current <= windowsize):
+            mavals.append(0)
+        else:
+            # Get the current average based on the window content
+            li = window.tolist()
+            total = 0
+            for i in li:
+                total += i
+            avg = (float)(total/windowsize)
+            # Append ma output for plotting below
+            mavals.append(avg);
+
+    # Display the results
+    plt.title("SMA Filtered sensors_event_t Data (X/Y/Z + Magnitude)\nSMA Window Size = %d Samples"
+        % (windowsize))
+    plt.xlabel('Timestamp (ms)')
+    plt.ylabel('Value')
+    plt.xlim(data['timestamp'].min(), data['timestamp'].max()*1.1)
+    plt.grid(True)
+    plt.plot(data['timestamp'], data['x'], color='r', alpha = 0.25, label='x')
+    plt.plot(data['timestamp'], data['y'], color='g', alpha = 0.25, label='y')
+    plt.plot(data['timestamp'], data['z'], color='b', alpha = 0.25, label='z')
+    plt.plot(data['timestamp'], data['a'], color='m', alpha = 0.25, label='mag')
+    plt.plot(data['timestamp'], mavals, color="black", label="mag filtered")
+    plt.legend()
+    plt.show()
+
+    pass
+
+if __name__ == '__main__':
+    main()
diff --git a/reform2-lpc-fw/src/drivers/sensors/testscripts/sampledata_accel.csv b/reform2-lpc-fw/src/drivers/sensors/testscripts/sampledata_accel.csv
new file mode 100644
index 0000000000000000000000000000000000000000..e376418bdc18c72d97b66a59f09656f4be4412f1
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/sensors/testscripts/sampledata_accel.csv
@@ -0,0 +1,5950 @@
+0,1,5714,6.001670,-6.629296,-4.785645,0.000000
+0,1,5729,6.001670,-6.629296,-4.785645,0.000000
+0,1,5734,5.883990,-6.590069,-4.746419,0.000000
+0,1,5739,5.883990,-6.590069,-4.746419,0.000000
+0,1,5744,5.962444,-6.590069,-4.824872,0.000000
+0,1,5749,5.962444,-6.590069,-4.824872,0.000000
+0,1,5754,6.001670,-6.707749,-4.824872,0.000000
+0,1,5759,6.001670,-6.707749,-4.824872,0.000000
+0,1,5764,5.962444,-6.629296,-4.785645,0.000000
+0,1,5769,5.962444,-6.629296,-4.785645,0.000000
+0,1,5774,6.080123,-6.629296,-4.667965,0.000000
+0,1,5779,6.080123,-6.629296,-4.667965,0.000000
+0,1,5784,5.923217,-6.668522,-4.667965,0.000000
+0,1,5789,5.923217,-6.668522,-4.667965,0.000000
+0,1,5794,6.040897,-6.668522,-4.785645,0.000000
+0,1,5799,6.040897,-6.668522,-4.785645,0.000000
+0,1,5804,6.040897,-6.550843,-4.746419,0.000000
+0,1,5809,6.040897,-6.550843,-4.746419,0.000000
+0,1,5814,5.962444,-6.668522,-4.667965,0.000000
+0,1,5819,5.962444,-6.668522,-4.667965,0.000000
+0,1,5824,6.001670,-6.629296,-4.707192,0.000000
+0,1,5829,6.001670,-6.629296,-4.707192,0.000000
+0,1,5859,5.805537,-6.668522,-4.707192,0.000000
+0,1,5864,5.727084,-6.668522,-4.746419,0.000000
+0,1,5869,5.727084,-6.668522,-4.746419,0.000000
+0,1,5874,5.805537,-6.629296,-4.746419,0.000000
+0,1,5879,5.805537,-6.629296,-4.746419,0.000000
+0,1,5884,5.844764,-6.707749,-4.824872,0.000000
+0,1,5889,5.844764,-6.707749,-4.824872,0.000000
+0,1,5894,5.883990,-6.707749,-4.785645,0.000000
+0,1,5899,5.883990,-6.707749,-4.785645,0.000000
+0,1,5904,5.923217,-6.668522,-4.746419,0.000000
+0,1,5909,5.923217,-6.668522,-4.746419,0.000000
+0,1,5914,5.766310,-6.668522,-4.785645,0.000000
+0,1,5919,5.766310,-6.668522,-4.785645,0.000000
+0,1,5924,5.844764,-6.668522,-4.746419,0.000000
+0,1,5929,5.844764,-6.668522,-4.746419,0.000000
+0,1,5934,5.805537,-6.786202,-4.746419,0.000000
+0,1,5939,5.805537,-6.786202,-4.746419,0.000000
+0,1,5944,5.805537,-6.707749,-4.707192,0.000000
+0,1,5949,5.805537,-6.707749,-4.707192,0.000000
+0,1,5954,5.805537,-6.707749,-4.824872,0.000000
+0,1,5959,5.805537,-6.707749,-4.824872,0.000000
+0,1,5964,5.883990,-6.746975,-4.746419,0.000000
+0,1,5969,5.883990,-6.746975,-4.746419,0.000000
+0,1,5974,5.766310,-6.629296,-4.785645,0.000000
+0,1,5979,5.766310,-6.629296,-4.785645,0.000000
+0,1,5984,5.727084,-6.668522,-4.785645,0.000000
+0,1,5989,5.727084,-6.668522,-4.785645,0.000000
+0,1,5994,5.844764,-6.707749,-4.707192,0.000000
+0,1,5999,5.844764,-6.707749,-4.707192,0.000000
+0,1,6004,5.844764,-6.629296,-4.746419,0.000000
+0,1,6009,5.844764,-6.629296,-4.746419,0.000000
+0,1,6014,5.844764,-6.629296,-4.746419,0.000000
+0,1,6019,5.844764,-6.629296,-4.746419,0.000000
+0,1,6024,5.844764,-6.629296,-4.864099,0.000000
+0,1,6029,5.923217,-6.707749,-4.864099,0.000000
+0,1,6034,5.923217,-6.707749,-4.864099,0.000000
+0,1,6039,5.923217,-6.825429,-4.824872,0.000000
+0,1,6044,5.923217,-6.825429,-4.824872,0.000000
+0,1,6049,5.962444,-6.707749,-4.824872,0.000000
+0,1,6054,5.962444,-6.707749,-4.824872,0.000000
+0,1,6059,6.001670,-6.707749,-4.746419,0.000000
+0,1,6064,6.001670,-6.707749,-4.746419,0.000000
+0,1,6069,5.962444,-6.746975,-4.785645,0.000000
+0,1,6074,5.962444,-6.746975,-4.785645,0.000000
+0,1,6079,6.080123,-6.668522,-4.942552,0.000000
+0,1,6084,6.080123,-6.668522,-4.942552,0.000000
+0,1,6089,6.040897,-6.590069,-4.707192,0.000000
+0,1,6094,6.040897,-6.590069,-4.707192,0.000000
+0,1,6099,6.040897,-6.590069,-4.824872,0.000000
+0,1,6104,6.040897,-6.590069,-4.824872,0.000000
+0,1,6109,6.040897,-6.629296,-4.785645,0.000000
+0,1,6114,6.040897,-6.629296,-4.785645,0.000000
+0,1,6119,6.001670,-6.629296,-4.707192,0.000000
+0,1,6124,6.001670,-6.629296,-4.707192,0.000000
+0,1,6129,6.040897,-6.629296,-4.746419,0.000000
+0,1,6134,6.040897,-6.629296,-4.746419,0.000000
+0,1,6139,5.962444,-6.668522,-4.746419,0.000000
+0,1,6144,5.962444,-6.668522,-4.746419,0.000000
+0,1,6149,6.040897,-6.707749,-4.746419,0.000000
+0,1,6154,6.040897,-6.707749,-4.746419,0.000000
+0,1,6159,6.315483,-6.825429,-4.864099,0.000000
+0,1,6164,6.315483,-6.825429,-4.864099,0.000000
+0,1,6169,6.315483,-6.629296,-4.942552,0.000000
+0,1,6174,6.315483,-6.629296,-4.942552,0.000000
+0,1,6179,6.158576,-6.825429,-4.628739,0.000000
+0,1,6184,6.158576,-6.825429,-4.628739,0.000000
+0,1,6189,6.276257,-6.393936,-4.981779,0.000000
+0,1,6194,6.276257,-6.393936,-4.981779,0.000000
+0,1,6199,6.119350,-6.746975,-4.589512,0.000000
+0,1,6204,6.119350,-6.746975,-4.589512,0.000000
+0,1,6209,6.040897,-6.472389,-4.864099,0.000000
+0,1,6214,6.040897,-6.472389,-4.864099,0.000000
+0,1,6219,5.962444,-6.393936,-4.707192,0.000000
+0,1,6224,5.962444,-6.393936,-4.707192,0.000000
+0,1,6229,5.923217,-6.472389,-4.628739,0.000000
+0,1,6234,5.923217,-6.472389,-4.628739,0.000000
+0,1,6239,5.766310,-6.354709,-4.628739,0.000000
+0,1,6244,5.766310,-6.354709,-4.628739,0.000000
+0,1,6249,5.687858,-6.511616,-4.550286,0.000000
+0,1,6254,5.687858,-6.511616,-4.550286,0.000000
+0,1,6259,5.648631,-6.472389,-4.432606,0.000000
+0,1,6264,5.648631,-6.472389,-4.432606,0.000000
+0,1,6269,5.805537,-6.472389,-4.511059,0.000000
+0,1,6274,5.805537,-6.472389,-4.511059,0.000000
+0,1,6279,5.727084,-6.629296,-4.393379,0.000000
+0,1,6284,5.727084,-6.629296,-4.393379,0.000000
+0,1,6289,5.883990,-6.511616,-4.354153,0.000000
+0,1,6294,5.883990,-6.511616,-4.354153,0.000000
+0,1,6299,5.923217,-6.550843,-4.275700,0.000000
+0,1,6304,5.923217,-6.550843,-4.275700,0.000000
+0,1,6309,6.040897,-6.511616,-4.236473,0.000000
+0,1,6314,6.040897,-6.511616,-4.236473,0.000000
+0,1,6319,6.080123,-6.511616,-4.393379,0.000000
+0,1,6324,6.080123,-6.511616,-4.393379,0.000000
+0,1,6329,6.197803,-6.590069,-4.432606,0.000000
+0,1,6334,6.197803,-6.590069,-4.432606,0.000000
+0,1,6339,6.158576,-6.433163,-4.432606,0.000000
+0,1,6344,6.158576,-6.433163,-4.432606,0.000000
+0,1,6349,6.158576,-6.550843,-4.628739,0.000000
+0,1,6354,6.158576,-6.550843,-4.628739,0.000000
+0,1,6359,6.197803,-6.393936,-4.667965,0.000000
+0,1,6364,6.197803,-6.393936,-4.667965,0.000000
+0,1,6369,6.119350,-6.433163,-4.589512,0.000000
+0,1,6374,6.119350,-6.433163,-4.589512,0.000000
+0,1,6379,6.080123,-6.315483,-4.471833,0.000000
+0,1,6384,6.080123,-6.315483,-4.471833,0.000000
+0,1,6389,6.119350,-6.393936,-4.550286,0.000000
+0,1,6394,6.119350,-6.393936,-4.550286,0.000000
+0,1,6399,6.237030,-6.433163,-4.432606,0.000000
+0,1,6404,6.237030,-6.433163,-4.432606,0.000000
+0,1,6409,6.197803,-6.511616,-4.511059,0.000000
+0,1,6414,6.197803,-6.511616,-4.511059,0.000000
+0,1,6419,6.237030,-6.393936,-4.511059,0.000000
+0,1,6424,6.237030,-6.393936,-4.511059,0.000000
+0,1,6429,6.315483,-6.315483,-4.471833,0.000000
+0,1,6434,6.315483,-6.315483,-4.471833,0.000000
+0,1,6439,6.315483,-6.354709,-4.589512,0.000000
+0,1,6444,6.315483,-6.354709,-4.589512,0.000000
+0,1,6449,6.393936,-6.433163,-4.589512,0.000000
+0,1,6454,6.393936,-6.433163,-4.589512,0.000000
+0,1,6459,6.354709,-6.315483,-4.589512,0.000000
+0,1,6464,6.354709,-6.315483,-4.589512,0.000000
+0,1,6469,6.158576,-6.354709,-4.707192,0.000000
+0,1,6474,6.158576,-6.354709,-4.707192,0.000000
+0,1,6479,6.040897,-6.393936,-4.707192,0.000000
+0,1,6484,6.040897,-6.393936,-4.707192,0.000000
+0,1,6489,6.040897,-6.393936,-4.707192,0.000000
+0,1,6494,5.883990,-6.354709,-4.667965,0.000000
+0,1,6499,5.883990,-6.354709,-4.667965,0.000000
+0,1,6504,5.766310,-6.433163,-4.667965,0.000000
+0,1,6509,5.766310,-6.433163,-4.667965,0.000000
+0,1,6514,5.727084,-6.433163,-4.746419,0.000000
+0,1,6519,5.727084,-6.433163,-4.746419,0.000000
+0,1,6524,5.727084,-6.472389,-4.707192,0.000000
+0,1,6529,5.727084,-6.472389,-4.707192,0.000000
+0,1,6534,5.727084,-6.511616,-4.785645,0.000000
+0,1,6539,5.727084,-6.511616,-4.785645,0.000000
+0,1,6544,5.766310,-6.550843,-4.981779,0.000000
+0,1,6549,5.766310,-6.550843,-4.981779,0.000000
+0,1,6554,5.805537,-6.433163,-4.981779,0.000000
+0,1,6559,5.805537,-6.433163,-4.981779,0.000000
+0,1,6564,5.883990,-6.315483,-5.099459,0.000000
+0,1,6569,5.883990,-6.315483,-5.099459,0.000000
+0,1,6574,6.080123,-6.197803,-5.099459,0.000000
+0,1,6579,6.080123,-6.197803,-5.099459,0.000000
+0,1,6584,6.080123,-6.158576,-4.942552,0.000000
+0,1,6589,6.080123,-6.158576,-4.942552,0.000000
+0,1,6594,5.962444,-6.080123,-4.707192,0.000000
+0,1,6599,5.962444,-6.080123,-4.707192,0.000000
+0,1,6604,5.844764,-5.962444,-4.589512,0.000000
+0,1,6609,5.844764,-5.962444,-4.589512,0.000000
+0,1,6614,5.805537,-6.276257,-4.628739,0.000000
+0,1,6619,5.805537,-6.276257,-4.628739,0.000000
+0,1,6624,5.687858,-6.472389,-4.628739,0.000000
+0,1,6629,5.687858,-6.472389,-4.628739,0.000000
+0,1,6634,5.805537,-6.590069,-4.785645,0.000000
+0,1,6639,5.805537,-6.590069,-4.785645,0.000000
+0,1,6644,5.805537,-6.786202,-5.021005,0.000000
+0,1,6649,5.805537,-6.786202,-5.021005,0.000000
+0,1,6654,5.883990,-6.943109,-5.138685,0.000000
+0,1,6659,5.883990,-6.943109,-5.138685,0.000000
+0,1,6664,6.001670,-6.943109,-5.413271,0.000000
+0,1,6669,6.001670,-6.943109,-5.413271,0.000000
+0,1,6674,5.766310,-6.825429,-5.452498,0.000000
+0,1,6679,5.766310,-6.825429,-5.452498,0.000000
+0,1,6684,5.648631,-6.550843,-5.452498,0.000000
+0,1,6689,5.648631,-6.550843,-5.452498,0.000000
+0,1,6694,5.452498,-6.511616,-5.491724,0.000000
+0,1,6699,5.452498,-6.511616,-5.491724,0.000000
+0,1,6704,5.452498,-6.354709,-5.570178,0.000000
+0,1,6709,5.452498,-6.354709,-5.570178,0.000000
+0,1,6714,5.256365,-6.393936,-5.334818,0.000000
+0,1,6719,5.256365,-6.393936,-5.334818,0.000000
+0,1,6724,5.177911,-6.393936,-5.334818,0.000000
+0,1,6729,5.177911,-6.393936,-5.334818,0.000000
+0,1,6734,5.217138,-6.433163,-5.060232,0.000000
+0,1,6739,5.217138,-6.433163,-5.060232,0.000000
+0,1,6744,5.295591,-6.511616,-5.177911,0.000000
+0,1,6749,5.295591,-6.511616,-5.177911,0.000000
+0,1,6754,5.491724,-6.590069,-5.217138,0.000000
+0,1,6759,5.491724,-6.590069,-5.217138,0.000000
+0,1,6764,5.648631,-6.668522,-5.334818,0.000000
+0,1,6769,5.648631,-6.668522,-5.334818,0.000000
+0,1,6774,5.766310,-6.511616,-5.452498,0.000000
+0,1,6779,5.766310,-6.511616,-5.452498,0.000000
+0,1,6784,5.687858,-6.354709,-5.530951,0.000000
+0,1,6789,5.687858,-6.354709,-5.530951,0.000000
+0,1,6794,5.648631,-6.158576,-5.570178,0.000000
+0,1,6799,5.648631,-6.158576,-5.570178,0.000000
+0,1,6804,5.374045,-6.040897,-5.452498,0.000000
+0,1,6809,5.374045,-6.040897,-5.452498,0.000000
+0,1,6814,5.295591,-6.119350,-5.570178,0.000000
+0,1,6819,5.295591,-6.119350,-5.570178,0.000000
+0,1,6824,5.099459,-6.119350,-5.256365,0.000000
+0,1,6829,5.099459,-6.119350,-5.256365,0.000000
+0,1,6834,5.021005,-6.119350,-5.295591,0.000000
+0,1,6839,5.021005,-6.119350,-5.295591,0.000000
+0,1,6844,5.021005,-6.197803,-5.177911,0.000000
+0,1,6849,5.021005,-6.197803,-5.177911,0.000000
+0,1,6854,5.060232,-6.276257,-5.177911,0.000000
+0,1,6859,5.060232,-6.276257,-5.177911,0.000000
+0,1,6864,5.060232,-6.197803,-5.177911,0.000000
+0,1,6869,5.060232,-6.197803,-5.177911,0.000000
+0,1,6874,5.099459,-6.276257,-5.217138,0.000000
+0,1,6879,5.099459,-6.276257,-5.217138,0.000000
+0,1,6884,5.452498,-6.393936,-5.217138,0.000000
+0,1,6889,5.452498,-6.393936,-5.217138,0.000000
+0,1,6894,5.727084,-6.433163,-5.491724,0.000000
+0,1,6899,5.727084,-6.433163,-5.491724,0.000000
+0,1,6904,6.158576,-6.472389,-5.687858,0.000000
+0,1,6909,6.158576,-6.472389,-5.687858,0.000000
+0,1,6914,6.237030,-6.472389,-5.609404,0.000000
+0,1,6919,6.237030,-6.472389,-5.609404,0.000000
+0,1,6924,6.315483,-6.590069,-5.491724,0.000000
+0,1,6929,6.315483,-6.590069,-5.491724,0.000000
+0,1,6934,6.276257,-6.825429,-5.452498,0.000000
+0,1,6939,6.276257,-6.825429,-5.452498,0.000000
+0,1,6944,6.276257,-6.825429,-5.491724,0.000000
+0,1,6949,6.276257,-6.786202,-5.491724,0.000000
+0,1,6954,6.276257,-6.786202,-5.491724,0.000000
+0,1,6959,6.315483,-6.825429,-5.530951,0.000000
+0,1,6964,6.315483,-6.825429,-5.530951,0.000000
+0,1,6969,6.197803,-6.786202,-5.727084,0.000000
+0,1,6974,6.197803,-6.786202,-5.727084,0.000000
+0,1,6979,6.276257,-6.707749,-5.766310,0.000000
+0,1,6984,6.276257,-6.707749,-5.766310,0.000000
+0,1,6989,6.080123,-6.668522,-5.766310,0.000000
+0,1,6994,6.080123,-6.668522,-5.766310,0.000000
+0,1,6999,5.883990,-6.629296,-5.687858,0.000000
+0,1,7004,5.883990,-6.629296,-5.687858,0.000000
+0,1,7009,5.805537,-6.668522,-5.609404,0.000000
+0,1,7014,5.805537,-6.668522,-5.609404,0.000000
+0,1,7019,5.491724,-6.590069,-5.334818,0.000000
+0,1,7024,5.491724,-6.590069,-5.334818,0.000000
+0,1,7029,5.452498,-6.550843,-5.217138,0.000000
+0,1,7034,5.452498,-6.550843,-5.217138,0.000000
+0,1,7039,5.413271,-6.668522,-5.021005,0.000000
+0,1,7044,5.413271,-6.668522,-5.021005,0.000000
+0,1,7049,5.413271,-6.707749,-4.864099,0.000000
+0,1,7054,5.413271,-6.707749,-4.864099,0.000000
+0,1,7059,5.374045,-6.786202,-4.746419,0.000000
+0,1,7064,5.374045,-6.786202,-4.746419,0.000000
+0,1,7069,5.452498,-6.786202,-4.511059,0.000000
+0,1,7074,5.452498,-6.786202,-4.511059,0.000000
+0,1,7079,5.491724,-6.786202,-4.471833,0.000000
+0,1,7084,5.491724,-6.786202,-4.471833,0.000000
+0,1,7089,5.687858,-6.943109,-4.550286,0.000000
+0,1,7094,5.687858,-6.943109,-4.550286,0.000000
+0,1,7099,5.923217,-6.943109,-4.667965,0.000000
+0,1,7104,5.923217,-6.943109,-4.667965,0.000000
+0,1,7109,6.119350,-7.021562,-4.746419,0.000000
+0,1,7114,6.119350,-7.021562,-4.746419,0.000000
+0,1,7119,6.197803,-6.864655,-4.824872,0.000000
+0,1,7124,6.197803,-6.864655,-4.824872,0.000000
+0,1,7129,6.237030,-7.021562,-4.864099,0.000000
+0,1,7134,6.237030,-7.021562,-4.864099,0.000000
+0,1,7139,6.276257,-6.943109,-4.903325,0.000000
+0,1,7144,6.276257,-6.943109,-4.903325,0.000000
+0,1,7149,6.511616,-7.060789,-5.021005,0.000000
+0,1,7154,6.511616,-7.060789,-5.021005,0.000000
+0,1,7159,6.746975,-7.374601,-5.217138,0.000000
+0,1,7164,6.746975,-7.374601,-5.217138,0.000000
+0,1,7169,7.139242,-8.159133,-5.374045,0.000000
+0,1,7174,7.139242,-8.159133,-5.374045,0.000000
+0,1,7179,7.766868,-8.943666,-5.727084,0.000000
+0,1,7184,7.766868,-8.943666,-5.727084,0.000000
+0,1,7189,8.002227,-9.492838,-6.315483,0.000000
+0,1,7194,8.002227,-9.492838,-6.315483,0.000000
+0,1,7199,8.119907,-9.492838,-6.590069,0.000000
+0,1,7204,8.119907,-9.492838,-6.590069,0.000000
+0,1,7209,7.806094,-8.904439,-6.590069,0.000000
+0,1,7214,7.806094,-8.904439,-6.590069,0.000000
+0,1,7219,7.453054,-8.825986,-6.550843,0.000000
+0,1,7224,7.453054,-8.825986,-6.550843,0.000000
+0,1,7229,7.060789,-8.512173,-6.707749,0.000000
+0,1,7234,7.060789,-8.512173,-6.707749,0.000000
+0,1,7239,6.590069,-8.276814,-6.668522,0.000000
+0,1,7244,6.590069,-8.276814,-6.668522,0.000000
+0,1,7249,6.237030,-7.806094,-6.590069,0.000000
+0,1,7254,6.237030,-7.806094,-6.590069,0.000000
+0,1,7259,5.923217,-7.453054,-6.315483,0.000000
+0,1,7264,5.923217,-7.453054,-6.315483,0.000000
+0,1,7269,5.648631,-7.256921,-5.805537,0.000000
+0,1,7274,5.648631,-7.256921,-5.805537,0.000000
+0,1,7279,5.413271,-6.943109,-5.805537,0.000000
+0,1,7284,5.413271,-6.943109,-5.805537,0.000000
+0,1,7289,5.413271,-6.903882,-5.687858,0.000000
+0,1,7294,5.413271,-6.903882,-5.687858,0.000000
+0,1,7299,5.609404,-6.590069,-5.687858,0.000000
+0,1,7304,5.609404,-6.590069,-5.687858,0.000000
+0,1,7309,5.844764,-6.080123,-5.648631,0.000000
+0,1,7314,5.844764,-6.080123,-5.648631,0.000000
+0,1,7319,6.001670,-5.727084,-5.334818,0.000000
+0,1,7324,6.001670,-5.727084,-5.334818,0.000000
+0,1,7329,6.080123,-5.295591,-5.256365,0.000000
+0,1,7334,6.080123,-5.295591,-5.256365,0.000000
+0,1,7339,6.080123,-5.021005,-5.021005,0.000000
+0,1,7344,6.080123,-5.021005,-5.021005,0.000000
+0,1,7349,6.040897,-5.021005,-4.903325,0.000000
+0,1,7354,6.040897,-5.021005,-4.903325,0.000000
+0,1,7359,5.766310,-5.256365,-4.942552,0.000000
+0,1,7364,5.766310,-5.256365,-4.942552,0.000000
+0,1,7369,5.413271,-5.570178,-4.785645,0.000000
+0,1,7374,5.413271,-5.570178,-4.785645,0.000000
+0,1,7379,5.217138,-5.844764,-4.707192,0.000000
+0,1,7384,5.217138,-5.844764,-4.707192,0.000000
+0,1,7389,5.099459,-6.119350,-4.511059,0.000000
+0,1,7394,5.099459,-6.119350,-4.511059,0.000000
+0,1,7399,5.099459,-6.119350,-4.354153,0.000000
+0,1,7404,5.060232,-6.354709,-4.393379,0.000000
+0,1,7409,5.060232,-6.354709,-4.393379,0.000000
+0,1,7414,4.942552,-6.472389,-4.158020,0.000000
+0,1,7419,4.942552,-6.472389,-4.158020,0.000000
+0,1,7424,4.864099,-6.590069,-4.079566,0.000000
+0,1,7429,4.864099,-6.590069,-4.079566,0.000000
+0,1,7434,4.981779,-6.786202,-4.040340,0.000000
+0,1,7439,4.981779,-6.786202,-4.040340,0.000000
+0,1,7444,5.099459,-6.903882,-3.961887,0.000000
+0,1,7449,5.099459,-6.903882,-3.961887,0.000000
+0,1,7454,5.217138,-6.864655,-4.040340,0.000000
+0,1,7459,5.217138,-6.864655,-4.040340,0.000000
+0,1,7464,5.256365,-6.903882,-4.001113,0.000000
+0,1,7469,5.256365,-6.903882,-4.001113,0.000000
+0,1,7474,5.452498,-7.139242,-3.844207,0.000000
+0,1,7479,5.452498,-7.139242,-3.844207,0.000000
+0,1,7484,5.452498,-7.178468,-3.883434,0.000000
+0,1,7489,5.452498,-7.178468,-3.883434,0.000000
+0,1,7494,5.491724,-7.178468,-3.648074,0.000000
+0,1,7499,5.491724,-7.178468,-3.648074,0.000000
+0,1,7504,5.530951,-6.903882,-3.569621,0.000000
+0,1,7509,5.530951,-6.903882,-3.569621,0.000000
+0,1,7514,5.452498,-6.746975,-3.451941,0.000000
+0,1,7519,5.452498,-6.746975,-3.451941,0.000000
+0,1,7524,5.334818,-6.550843,-3.295035,0.000000
+0,1,7529,5.334818,-6.550843,-3.295035,0.000000
+0,1,7534,5.374045,-6.511616,-3.059675,0.000000
+0,1,7539,5.374045,-6.511616,-3.059675,0.000000
+0,1,7544,5.295591,-6.315483,-2.902768,0.000000
+0,1,7549,5.295591,-6.315483,-2.902768,0.000000
+0,1,7554,5.413271,-6.119350,-2.863542,0.000000
+0,1,7559,5.413271,-6.119350,-2.863542,0.000000
+0,1,7564,5.452498,-6.001670,-2.667409,0.000000
+0,1,7569,5.452498,-6.001670,-2.667409,0.000000
+0,1,7574,5.491724,-5.883990,-2.549729,0.000000
+0,1,7579,5.491724,-5.883990,-2.549729,0.000000
+0,1,7584,5.452498,-5.923217,-2.432049,0.000000
+0,1,7589,5.452498,-5.923217,-2.432049,0.000000
+0,1,7594,5.334818,-5.883990,-2.353596,0.000000
+0,1,7599,5.334818,-5.883990,-2.353596,0.000000
+0,1,7604,5.217138,-5.766310,-2.235916,0.000000
+0,1,7609,5.217138,-5.766310,-2.235916,0.000000
+0,1,7614,5.099459,-5.923217,-2.196690,0.000000
+0,1,7619,5.099459,-5.923217,-2.196690,0.000000
+0,1,7624,4.981779,-5.962444,-2.353596,0.000000
+0,1,7629,4.981779,-5.962444,-2.353596,0.000000
+0,1,7634,5.021005,-6.158576,-2.588956,0.000000
+0,1,7639,5.021005,-6.158576,-2.588956,0.000000
+0,1,7644,5.021005,-6.158576,-2.745862,0.000000
+0,1,7649,5.021005,-6.158576,-2.745862,0.000000
+0,1,7654,5.099459,-6.237030,-2.863542,0.000000
+0,1,7659,5.099459,-6.237030,-2.863542,0.000000
+0,1,7664,5.138685,-6.237030,-3.098902,0.000000
+0,1,7669,5.138685,-6.237030,-3.098902,0.000000
+0,1,7674,5.452498,-6.237030,-3.255808,0.000000
+0,1,7679,5.452498,-6.237030,-3.255808,0.000000
+0,1,7684,5.766310,-6.276257,-3.491168,0.000000
+0,1,7689,5.766310,-6.276257,-3.491168,0.000000
+0,1,7694,5.844764,-6.197803,-3.412714,0.000000
+0,1,7699,5.844764,-6.197803,-3.412714,0.000000
+0,1,7704,6.237030,-6.080123,-3.648074,0.000000
+0,1,7709,6.237030,-6.080123,-3.648074,0.000000
+0,1,7714,6.472389,-5.844764,-3.844207,0.000000
+0,1,7719,6.472389,-5.844764,-3.844207,0.000000
+0,1,7724,6.668522,-5.805537,-3.883434,0.000000
+0,1,7729,6.668522,-5.805537,-3.883434,0.000000
+0,1,7734,6.668522,-5.923217,-4.236473,0.000000
+0,1,7739,6.668522,-5.923217,-4.236473,0.000000
+0,1,7744,6.668522,-5.727084,-4.001113,0.000000
+0,1,7749,6.668522,-5.727084,-4.001113,0.000000
+0,1,7754,6.746975,-5.687858,-4.158020,0.000000
+0,1,7759,6.746975,-5.687858,-4.158020,0.000000
+0,1,7764,6.903882,-5.766310,-4.275700,0.000000
+0,1,7769,6.903882,-5.766310,-4.275700,0.000000
+0,1,7774,6.943109,-5.883990,-4.354153,0.000000
+0,1,7779,6.943109,-5.883990,-4.354153,0.000000
+0,1,7784,6.903882,-5.766310,-4.511059,0.000000
+0,1,7789,6.903882,-5.766310,-4.511059,0.000000
+0,1,7794,7.021562,-5.805537,-4.589512,0.000000
+0,1,7799,7.021562,-5.805537,-4.589512,0.000000
+0,1,7804,7.021562,-6.080123,-4.864099,0.000000
+0,1,7809,7.021562,-6.080123,-4.864099,0.000000
+0,1,7814,7.021562,-6.040897,-4.942552,0.000000
+0,1,7819,7.021562,-6.040897,-4.942552,0.000000
+0,1,7824,6.982335,-6.119350,-5.099459,0.000000
+0,1,7829,6.982335,-6.119350,-5.099459,0.000000
+0,1,7834,7.021562,-6.315483,-5.099459,0.000000
+0,1,7839,7.021562,-6.315483,-5.099459,0.000000
+0,1,7844,6.825429,-6.315483,-5.413271,0.000000
+0,1,7849,6.825429,-6.315483,-5.413271,0.000000
+0,1,7854,6.825429,-6.315483,-5.413271,0.000000
+0,1,7859,7.060789,-6.511616,-5.413271,0.000000
+0,1,7864,7.060789,-6.511616,-5.413271,0.000000
+0,1,7869,7.100015,-6.629296,-5.452498,0.000000
+0,1,7874,7.100015,-6.629296,-5.452498,0.000000
+0,1,7879,7.256921,-6.629296,-5.570178,0.000000
+0,1,7884,7.256921,-6.629296,-5.570178,0.000000
+0,1,7889,7.296148,-6.550843,-5.648631,0.000000
+0,1,7894,7.296148,-6.550843,-5.648631,0.000000
+0,1,7899,7.296148,-6.550843,-5.727084,0.000000
+0,1,7904,7.296148,-6.550843,-5.727084,0.000000
+0,1,7909,7.217695,-6.276257,-5.962444,0.000000
+0,1,7914,7.217695,-6.276257,-5.962444,0.000000
+0,1,7919,7.139242,-6.197803,-5.923217,0.000000
+0,1,7924,7.139242,-6.197803,-5.923217,0.000000
+0,1,7929,7.139242,-5.923217,-5.923217,0.000000
+0,1,7934,7.139242,-5.923217,-5.923217,0.000000
+0,1,7939,6.943109,-5.766310,-5.805537,0.000000
+0,1,7944,6.943109,-5.766310,-5.805537,0.000000
+0,1,7949,6.786202,-5.609404,-5.805537,0.000000
+0,1,7954,6.786202,-5.609404,-5.805537,0.000000
+0,1,7959,6.864655,-6.354709,-5.766310,0.000000
+0,1,7964,6.864655,-6.354709,-5.766310,0.000000
+0,1,7969,7.296148,-7.413828,-5.766310,0.000000
+0,1,7974,7.296148,-7.413828,-5.766310,0.000000
+0,1,7979,7.453054,-8.237586,-5.844764,0.000000
+0,1,7984,7.453054,-8.237586,-5.844764,0.000000
+0,1,7989,7.727641,-8.433720,-5.962444,0.000000
+0,1,7994,7.727641,-8.433720,-5.962444,0.000000
+0,1,7999,7.806094,-8.198359,-6.472389,0.000000
+0,1,8004,7.806094,-8.198359,-6.472389,0.000000
+0,1,8009,8.080680,-8.119907,-6.433163,0.000000
+0,1,8014,8.080680,-8.119907,-6.433163,0.000000
+0,1,8019,8.080680,-7.413828,-6.511616,0.000000
+0,1,8024,8.080680,-7.413828,-6.511616,0.000000
+0,1,8029,7.963000,-6.472389,-6.668522,0.000000
+0,1,8034,7.963000,-6.472389,-6.668522,0.000000
+0,1,8039,7.766868,-6.080123,-6.825429,0.000000
+0,1,8044,7.766868,-6.080123,-6.825429,0.000000
+0,1,8049,7.570734,-6.080123,-6.903882,0.000000
+0,1,8054,7.570734,-6.080123,-6.903882,0.000000
+0,1,8059,7.217695,-6.040897,-6.237030,0.000000
+0,1,8064,7.217695,-6.040897,-6.237030,0.000000
+0,1,8069,6.746975,-6.158576,-6.158576,0.000000
+0,1,8074,6.746975,-6.158576,-6.158576,0.000000
+0,1,8079,6.197803,-6.629296,-5.374045,0.000000
+0,1,8084,6.197803,-6.629296,-5.374045,0.000000
+0,1,8089,5.609404,-7.100015,-5.491724,0.000000
+0,1,8094,5.609404,-7.100015,-5.491724,0.000000
+0,1,8099,5.452498,-7.649188,-4.981779,0.000000
+0,1,8104,5.452498,-7.649188,-4.981779,0.000000
+0,1,8109,5.256365,-7.335374,-4.746419,0.000000
+0,1,8114,5.256365,-7.335374,-4.746419,0.000000
+0,1,8119,5.138685,-7.335374,-4.667965,0.000000
+0,1,8124,5.138685,-7.335374,-4.667965,0.000000
+0,1,8129,5.177911,-7.492281,-4.707192,0.000000
+0,1,8134,5.177911,-7.492281,-4.707192,0.000000
+0,1,8139,5.177911,-7.453054,-4.785645,0.000000
+0,1,8144,5.177911,-7.453054,-4.785645,0.000000
+0,1,8149,5.021005,-7.374601,-4.824872,0.000000
+0,1,8154,5.021005,-7.374601,-4.824872,0.000000
+0,1,8159,5.021005,-7.413828,-4.903325,0.000000
+0,1,8164,5.021005,-7.413828,-4.903325,0.000000
+0,1,8169,4.903325,-7.649188,-4.981779,0.000000
+0,1,8174,4.903325,-7.649188,-4.981779,0.000000
+0,1,8179,4.785645,-7.727641,-5.138685,0.000000
+0,1,8184,4.785645,-7.727641,-5.138685,0.000000
+0,1,8189,4.589512,-7.766868,-5.217138,0.000000
+0,1,8194,4.589512,-7.766868,-5.217138,0.000000
+0,1,8199,4.393379,-7.688414,-5.177911,0.000000
+0,1,8204,4.393379,-7.688414,-5.177911,0.000000
+0,1,8209,4.314926,-7.727641,-5.021005,0.000000
+0,1,8214,4.314926,-7.727641,-5.021005,0.000000
+0,1,8219,4.314926,-7.609961,-5.099459,0.000000
+0,1,8224,4.314926,-7.609961,-5.099459,0.000000
+0,1,8229,4.393379,-7.296148,-4.903325,0.000000
+0,1,8234,4.393379,-7.296148,-4.903325,0.000000
+0,1,8239,4.432606,-7.256921,-4.785645,0.000000
+0,1,8244,4.432606,-7.256921,-4.785645,0.000000
+0,1,8249,4.511059,-7.060789,-4.785645,0.000000
+0,1,8254,4.511059,-7.060789,-4.785645,0.000000
+0,1,8259,4.667965,-6.943109,-4.667965,0.000000
+0,1,8264,4.667965,-6.943109,-4.667965,0.000000
+0,1,8269,4.785645,-6.825429,-4.471833,0.000000
+0,1,8274,4.785645,-6.825429,-4.471833,0.000000
+0,1,8279,4.942552,-6.707749,-4.432606,0.000000
+0,1,8284,4.942552,-6.707749,-4.432606,0.000000
+0,1,8289,4.942552,-6.668522,-4.197247,0.000000
+0,1,8294,4.942552,-6.668522,-4.197247,0.000000
+0,1,8299,4.981779,-6.472389,-4.197247,0.000000
+0,1,8304,4.981779,-6.472389,-4.197247,0.000000
+0,1,8309,5.138685,-6.393936,-4.079566,0.000000
+0,1,8314,5.021005,-6.393936,-4.079566,0.000000
+0,1,8319,5.021005,-6.393936,-4.079566,0.000000
+0,1,8324,4.981779,-6.433163,-4.001113,0.000000
+0,1,8329,4.981779,-6.433163,-4.001113,0.000000
+0,1,8334,4.981779,-6.472389,-3.765754,0.000000
+0,1,8339,4.981779,-6.472389,-3.765754,0.000000
+0,1,8344,4.903325,-6.433163,-3.687301,0.000000
+0,1,8349,4.903325,-6.433163,-3.687301,0.000000
+0,1,8354,4.746419,-6.393936,-3.648074,0.000000
+0,1,8359,4.746419,-6.393936,-3.648074,0.000000
+0,1,8364,4.707192,-6.511616,-3.569621,0.000000
+0,1,8369,4.707192,-6.511616,-3.569621,0.000000
+0,1,8374,4.667965,-6.550843,-3.373488,0.000000
+0,1,8379,4.667965,-6.550843,-3.373488,0.000000
+0,1,8384,4.471833,-6.550843,-3.451941,0.000000
+0,1,8389,4.471833,-6.550843,-3.451941,0.000000
+0,1,8394,4.511059,-6.590069,-3.412714,0.000000
+0,1,8399,4.511059,-6.590069,-3.412714,0.000000
+0,1,8404,4.628739,-6.472389,-3.491168,0.000000
+0,1,8409,4.628739,-6.472389,-3.491168,0.000000
+0,1,8414,4.667965,-6.393936,-3.530394,0.000000
+0,1,8419,4.667965,-6.393936,-3.530394,0.000000
+0,1,8424,4.746419,-6.433163,-3.491168,0.000000
+0,1,8429,4.746419,-6.433163,-3.491168,0.000000
+0,1,8434,4.864099,-6.393936,-3.451941,0.000000
+0,1,8439,4.864099,-6.393936,-3.451941,0.000000
+0,1,8444,4.707192,-6.668522,-3.255808,0.000000
+0,1,8449,4.707192,-6.668522,-3.255808,0.000000
+0,1,8454,4.981779,-6.472389,-3.451941,0.000000
+0,1,8459,4.981779,-6.472389,-3.451941,0.000000
+0,1,8464,4.981779,-6.746975,-3.530394,0.000000
+0,1,8469,4.981779,-6.746975,-3.530394,0.000000
+0,1,8474,5.099459,-6.982335,-3.726527,0.000000
+0,1,8479,5.099459,-6.982335,-3.726527,0.000000
+0,1,8484,5.491724,-7.217695,-3.530394,0.000000
+0,1,8489,5.491724,-7.217695,-3.530394,0.000000
+0,1,8494,5.687858,-7.139242,-3.844207,0.000000
+0,1,8499,5.687858,-7.139242,-3.844207,0.000000
+0,1,8504,5.923217,-7.178468,-3.883434,0.000000
+0,1,8509,5.923217,-7.178468,-3.883434,0.000000
+0,1,8514,6.197803,-7.296148,-3.961887,0.000000
+0,1,8519,6.197803,-7.296148,-3.961887,0.000000
+0,1,8524,6.550843,-7.453054,-4.118793,0.000000
+0,1,8529,6.550843,-7.453054,-4.118793,0.000000
+0,1,8534,6.786202,-7.453054,-4.236473,0.000000
+0,1,8539,6.786202,-7.453054,-4.236473,0.000000
+0,1,8544,6.903882,-7.531507,-4.354153,0.000000
+0,1,8549,6.903882,-7.531507,-4.354153,0.000000
+0,1,8554,6.864655,-7.570734,-4.550286,0.000000
+0,1,8559,6.864655,-7.570734,-4.550286,0.000000
+0,1,8564,6.825429,-7.649188,-4.667965,0.000000
+0,1,8569,6.825429,-7.649188,-4.667965,0.000000
+0,1,8574,6.707749,-7.531507,-4.785645,0.000000
+0,1,8579,6.707749,-7.531507,-4.785645,0.000000
+0,1,8584,6.629296,-7.139242,-4.981779,0.000000
+0,1,8589,6.629296,-7.139242,-4.981779,0.000000
+0,1,8594,6.276257,-7.021562,-5.021005,0.000000
+0,1,8599,6.276257,-7.021562,-5.021005,0.000000
+0,1,8604,6.119350,-7.021562,-5.099459,0.000000
+0,1,8609,6.119350,-7.021562,-5.099459,0.000000
+0,1,8614,5.923217,-7.296148,-5.021005,0.000000
+0,1,8619,5.923217,-7.296148,-5.021005,0.000000
+0,1,8624,6.119350,-8.041453,-5.021005,0.000000
+0,1,8629,6.119350,-8.041453,-5.021005,0.000000
+0,1,8634,6.315483,-9.022119,-4.942552,0.000000
+0,1,8639,6.315483,-9.022119,-4.942552,0.000000
+0,1,8644,6.590069,-9.100572,-5.334818,0.000000
+0,1,8649,6.590069,-9.100572,-5.334818,0.000000
+0,1,8654,6.982335,-9.649744,-5.609404,0.000000
+0,1,8659,6.982335,-9.649744,-5.609404,0.000000
+0,1,8664,6.943109,-9.610518,-5.766310,0.000000
+0,1,8669,6.943109,-9.610518,-5.766310,0.000000
+0,1,8674,6.629296,-9.414385,-5.805537,0.000000
+0,1,8679,6.629296,-9.414385,-5.805537,0.000000
+0,1,8684,6.472389,-8.982892,-5.844764,0.000000
+0,1,8689,6.472389,-8.982892,-5.844764,0.000000
+0,1,8694,6.511616,-8.747532,-6.197803,0.000000
+0,1,8699,6.511616,-8.747532,-6.197803,0.000000
+0,1,8704,6.825429,-8.590626,-6.511616,0.000000
+0,1,8709,6.825429,-8.590626,-6.511616,0.000000
+0,1,8714,6.943109,-8.080680,-6.746975,0.000000
+0,1,8719,6.943109,-8.080680,-6.746975,0.000000
+0,1,8724,6.864655,-7.256921,-6.825429,0.000000
+0,1,8729,6.864655,-7.256921,-6.825429,0.000000
+0,1,8734,6.629296,-6.668522,-6.746975,0.000000
+0,1,8739,6.629296,-6.668522,-6.746975,0.000000
+0,1,8744,6.237030,-6.276257,-6.472389,0.000000
+0,1,8749,6.237030,-6.276257,-6.472389,0.000000
+0,1,8754,5.923217,-6.393936,-5.962444,0.000000
+0,1,8759,5.923217,-6.393936,-5.962444,0.000000
+0,1,8764,5.766310,-6.746975,-5.687858,0.000000
+0,1,8769,5.766310,-6.746975,-5.687858,0.000000
+0,1,8774,5.766310,-6.746975,-5.687858,0.000000
+0,1,8779,5.805537,-7.021562,-5.217138,0.000000
+0,1,8784,5.805537,-7.021562,-5.217138,0.000000
+0,1,8789,6.001670,-6.903882,-4.942552,0.000000
+0,1,8794,6.001670,-6.903882,-4.942552,0.000000
+0,1,8799,6.158576,-6.668522,-4.511059,0.000000
+0,1,8804,6.158576,-6.668522,-4.511059,0.000000
+0,1,8809,6.197803,-6.511616,-4.118793,0.000000
+0,1,8814,6.197803,-6.511616,-4.118793,0.000000
+0,1,8819,6.276257,-6.472389,-4.001113,0.000000
+0,1,8824,6.276257,-6.472389,-4.001113,0.000000
+0,1,8829,6.237030,-6.393936,-3.804980,0.000000
+0,1,8834,6.237030,-6.393936,-3.804980,0.000000
+0,1,8839,6.354709,-6.276257,-3.648074,0.000000
+0,1,8844,6.354709,-6.276257,-3.648074,0.000000
+0,1,8849,6.472389,-5.962444,-3.804980,0.000000
+0,1,8854,6.472389,-5.962444,-3.804980,0.000000
+0,1,8859,6.393936,-6.119350,-3.295035,0.000000
+0,1,8864,6.393936,-6.119350,-3.295035,0.000000
+0,1,8869,6.315483,-5.923217,-3.412714,0.000000
+0,1,8874,6.315483,-5.923217,-3.412714,0.000000
+0,1,8879,5.923217,-5.805537,-2.902768,0.000000
+0,1,8884,5.923217,-5.805537,-2.902768,0.000000
+0,1,8889,5.687858,-5.687858,-2.824315,0.000000
+0,1,8894,5.687858,-5.687858,-2.824315,0.000000
+0,1,8899,5.334818,-5.648631,-2.824315,0.000000
+0,1,8904,5.334818,-5.648631,-2.824315,0.000000
+0,1,8909,4.942552,-5.413271,-2.785089,0.000000
+0,1,8914,4.942552,-5.413271,-2.785089,0.000000
+0,1,8919,4.785645,-5.256365,-2.471276,0.000000
+0,1,8924,4.785645,-5.256365,-2.471276,0.000000
+0,1,8929,4.667965,-5.099459,-2.588956,0.000000
+0,1,8934,4.667965,-5.099459,-2.588956,0.000000
+0,1,8939,4.628739,-5.138685,-2.628182,0.000000
+0,1,8944,4.628739,-5.138685,-2.628182,0.000000
+0,1,8949,4.471833,-5.177911,-2.392823,0.000000
+0,1,8954,4.471833,-5.177911,-2.392823,0.000000
+0,1,8959,4.589512,-5.138685,-2.432049,0.000000
+0,1,8964,4.589512,-5.138685,-2.432049,0.000000
+0,1,8969,4.432606,-5.060232,-2.235916,0.000000
+0,1,8974,4.432606,-5.060232,-2.235916,0.000000
+0,1,8979,4.707192,-5.177911,-2.432049,0.000000
+0,1,8984,4.707192,-5.177911,-2.432049,0.000000
+0,1,8989,4.824872,-5.177911,-2.706636,0.000000
+0,1,8994,4.824872,-5.177911,-2.706636,0.000000
+0,1,8999,5.021005,-5.374045,-2.941995,0.000000
+0,1,9004,5.021005,-5.374045,-2.941995,0.000000
+0,1,9009,5.060232,-5.452498,-2.902768,0.000000
+0,1,9014,5.060232,-5.452498,-2.902768,0.000000
+0,1,9019,5.021005,-5.609404,-3.059675,0.000000
+0,1,9024,5.021005,-5.609404,-3.059675,0.000000
+0,1,9029,5.138685,-5.570178,-3.059675,0.000000
+0,1,9034,5.138685,-5.570178,-3.059675,0.000000
+0,1,9039,5.099459,-5.883990,-3.412714,0.000000
+0,1,9044,5.099459,-5.883990,-3.412714,0.000000
+0,1,9049,5.374045,-6.080123,-3.765754,0.000000
+0,1,9054,5.374045,-6.080123,-3.765754,0.000000
+0,1,9059,5.374045,-6.158576,-4.001113,0.000000
+0,1,9064,5.374045,-6.158576,-4.001113,0.000000
+0,1,9069,5.491724,-6.080123,-4.236473,0.000000
+0,1,9074,5.491724,-6.080123,-4.236473,0.000000
+0,1,9079,5.609404,-6.080123,-4.393379,0.000000
+0,1,9084,5.609404,-6.080123,-4.393379,0.000000
+0,1,9089,5.766310,-6.080123,-4.511059,0.000000
+0,1,9094,5.766310,-6.080123,-4.511059,0.000000
+0,1,9099,5.805537,-6.197803,-4.707192,0.000000
+0,1,9104,5.805537,-6.197803,-4.707192,0.000000
+0,1,9109,5.883990,-6.197803,-5.021005,0.000000
+0,1,9114,5.883990,-6.197803,-5.021005,0.000000
+0,1,9119,6.119350,-6.550843,-4.981779,0.000000
+0,1,9124,6.119350,-6.550843,-4.981779,0.000000
+0,1,9129,6.119350,-6.668522,-5.099459,0.000000
+0,1,9133,6.119350,-6.668522,-5.099459,0.000000
+0,1,9138,6.315483,-6.825429,-5.295591,0.000000
+0,1,9143,6.315483,-6.825429,-5.295591,0.000000
+0,1,9148,6.315483,-7.256921,-5.413271,0.000000
+0,1,9153,6.315483,-7.256921,-5.413271,0.000000
+0,1,9158,6.707749,-7.453054,-5.491724,0.000000
+0,1,9163,6.707749,-7.453054,-5.491724,0.000000
+0,1,9168,7.100015,-7.766868,-5.374045,0.000000
+0,1,9173,7.100015,-7.766868,-5.374045,0.000000
+0,1,9178,7.531507,-7.845320,-5.844764,0.000000
+0,1,9183,7.531507,-7.845320,-5.844764,0.000000
+0,1,9188,7.727641,-7.806094,-6.080123,0.000000
+0,1,9193,7.727641,-7.806094,-6.080123,0.000000
+0,1,9198,8.433720,-7.766868,-6.315483,0.000000
+0,1,9203,8.433720,-7.766868,-6.315483,0.000000
+0,1,9208,8.394493,-7.570734,-6.550843,0.000000
+0,1,9213,8.394493,-7.570734,-6.550843,0.000000
+0,1,9218,8.355267,-7.217695,-6.629296,0.000000
+0,1,9223,8.355267,-7.217695,-6.629296,0.000000
+0,1,9228,8.355267,-7.217695,-6.629296,0.000000
+0,1,9233,8.433720,-6.864655,-6.746975,0.000000
+0,1,9243,8.198359,-6.590069,-6.825429,0.000000
+0,1,9248,8.198359,-6.590069,-6.825429,0.000000
+0,1,9253,7.806094,-6.511616,-6.668522,0.000000
+0,1,9258,7.806094,-6.511616,-6.668522,0.000000
+0,1,9263,7.531507,-6.550843,-6.472389,0.000000
+0,1,9268,7.531507,-6.550843,-6.472389,0.000000
+0,1,9273,7.609961,-7.256921,-6.197803,0.000000
+0,1,9278,7.609961,-7.256921,-6.197803,0.000000
+0,1,9283,7.727641,-8.002227,-5.883990,0.000000
+0,1,9288,7.727641,-8.002227,-5.883990,0.000000
+0,1,9293,7.963000,-8.865212,-5.609404,0.000000
+0,1,9298,7.963000,-8.865212,-5.609404,0.000000
+0,1,9303,8.316040,-8.747532,-5.962444,0.000000
+0,1,9308,8.316040,-8.747532,-5.962444,0.000000
+0,1,9313,8.629852,-8.551399,-6.237030,0.000000
+0,1,9318,8.629852,-8.551399,-6.237030,0.000000
+0,1,9323,8.825986,-8.198359,-6.040897,0.000000
+0,1,9328,8.825986,-8.198359,-6.040897,0.000000
+0,1,9333,8.708306,-7.374601,-6.001670,0.000000
+0,1,9338,8.708306,-7.374601,-6.001670,0.000000
+0,1,9343,8.708306,-6.943109,-6.158576,0.000000
+0,1,9348,8.708306,-6.943109,-6.158576,0.000000
+0,1,9353,8.551399,-6.590069,-6.315483,0.000000
+0,1,9358,8.551399,-6.590069,-6.315483,0.000000
+0,1,9363,8.355267,-6.590069,-6.237030,0.000000
+0,1,9368,8.355267,-6.590069,-6.237030,0.000000
+0,1,9373,8.080680,-6.707749,-6.393936,0.000000
+0,1,9378,8.080680,-6.707749,-6.393936,0.000000
+0,1,9383,7.413828,-6.707749,-5.687858,0.000000
+0,1,9388,7.413828,-6.707749,-5.687858,0.000000
+0,1,9393,6.864655,-7.021562,-5.413271,0.000000
+0,1,9398,6.864655,-7.021562,-5.413271,0.000000
+0,1,9403,6.629296,-7.296148,-5.334818,0.000000
+0,1,9408,6.629296,-7.296148,-5.334818,0.000000
+0,1,9413,6.197803,-7.609961,-5.021005,0.000000
+0,1,9418,6.197803,-7.609961,-5.021005,0.000000
+0,1,9423,5.883990,-7.727641,-4.864099,0.000000
+0,1,9428,5.883990,-7.727641,-4.864099,0.000000
+0,1,9433,5.413271,-7.884547,-4.707192,0.000000
+0,1,9438,5.413271,-7.884547,-4.707192,0.000000
+0,1,9443,5.256365,-8.276814,-4.667965,0.000000
+0,1,9448,5.256365,-8.276814,-4.667965,0.000000
+0,1,9453,5.138685,-8.472946,-4.628739,0.000000
+0,1,9458,5.138685,-8.472946,-4.628739,0.000000
+0,1,9463,5.021005,-8.472946,-4.707192,0.000000
+0,1,9468,5.021005,-8.472946,-4.707192,0.000000
+0,1,9473,4.942552,-8.472946,-4.589512,0.000000
+0,1,9478,4.942552,-8.472946,-4.589512,0.000000
+0,1,9483,4.942552,-8.355267,-4.393379,0.000000
+0,1,9488,4.942552,-8.355267,-4.393379,0.000000
+0,1,9493,4.667965,-8.316040,-4.628739,0.000000
+0,1,9498,4.667965,-8.316040,-4.628739,0.000000
+0,1,9503,4.667965,-8.394493,-4.550286,0.000000
+0,1,9508,4.667965,-8.394493,-4.550286,0.000000
+0,1,9513,4.511059,-8.080680,-4.550286,0.000000
+0,1,9518,4.511059,-8.080680,-4.550286,0.000000
+0,1,9523,4.314926,-7.806094,-4.471833,0.000000
+0,1,9528,4.314926,-7.806094,-4.471833,0.000000
+0,1,9533,4.079566,-7.531507,-4.432606,0.000000
+0,1,9538,4.079566,-7.531507,-4.432606,0.000000
+0,1,9543,4.040340,-7.453054,-4.236473,0.000000
+0,1,9548,4.040340,-7.453054,-4.236473,0.000000
+0,1,9553,4.001113,-7.178468,-4.118793,0.000000
+0,1,9558,4.001113,-7.178468,-4.118793,0.000000
+0,1,9563,3.961887,-7.100015,-4.040340,0.000000
+0,1,9568,3.961887,-7.100015,-4.040340,0.000000
+0,1,9573,3.961887,-6.982335,-3.844207,0.000000
+0,1,9578,3.961887,-6.982335,-3.844207,0.000000
+0,1,9583,3.922660,-6.943109,-3.687301,0.000000
+0,1,9588,3.922660,-6.943109,-3.687301,0.000000
+0,1,9593,4.079566,-6.825429,-3.687301,0.000000
+0,1,9598,4.079566,-6.825429,-3.687301,0.000000
+0,1,9603,4.314926,-6.746975,-3.412714,0.000000
+0,1,9608,4.314926,-6.746975,-3.412714,0.000000
+0,1,9613,4.197247,-6.707749,-3.295035,0.000000
+0,1,9618,4.197247,-6.707749,-3.295035,0.000000
+0,1,9623,4.236473,-6.746975,-3.059675,0.000000
+0,1,9628,4.236473,-6.746975,-3.059675,0.000000
+0,1,9633,4.275700,-6.825429,-3.098902,0.000000
+0,1,9638,4.275700,-6.825429,-3.098902,0.000000
+0,1,9643,4.354153,-6.746975,-3.098902,0.000000
+0,1,9648,4.354153,-6.746975,-3.098902,0.000000
+0,1,9653,4.236473,-6.629296,-3.059675,0.000000
+0,1,9658,4.236473,-6.629296,-3.059675,0.000000
+0,1,9663,3.961887,-6.433163,-2.902768,0.000000
+0,1,9668,3.961887,-6.433163,-2.902768,0.000000
+0,1,9673,4.275700,-6.746975,-2.863542,0.000000
+0,1,9678,4.275700,-6.746975,-2.863542,0.000000
+0,1,9683,4.275700,-6.746975,-3.020448,0.000000
+0,1,9688,4.236473,-6.668522,-3.020448,0.000000
+0,1,9693,4.236473,-6.668522,-3.020448,0.000000
+0,1,9698,4.197247,-6.550843,-3.177355,0.000000
+0,1,9703,4.197247,-6.550843,-3.177355,0.000000
+0,1,9708,4.628739,-8.865212,-2.353596,0.000000
+0,1,9713,4.628739,-8.865212,-2.353596,0.000000
+0,1,9718,4.471833,-6.590069,-3.491168,0.000000
+0,1,9723,4.471833,-6.590069,-3.491168,0.000000
+0,1,9728,4.550286,-5.805537,-3.922660,0.000000
+0,1,9733,4.550286,-5.805537,-3.922660,0.000000
+0,1,9738,4.707192,-6.707749,-3.804980,0.000000
+0,1,9743,4.707192,-6.707749,-3.804980,0.000000
+0,1,9748,4.550286,-6.825429,-3.687301,0.000000
+0,1,9753,4.550286,-6.825429,-3.687301,0.000000
+0,1,9758,4.942552,-7.335374,-3.726527,0.000000
+0,1,9763,4.942552,-7.335374,-3.726527,0.000000
+0,1,9768,5.217138,-7.335374,-3.687301,0.000000
+0,1,9773,5.217138,-7.335374,-3.687301,0.000000
+0,1,9778,5.099459,-7.335374,-3.687301,0.000000
+0,1,9783,5.099459,-7.335374,-3.687301,0.000000
+0,1,9788,4.981779,-7.178468,-3.687301,0.000000
+0,1,9793,4.981779,-7.178468,-3.687301,0.000000
+0,1,9798,5.177911,-7.453054,-3.451941,0.000000
+0,1,9803,5.177911,-7.453054,-3.451941,0.000000
+0,1,9808,5.374045,-7.531507,-3.608848,0.000000
+0,1,9813,5.374045,-7.531507,-3.608848,0.000000
+0,1,9818,5.570178,-7.609961,-3.530394,0.000000
+0,1,9823,5.570178,-7.609961,-3.530394,0.000000
+0,1,9828,5.923217,-7.688414,-3.726527,0.000000
+0,1,9833,5.923217,-7.688414,-3.726527,0.000000
+0,1,9838,6.354709,-7.649188,-3.687301,0.000000
+0,1,9843,6.354709,-7.649188,-3.687301,0.000000
+0,1,9848,6.119350,-7.021562,-3.961887,0.000000
+0,1,9853,6.119350,-7.021562,-3.961887,0.000000
+0,1,9858,6.354709,-7.374601,-3.530394,0.000000
+0,1,9863,6.354709,-7.374601,-3.530394,0.000000
+0,1,9868,6.393936,-7.100015,-3.726527,0.000000
+0,1,9873,6.393936,-7.100015,-3.726527,0.000000
+0,1,9878,6.393936,-6.864655,-4.001113,0.000000
+0,1,9883,6.393936,-6.864655,-4.001113,0.000000
+0,1,9888,6.393936,-6.943109,-4.001113,0.000000
+0,1,9893,6.393936,-6.943109,-4.001113,0.000000
+0,1,9898,6.158576,-6.746975,-4.040340,0.000000
+0,1,9903,6.158576,-6.746975,-4.040340,0.000000
+0,1,9908,6.237030,-6.511616,-3.961887,0.000000
+0,1,9913,6.237030,-6.511616,-3.961887,0.000000
+0,1,9918,6.119350,-6.433163,-3.883434,0.000000
+0,1,9923,6.119350,-6.433163,-3.883434,0.000000
+0,1,9928,5.962444,-6.237030,-3.687301,0.000000
+0,1,9933,5.962444,-6.237030,-3.687301,0.000000
+0,1,9938,6.511616,-6.943109,-3.491168,0.000000
+0,1,9943,6.511616,-6.943109,-3.491168,0.000000
+0,1,9948,7.178468,-8.119907,-3.530394,0.000000
+0,1,9953,7.178468,-8.119907,-3.530394,0.000000
+0,1,9958,7.492281,-8.433720,-3.961887,0.000000
+0,1,9963,7.492281,-8.433720,-3.961887,0.000000
+0,1,9968,8.080680,-9.375158,-3.883434,0.000000
+0,1,9973,8.080680,-9.375158,-3.883434,0.000000
+0,1,9978,8.433720,-10.081236,-4.275700,0.000000
+0,1,9983,8.433720,-10.081236,-4.275700,0.000000
+0,1,9988,8.355267,-9.963557,-4.550286,0.000000
+0,1,9993,8.355267,-9.963557,-4.550286,0.000000
+0,1,9998,7.923774,-9.100572,-5.099459,0.000000
+0,1,10003,7.923774,-9.100572,-5.099459,0.000000
+0,1,10008,7.570734,-8.237586,-5.099459,0.000000
+0,1,10013,7.570734,-8.237586,-5.099459,0.000000
+0,1,10018,7.492281,-7.688414,-5.413271,0.000000
+0,1,10023,7.492281,-7.688414,-5.413271,0.000000
+0,1,10028,7.570734,-7.335374,-5.766310,0.000000
+0,1,10033,7.570734,-7.335374,-5.766310,0.000000
+0,1,10038,7.531507,-6.746975,-5.923217,0.000000
+0,1,10043,7.531507,-6.746975,-5.923217,0.000000
+0,1,10048,7.413828,-6.433163,-5.805537,0.000000
+0,1,10053,7.413828,-6.433163,-5.805537,0.000000
+0,1,10058,7.060789,-6.119350,-6.119350,0.000000
+0,1,10063,7.060789,-6.119350,-6.119350,0.000000
+0,1,10068,7.139242,-6.550843,-6.158576,0.000000
+0,1,10073,7.139242,-6.550843,-6.158576,0.000000
+0,1,10078,7.139242,-7.100015,-6.119350,0.000000
+0,1,10083,7.139242,-7.100015,-6.119350,0.000000
+0,1,10088,7.021562,-7.531507,-6.040897,0.000000
+0,1,10093,7.021562,-7.531507,-6.040897,0.000000
+0,1,10098,7.217695,-7.256921,-6.080123,0.000000
+0,1,10103,7.217695,-7.256921,-6.080123,0.000000
+0,1,10108,7.374601,-7.060789,-5.883990,0.000000
+0,1,10113,7.374601,-7.060789,-5.883990,0.000000
+0,1,10118,7.492281,-6.825429,-5.844764,0.000000
+0,1,10123,7.492281,-6.825429,-5.844764,0.000000
+0,1,10128,7.649188,-6.668522,-5.844764,0.000000
+0,1,10133,7.649188,-6.668522,-5.844764,0.000000
+0,1,10138,7.727641,-6.511616,-5.687858,0.000000
+0,1,10143,7.727641,-6.511616,-5.687858,0.000000
+0,1,10148,7.727641,-6.511616,-5.687858,0.000000
+0,1,10153,7.570734,-6.276257,-5.609404,0.000000
+0,1,10158,7.570734,-6.276257,-5.609404,0.000000
+0,1,10163,7.335374,-5.766310,-5.217138,0.000000
+0,1,10168,7.335374,-5.766310,-5.217138,0.000000
+0,1,10173,6.982335,-5.570178,-4.785645,0.000000
+0,1,10178,6.982335,-5.570178,-4.785645,0.000000
+0,1,10183,6.629296,-5.295591,-4.354153,0.000000
+0,1,10188,6.629296,-5.295591,-4.354153,0.000000
+0,1,10193,6.354709,-5.295591,-3.961887,0.000000
+0,1,10198,6.354709,-5.295591,-3.961887,0.000000
+0,1,10203,5.844764,-5.295591,-3.804980,0.000000
+0,1,10208,5.844764,-5.295591,-3.804980,0.000000
+0,1,10213,5.413271,-5.256365,-3.530394,0.000000
+0,1,10218,5.413271,-5.256365,-3.530394,0.000000
+0,1,10223,5.021005,-5.099459,-3.295035,0.000000
+0,1,10228,5.021005,-5.099459,-3.295035,0.000000
+0,1,10233,4.707192,-5.256365,-2.941995,0.000000
+0,1,10238,4.707192,-5.256365,-2.941995,0.000000
+0,1,10243,4.471833,-5.374045,-2.824315,0.000000
+0,1,10248,4.471833,-5.374045,-2.824315,0.000000
+0,1,10253,4.393379,-5.452498,-2.706636,0.000000
+0,1,10258,4.393379,-5.452498,-2.706636,0.000000
+0,1,10263,4.197247,-5.570178,-2.588956,0.000000
+0,1,10268,4.197247,-5.570178,-2.588956,0.000000
+0,1,10273,4.118793,-5.491724,-2.549729,0.000000
+0,1,10278,4.118793,-5.491724,-2.549729,0.000000
+0,1,10283,3.961887,-5.530951,-2.510503,0.000000
+0,1,10288,3.961887,-5.530951,-2.510503,0.000000
+0,1,10293,4.079566,-5.844764,-2.706636,0.000000
+0,1,10298,4.079566,-5.844764,-2.706636,0.000000
+0,1,10303,4.079566,-5.844764,-2.667409,0.000000
+0,1,10308,4.079566,-5.844764,-2.667409,0.000000
+0,1,10313,4.158020,-6.080123,-2.745862,0.000000
+0,1,10318,4.158020,-6.080123,-2.745862,0.000000
+0,1,10323,4.275700,-6.158576,-2.863542,0.000000
+0,1,10328,4.275700,-6.158576,-2.863542,0.000000
+0,1,10333,4.275700,-6.237030,-2.941995,0.000000
+0,1,10338,4.275700,-6.237030,-2.941995,0.000000
+0,1,10343,4.511059,-6.511616,-2.981222,0.000000
+0,1,10348,4.511059,-6.511616,-2.981222,0.000000
+0,1,10353,4.667965,-6.550843,-3.177355,0.000000
+0,1,10358,4.667965,-6.550843,-3.177355,0.000000
+0,1,10363,4.942552,-6.550843,-3.451941,0.000000
+0,1,10368,4.942552,-6.550843,-3.451941,0.000000
+0,1,10373,5.099459,-6.472389,-3.451941,0.000000
+0,1,10378,5.099459,-6.472389,-3.451941,0.000000
+0,1,10383,5.334818,-6.550843,-3.608848,0.000000
+0,1,10388,5.334818,-6.550843,-3.608848,0.000000
+0,1,10393,5.530951,-6.707749,-3.726527,0.000000
+0,1,10398,5.530951,-6.707749,-3.726527,0.000000
+0,1,10403,5.687858,-6.786202,-3.804980,0.000000
+0,1,10408,5.687858,-6.786202,-3.804980,0.000000
+0,1,10413,5.883990,-6.825429,-4.079566,0.000000
+0,1,10418,5.883990,-6.825429,-4.079566,0.000000
+0,1,10423,5.923217,-6.864655,-4.118793,0.000000
+0,1,10428,5.923217,-6.864655,-4.118793,0.000000
+0,1,10433,6.276257,-7.021562,-4.550286,0.000000
+0,1,10438,6.276257,-7.021562,-4.550286,0.000000
+0,1,10443,6.629296,-7.100015,-4.432606,0.000000
+0,1,10448,6.629296,-7.100015,-4.432606,0.000000
+0,1,10453,6.864655,-7.060789,-4.393379,0.000000
+0,1,10458,6.864655,-7.060789,-4.393379,0.000000
+0,1,10463,6.982335,-6.864655,-4.236473,0.000000
+0,1,10468,6.982335,-6.864655,-4.236473,0.000000
+0,1,10473,7.217695,-6.668522,-4.197247,0.000000
+0,1,10478,7.217695,-6.668522,-4.197247,0.000000
+0,1,10483,7.531507,-6.746975,-4.432606,0.000000
+0,1,10488,7.531507,-6.746975,-4.432606,0.000000
+0,1,10493,7.727641,-6.982335,-4.432606,0.000000
+0,1,10498,7.727641,-6.982335,-4.432606,0.000000
+0,1,10503,7.923774,-6.825429,-4.471833,0.000000
+0,1,10508,7.923774,-6.825429,-4.471833,0.000000
+0,1,10513,7.963000,-6.746975,-4.511059,0.000000
+0,1,10518,7.963000,-6.746975,-4.511059,0.000000
+0,1,10523,8.002227,-6.746975,-4.707192,0.000000
+0,1,10528,8.002227,-6.746975,-4.707192,0.000000
+0,1,10533,7.766868,-6.550843,-4.785645,0.000000
+0,1,10538,7.766868,-6.550843,-4.785645,0.000000
+0,1,10543,7.649188,-6.393936,-5.099459,0.000000
+0,1,10548,7.649188,-6.393936,-5.099459,0.000000
+0,1,10553,7.570734,-6.315483,-4.981779,0.000000
+0,1,10558,7.570734,-6.315483,-4.981779,0.000000
+0,1,10563,7.335374,-6.119350,-5.138685,0.000000
+0,1,10568,7.335374,-6.119350,-5.138685,0.000000
+0,1,10573,7.139242,-6.119350,-5.177911,0.000000
+0,1,10578,7.139242,-6.119350,-5.177911,0.000000
+0,1,10583,7.139242,-6.786202,-4.981779,0.000000
+0,1,10588,7.139242,-6.786202,-4.981779,0.000000
+0,1,10593,7.217695,-7.923774,-4.981779,0.000000
+0,1,10598,7.217695,-7.923774,-4.981779,0.000000
+0,1,10603,7.374601,-8.629852,-5.021005,0.000000
+0,1,10608,7.374601,-8.629852,-5.021005,0.000000
+0,1,10613,7.374601,-8.629852,-5.021005,0.000000
+0,1,10618,7.256921,-8.865212,-4.942552,0.000000
+0,1,10623,7.256921,-8.865212,-4.942552,0.000000
+0,1,10628,7.296148,-8.825986,-5.256365,0.000000
+0,1,10633,7.296148,-8.825986,-5.256365,0.000000
+0,1,10638,7.413828,-8.276814,-5.687858,0.000000
+0,1,10643,7.413828,-8.276814,-5.687858,0.000000
+0,1,10648,7.845320,-7.963000,-5.609404,0.000000
+0,1,10653,7.845320,-7.963000,-5.609404,0.000000
+0,1,10658,8.041453,-7.609961,-5.766310,0.000000
+0,1,10663,8.041453,-7.609961,-5.766310,0.000000
+0,1,10668,8.159133,-7.413828,-6.119350,0.000000
+0,1,10673,8.159133,-7.413828,-6.119350,0.000000
+0,1,10678,8.237586,-7.374601,-6.119350,0.000000
+0,1,10683,8.237586,-7.374601,-6.119350,0.000000
+0,1,10688,8.237586,-7.256921,-6.433163,0.000000
+0,1,10693,8.237586,-7.256921,-6.433163,0.000000
+0,1,10698,8.159133,-7.296148,-6.511616,0.000000
+0,1,10703,8.159133,-7.296148,-6.511616,0.000000
+0,1,10708,7.727641,-7.296148,-6.237030,0.000000
+0,1,10713,7.727641,-7.296148,-6.237030,0.000000
+0,1,10718,7.296148,-7.178468,-6.119350,0.000000
+0,1,10723,7.296148,-7.178468,-6.119350,0.000000
+0,1,10728,6.746975,-7.256921,-5.766310,0.000000
+0,1,10733,6.746975,-7.256921,-5.766310,0.000000
+0,1,10738,6.433163,-7.374601,-5.491724,0.000000
+0,1,10743,6.433163,-7.374601,-5.491724,0.000000
+0,1,10748,5.805537,-7.453054,-5.177911,0.000000
+0,1,10753,5.805537,-7.453054,-5.177911,0.000000
+0,1,10758,5.452498,-7.688414,-5.060232,0.000000
+0,1,10763,5.452498,-7.688414,-5.060232,0.000000
+0,1,10768,5.256365,-7.845320,-4.942552,0.000000
+0,1,10773,5.256365,-7.845320,-4.942552,0.000000
+0,1,10778,5.021005,-7.923774,-4.785645,0.000000
+0,1,10783,5.021005,-7.923774,-4.785645,0.000000
+0,1,10788,4.824872,-8.119907,-4.707192,0.000000
+0,1,10793,4.824872,-8.119907,-4.707192,0.000000
+0,1,10798,4.707192,-8.237586,-4.589512,0.000000
+0,1,10803,4.707192,-8.237586,-4.589512,0.000000
+0,1,10808,4.589512,-8.316040,-4.471833,0.000000
+0,1,10813,4.589512,-8.316040,-4.471833,0.000000
+0,1,10818,4.511059,-8.355267,-4.393379,0.000000
+0,1,10823,4.511059,-8.355267,-4.393379,0.000000
+0,1,10828,4.511059,-8.394493,-4.314926,0.000000
+0,1,10833,4.511059,-8.394493,-4.314926,0.000000
+0,1,10838,4.471833,-8.433720,-4.393379,0.000000
+0,1,10843,4.471833,-8.433720,-4.393379,0.000000
+0,1,10848,4.550286,-8.237586,-4.393379,0.000000
+0,1,10853,4.550286,-8.237586,-4.393379,0.000000
+0,1,10858,4.511059,-8.041453,-4.314926,0.000000
+0,1,10863,4.511059,-8.041453,-4.314926,0.000000
+0,1,10868,4.393379,-7.845320,-4.275700,0.000000
+0,1,10873,4.393379,-7.845320,-4.275700,0.000000
+0,1,10878,4.393379,-7.649188,-4.314926,0.000000
+0,1,10883,4.393379,-7.649188,-4.314926,0.000000
+0,1,10888,4.354153,-7.609961,-4.236473,0.000000
+0,1,10893,4.354153,-7.609961,-4.236473,0.000000
+0,1,10898,4.432606,-7.492281,-4.158020,0.000000
+0,1,10903,4.432606,-7.492281,-4.158020,0.000000
+0,1,10908,4.432606,-7.453054,-4.079566,0.000000
+0,1,10913,4.432606,-7.453054,-4.079566,0.000000
+0,1,10918,4.511059,-7.453054,-4.079566,0.000000
+0,1,10923,4.511059,-7.453054,-4.079566,0.000000
+0,1,10928,4.667965,-7.335374,-3.961887,0.000000
+0,1,10933,4.667965,-7.335374,-3.961887,0.000000
+0,1,10938,4.824872,-7.335374,-3.844207,0.000000
+0,1,10943,4.824872,-7.335374,-3.844207,0.000000
+0,1,10948,4.746419,-7.217695,-3.765754,0.000000
+0,1,10953,4.746419,-7.217695,-3.765754,0.000000
+0,1,10958,4.785645,-7.217695,-3.726527,0.000000
+0,1,10963,4.785645,-7.217695,-3.726527,0.000000
+0,1,10968,4.707192,-7.217695,-3.530394,0.000000
+0,1,10973,4.707192,-7.217695,-3.530394,0.000000
+0,1,10978,4.667965,-7.060789,-3.412714,0.000000
+0,1,10983,4.667965,-7.060789,-3.412714,0.000000
+0,1,10988,4.550286,-7.100015,-3.255808,0.000000
+0,1,10993,4.550286,-7.100015,-3.255808,0.000000
+0,1,10998,4.550286,-7.060789,-3.138128,0.000000
+0,1,11003,4.550286,-7.060789,-3.138128,0.000000
+0,1,11008,4.589512,-6.982335,-3.059675,0.000000
+0,1,11013,4.589512,-6.982335,-3.059675,0.000000
+0,1,11018,4.589512,-6.982335,-3.020448,0.000000
+0,1,11023,4.589512,-6.982335,-3.020448,0.000000
+0,1,11028,4.511059,-6.825429,-2.785089,0.000000
+0,1,11033,4.511059,-6.825429,-2.785089,0.000000
+0,1,11038,4.550286,-6.629296,-2.706636,0.000000
+0,1,11043,4.550286,-6.629296,-2.706636,0.000000
+0,1,11048,4.667965,-6.550843,-2.628182,0.000000
+0,1,11053,4.667965,-6.550843,-2.628182,0.000000
+0,1,11058,4.785645,-6.511616,-2.667409,0.000000
+0,1,11063,4.785645,-6.511616,-2.667409,0.000000
+0,1,11068,4.942552,-6.511616,-2.902768,0.000000
+0,1,11073,4.981779,-6.511616,-2.902768,0.000000
+0,1,11078,4.981779,-6.511616,-2.902768,0.000000
+0,1,11083,5.138685,-6.550843,-2.981222,0.000000
+0,1,11088,5.138685,-6.550843,-2.981222,0.000000
+0,1,11093,5.452498,-6.707749,-3.255808,0.000000
+0,1,11098,5.452498,-6.707749,-3.255808,0.000000
+0,1,11103,5.609404,-6.903882,-3.373488,0.000000
+0,1,11108,5.609404,-6.903882,-3.373488,0.000000
+0,1,11113,5.844764,-7.021562,-3.373488,0.000000
+0,1,11118,5.844764,-7.021562,-3.373488,0.000000
+0,1,11123,6.001670,-7.256921,-3.412714,0.000000
+0,1,11128,6.001670,-7.256921,-3.412714,0.000000
+0,1,11133,6.315483,-7.413828,-3.138128,0.000000
+0,1,11138,6.315483,-7.413828,-3.138128,0.000000
+0,1,11143,6.511616,-7.413828,-3.098902,0.000000
+0,1,11148,6.511616,-7.413828,-3.098902,0.000000
+0,1,11153,6.786202,-7.256921,-3.098902,0.000000
+0,1,11158,6.786202,-7.256921,-3.098902,0.000000
+0,1,11163,6.786202,-7.256921,-3.098902,0.000000
+0,1,11168,6.786202,-7.256921,-3.098902,0.000000
+0,1,11173,6.590069,-7.021562,-3.098902,0.000000
+0,1,11178,6.590069,-7.021562,-3.098902,0.000000
+0,1,11183,6.393936,-6.864655,-3.295035,0.000000
+0,1,11188,6.393936,-6.864655,-3.295035,0.000000
+0,1,11193,6.276257,-6.707749,-3.334261,0.000000
+0,1,11198,6.276257,-6.707749,-3.334261,0.000000
+0,1,11203,6.158576,-6.511616,-3.295035,0.000000
+0,1,11208,6.158576,-6.511616,-3.295035,0.000000
+0,1,11213,6.001670,-6.393936,-3.373488,0.000000
+0,1,11218,6.001670,-6.393936,-3.373488,0.000000
+0,1,11223,6.119350,-6.472389,-3.138128,0.000000
+0,1,11228,6.119350,-6.472389,-3.138128,0.000000
+0,1,11233,6.197803,-6.786202,-2.981222,0.000000
+0,1,11238,6.197803,-6.786202,-2.981222,0.000000
+0,1,11243,6.511616,-7.609961,-2.628182,0.000000
+0,1,11248,6.511616,-7.609961,-2.628182,0.000000
+0,1,11253,6.746975,-8.041453,-2.628182,0.000000
+0,1,11258,6.746975,-8.041453,-2.628182,0.000000
+0,1,11263,6.668522,-8.669080,-2.941995,0.000000
+0,1,11268,6.668522,-8.669080,-2.941995,0.000000
+0,1,11273,6.825429,-9.335931,-3.059675,0.000000
+0,1,11278,6.825429,-9.335931,-3.059675,0.000000
+0,1,11283,6.903882,-9.649744,-3.177355,0.000000
+0,1,11288,6.903882,-9.649744,-3.177355,0.000000
+0,1,11293,7.021562,-9.335931,-3.687301,0.000000
+0,1,11298,7.021562,-9.335931,-3.687301,0.000000
+0,1,11303,7.139242,-9.061345,-3.961887,0.000000
+0,1,11308,7.139242,-9.061345,-3.961887,0.000000
+0,1,11313,7.413828,-8.472946,-4.158020,0.000000
+0,1,11318,7.413828,-8.472946,-4.158020,0.000000
+0,1,11323,7.492281,-7.884547,-4.393379,0.000000
+0,1,11328,7.492281,-7.884547,-4.393379,0.000000
+0,1,11333,7.531507,-7.335374,-4.628739,0.000000
+0,1,11338,7.531507,-7.335374,-4.628739,0.000000
+0,1,11343,7.492281,-6.786202,-4.824872,0.000000
+0,1,11348,7.492281,-6.786202,-4.824872,0.000000
+0,1,11353,7.531507,-6.354709,-4.903325,0.000000
+0,1,11358,7.531507,-6.354709,-4.903325,0.000000
+0,1,11363,7.453054,-6.197803,-4.864099,0.000000
+0,1,11368,7.453054,-6.197803,-4.864099,0.000000
+0,1,11373,7.256921,-6.354709,-4.864099,0.000000
+0,1,11378,7.256921,-6.354709,-4.864099,0.000000
+0,1,11383,7.217695,-6.746975,-4.864099,0.000000
+0,1,11388,7.217695,-6.746975,-4.864099,0.000000
+0,1,11393,7.100015,-7.256921,-4.903325,0.000000
+0,1,11398,7.100015,-7.256921,-4.903325,0.000000
+0,1,11403,7.139242,-7.335374,-4.903325,0.000000
+0,1,11408,7.139242,-7.335374,-4.903325,0.000000
+0,1,11413,7.217695,-7.296148,-4.864099,0.000000
+0,1,11418,7.217695,-7.296148,-4.864099,0.000000
+0,1,11423,7.256921,-7.060789,-4.707192,0.000000
+0,1,11428,7.256921,-7.060789,-4.707192,0.000000
+0,1,11433,7.374601,-6.903882,-4.589512,0.000000
+0,1,11438,7.374601,-6.903882,-4.589512,0.000000
+0,1,11443,7.335374,-6.786202,-4.511059,0.000000
+0,1,11448,7.335374,-6.786202,-4.511059,0.000000
+0,1,11453,7.139242,-6.590069,-4.314926,0.000000
+0,1,11458,7.139242,-6.590069,-4.314926,0.000000
+0,1,11463,6.982335,-6.472389,-4.236473,0.000000
+0,1,11468,6.982335,-6.472389,-4.236473,0.000000
+0,1,11473,6.550843,-6.276257,-3.922660,0.000000
+0,1,11478,6.550843,-6.276257,-3.922660,0.000000
+0,1,11483,6.237030,-6.119350,-3.648074,0.000000
+0,1,11488,6.237030,-6.119350,-3.648074,0.000000
+0,1,11493,5.805537,-6.001670,-3.451941,0.000000
+0,1,11498,5.805537,-6.001670,-3.451941,0.000000
+0,1,11503,5.374045,-6.040897,-3.138128,0.000000
+0,1,11508,5.374045,-6.040897,-3.138128,0.000000
+0,1,11513,5.177911,-5.962444,-2.981222,0.000000
+0,1,11518,5.177911,-5.962444,-2.981222,0.000000
+0,1,11523,4.942552,-5.805537,-2.745862,0.000000
+0,1,11528,4.942552,-5.805537,-2.745862,0.000000
+0,1,11533,4.864099,-5.766310,-2.745862,0.000000
+0,1,11538,4.864099,-5.766310,-2.745862,0.000000
+0,1,11543,4.864099,-5.766310,-2.745862,0.000000
+0,1,11548,4.824872,-5.687858,-2.549729,0.000000
+0,1,11553,4.824872,-5.687858,-2.549729,0.000000
+0,1,11558,4.864099,-5.609404,-2.432049,0.000000
+0,1,11563,4.864099,-5.609404,-2.432049,0.000000
+0,1,11568,4.707192,-5.530951,-2.275143,0.000000
+0,1,11573,4.707192,-5.530951,-2.275143,0.000000
+0,1,11578,4.785645,-5.452498,-2.314370,0.000000
+0,1,11583,4.785645,-5.452498,-2.314370,0.000000
+0,1,11588,4.707192,-5.687858,-2.235916,0.000000
+0,1,11593,4.707192,-5.687858,-2.235916,0.000000
+0,1,11598,4.942552,-5.648631,-2.353596,0.000000
+0,1,11603,4.942552,-5.648631,-2.353596,0.000000
+0,1,11608,4.746419,-5.609404,-2.392823,0.000000
+0,1,11613,4.746419,-5.609404,-2.392823,0.000000
+0,1,11618,4.903325,-5.648631,-2.628182,0.000000
+0,1,11623,4.903325,-5.648631,-2.628182,0.000000
+0,1,11628,4.864099,-5.962444,-2.588956,0.000000
+0,1,11633,4.864099,-5.962444,-2.588956,0.000000
+0,1,11638,4.903325,-6.119350,-2.824315,0.000000
+0,1,11643,4.903325,-6.119350,-2.824315,0.000000
+0,1,11648,4.864099,-6.393936,-2.824315,0.000000
+0,1,11653,4.864099,-6.393936,-2.824315,0.000000
+0,1,11658,4.942552,-6.511616,-2.981222,0.000000
+0,1,11663,4.942552,-6.511616,-2.981222,0.000000
+0,1,11668,4.981779,-6.590069,-3.177355,0.000000
+0,1,11673,4.981779,-6.590069,-3.177355,0.000000
+0,1,11678,5.099459,-6.629296,-3.373488,0.000000
+0,1,11683,5.099459,-6.629296,-3.373488,0.000000
+0,1,11688,5.177911,-6.629296,-3.491168,0.000000
+0,1,11693,5.177911,-6.629296,-3.491168,0.000000
+0,1,11698,5.334818,-6.668522,-3.726527,0.000000
+0,1,11703,5.334818,-6.668522,-3.726527,0.000000
+0,1,11708,5.530951,-6.629296,-4.001113,0.000000
+0,1,11713,5.530951,-6.629296,-4.001113,0.000000
+0,1,11718,5.727084,-6.746975,-4.275700,0.000000
+0,1,11723,5.727084,-6.746975,-4.275700,0.000000
+0,1,11728,6.040897,-6.786202,-4.511059,0.000000
+0,1,11733,6.040897,-6.786202,-4.511059,0.000000
+0,1,11738,6.433163,-6.982335,-4.707192,0.000000
+0,1,11743,6.433163,-6.982335,-4.707192,0.000000
+0,1,11748,6.786202,-7.100015,-4.707192,0.000000
+0,1,11753,6.786202,-7.100015,-4.707192,0.000000
+0,1,11758,7.178468,-7.335374,-4.824872,0.000000
+0,1,11763,7.178468,-7.335374,-4.824872,0.000000
+0,1,11768,7.609961,-7.296148,-4.864099,0.000000
+0,1,11773,7.609961,-7.296148,-4.864099,0.000000
+0,1,11778,7.884547,-7.413828,-4.746419,0.000000
+0,1,11783,7.884547,-7.413828,-4.746419,0.000000
+0,1,11788,8.080680,-7.335374,-4.903325,0.000000
+0,1,11793,8.080680,-7.335374,-4.903325,0.000000
+0,1,11798,8.472946,-7.296148,-4.942552,0.000000
+0,1,11803,8.472946,-7.296148,-4.942552,0.000000
+0,1,11808,8.825986,-7.335374,-5.099459,0.000000
+0,1,11813,8.825986,-7.335374,-5.099459,0.000000
+0,1,11818,9.061345,-7.256921,-5.099459,0.000000
+0,1,11823,9.061345,-7.256921,-5.099459,0.000000
+0,1,11828,9.061345,-7.178468,-5.334818,0.000000
+0,1,11833,9.061345,-7.178468,-5.334818,0.000000
+0,1,11838,9.257479,-7.139242,-5.413271,0.000000
+0,1,11843,9.257479,-7.139242,-5.413271,0.000000
+0,1,11848,8.904439,-6.825429,-5.491724,0.000000
+0,1,11853,8.904439,-6.825429,-5.491724,0.000000
+0,1,11858,8.786758,-6.550843,-5.530951,0.000000
+0,1,11863,8.786758,-6.550843,-5.530951,0.000000
+0,1,11868,8.394493,-6.903882,-5.452498,0.000000
+0,1,11873,8.394493,-6.903882,-5.452498,0.000000
+0,1,11878,8.080680,-7.296148,-5.334818,0.000000
+0,1,11883,8.080680,-7.296148,-5.334818,0.000000
+0,1,11888,8.002227,-8.276814,-5.374045,0.000000
+0,1,11893,8.002227,-8.276814,-5.374045,0.000000
+0,1,11898,7.923774,-9.100572,-4.942552,0.000000
+0,1,11903,7.923774,-9.100572,-4.942552,0.000000
+0,1,11908,7.963000,-9.296705,-4.981779,0.000000
+0,1,11913,7.963000,-9.296705,-4.981779,0.000000
+0,1,11918,8.041453,-9.414385,-4.903325,0.000000
+0,1,11923,8.041453,-9.414385,-4.903325,0.000000
+0,1,11928,7.963000,-9.414385,-5.060232,0.000000
+0,1,11933,7.963000,-9.414385,-5.060232,0.000000
+0,1,11938,8.159133,-9.139798,-4.824872,0.000000
+0,1,11943,8.159133,-9.139798,-4.824872,0.000000
+0,1,11948,8.080680,-8.865212,-5.334818,0.000000
+0,1,11953,8.080680,-8.865212,-5.334818,0.000000
+0,1,11958,8.002227,-8.512173,-5.295591,0.000000
+0,1,11963,8.002227,-8.512173,-5.295591,0.000000
+0,1,11968,7.649188,-8.472946,-5.295591,0.000000
+0,1,11973,7.649188,-8.472946,-5.295591,0.000000
+0,1,11978,7.374601,-8.237586,-5.374045,0.000000
+0,1,11983,7.374601,-8.237586,-5.374045,0.000000
+0,1,11988,6.982335,-7.923774,-5.570178,0.000000
+0,1,11993,6.982335,-7.923774,-5.570178,0.000000
+0,1,11998,6.982335,-7.609961,-5.413271,0.000000
+0,1,12003,6.550843,-7.649188,-5.452498,0.000000
+0,1,12008,6.550843,-7.649188,-5.452498,0.000000
+0,1,12013,5.923217,-7.766868,-5.295591,0.000000
+0,1,12018,5.923217,-7.766868,-5.295591,0.000000
+0,1,12023,5.491724,-7.688414,-4.824872,0.000000
+0,1,12028,5.491724,-7.688414,-4.824872,0.000000
+0,1,12033,5.099459,-7.766868,-4.667965,0.000000
+0,1,12038,5.099459,-7.766868,-4.667965,0.000000
+0,1,12043,4.903325,-8.080680,-4.314926,0.000000
+0,1,12048,4.903325,-8.080680,-4.314926,0.000000
+0,1,12053,4.667965,-8.355267,-4.158020,0.000000
+0,1,12058,4.667965,-8.355267,-4.158020,0.000000
+0,1,12063,4.432606,-8.433720,-3.922660,0.000000
+0,1,12068,4.432606,-8.433720,-3.922660,0.000000
+0,1,12073,4.314926,-8.433720,-3.804980,0.000000
+0,1,12078,4.314926,-8.433720,-3.804980,0.000000
+0,1,12083,4.275700,-8.551399,-3.687301,0.000000
+0,1,12088,4.275700,-8.551399,-3.687301,0.000000
+0,1,12093,4.275700,-8.551399,-3.765754,0.000000
+0,1,12098,4.275700,-8.551399,-3.765754,0.000000
+0,1,12103,4.275700,-8.629852,-3.765754,0.000000
+0,1,12108,4.275700,-8.629852,-3.765754,0.000000
+0,1,12113,4.197247,-8.708306,-3.844207,0.000000
+0,1,12118,4.197247,-8.708306,-3.844207,0.000000
+0,1,12123,4.118793,-8.786758,-3.961887,0.000000
+0,1,12128,4.118793,-8.786758,-3.961887,0.000000
+0,1,12133,4.040340,-8.708306,-3.961887,0.000000
+0,1,12138,4.040340,-8.708306,-3.961887,0.000000
+0,1,12143,3.922660,-8.551399,-4.236473,0.000000
+0,1,12148,3.922660,-8.551399,-4.236473,0.000000
+0,1,12153,3.922660,-8.355267,-4.197247,0.000000
+0,1,12158,3.922660,-8.355267,-4.197247,0.000000
+0,1,12163,3.765754,-8.237586,-4.197247,0.000000
+0,1,12168,3.765754,-8.237586,-4.197247,0.000000
+0,1,12173,3.726527,-8.159133,-4.197247,0.000000
+0,1,12178,3.726527,-8.159133,-4.197247,0.000000
+0,1,12183,3.608848,-7.884547,-4.079566,0.000000
+0,1,12188,3.608848,-7.884547,-4.079566,0.000000
+0,1,12193,3.608848,-7.845320,-3.961887,0.000000
+0,1,12198,3.608848,-7.845320,-3.961887,0.000000
+0,1,12203,3.530394,-7.727641,-3.804980,0.000000
+0,1,12208,3.530394,-7.727641,-3.804980,0.000000
+0,1,12213,3.530394,-7.806094,-3.648074,0.000000
+0,1,12218,3.530394,-7.806094,-3.648074,0.000000
+0,1,12223,3.451941,-7.766868,-3.648074,0.000000
+0,1,12228,3.451941,-7.766868,-3.648074,0.000000
+0,1,12233,3.491168,-7.688414,-3.491168,0.000000
+0,1,12238,3.491168,-7.688414,-3.491168,0.000000
+0,1,12243,3.451941,-7.570734,-3.373488,0.000000
+0,1,12248,3.451941,-7.570734,-3.373488,0.000000
+0,1,12253,3.530394,-7.649188,-3.098902,0.000000
+0,1,12258,3.530394,-7.649188,-3.098902,0.000000
+0,1,12263,3.608848,-7.531507,-3.059675,0.000000
+0,1,12268,3.608848,-7.531507,-3.059675,0.000000
+0,1,12273,3.608848,-7.492281,-2.941995,0.000000
+0,1,12278,3.608848,-7.492281,-2.941995,0.000000
+0,1,12283,3.648074,-7.256921,-2.785089,0.000000
+0,1,12288,3.648074,-7.256921,-2.785089,0.000000
+0,1,12293,3.687301,-7.217695,-2.706636,0.000000
+0,1,12298,3.687301,-7.217695,-2.706636,0.000000
+0,1,12303,3.883434,-7.100015,-2.706636,0.000000
+0,1,12308,3.883434,-7.100015,-2.706636,0.000000
+0,1,12313,3.922660,-7.100015,-2.667409,0.000000
+0,1,12318,3.922660,-7.100015,-2.667409,0.000000
+0,1,12323,4.079566,-7.100015,-2.745862,0.000000
+0,1,12328,4.079566,-7.100015,-2.745862,0.000000
+0,1,12333,4.197247,-6.982335,-2.667409,0.000000
+0,1,12338,4.197247,-6.982335,-2.667409,0.000000
+0,1,12343,4.275700,-6.982335,-2.745862,0.000000
+0,1,12348,4.275700,-6.982335,-2.745862,0.000000
+0,1,12353,4.354153,-7.021562,-2.628182,0.000000
+0,1,12358,4.354153,-7.021562,-2.628182,0.000000
+0,1,12363,4.354153,-7.021562,-2.667409,0.000000
+0,1,12368,4.354153,-7.021562,-2.667409,0.000000
+0,1,12373,4.354153,-7.139242,-2.432049,0.000000
+0,1,12378,4.354153,-7.139242,-2.432049,0.000000
+0,1,12383,4.471833,-7.256921,-2.392823,0.000000
+0,1,12388,4.471833,-7.256921,-2.392823,0.000000
+0,1,12393,4.667965,-7.374601,-2.510503,0.000000
+0,1,12398,4.667965,-7.374601,-2.510503,0.000000
+0,1,12403,4.746419,-7.531507,-2.549729,0.000000
+0,1,12408,4.746419,-7.531507,-2.549729,0.000000
+0,1,12413,5.021005,-7.688414,-2.785089,0.000000
+0,1,12418,5.021005,-7.688414,-2.785089,0.000000
+0,1,12423,5.177911,-7.727641,-2.785089,0.000000
+0,1,12428,5.177911,-7.727641,-2.785089,0.000000
+0,1,12433,5.374045,-7.766868,-2.745862,0.000000
+0,1,12438,5.374045,-7.766868,-2.745862,0.000000
+0,1,12443,5.530951,-7.845320,-2.863542,0.000000
+0,1,12448,5.530951,-7.845320,-2.863542,0.000000
+0,1,12453,5.883990,-8.002227,-2.902768,0.000000
+0,1,12458,5.883990,-8.002227,-2.902768,0.000000
+0,1,12463,5.883990,-8.002227,-2.902768,0.000000
+0,1,12468,6.119350,-7.963000,-3.059675,0.000000
+0,1,12473,6.119350,-7.963000,-3.059675,0.000000
+0,1,12478,6.276257,-8.002227,-3.177355,0.000000
+0,1,12483,6.276257,-8.002227,-3.177355,0.000000
+0,1,12488,6.511616,-8.119907,-3.373488,0.000000
+0,1,12493,6.511616,-8.119907,-3.373488,0.000000
+0,1,12498,6.433163,-7.923774,-3.491168,0.000000
+0,1,12503,6.433163,-7.923774,-3.491168,0.000000
+0,1,12508,6.393936,-7.963000,-3.648074,0.000000
+0,1,12513,6.393936,-7.963000,-3.648074,0.000000
+0,1,12518,6.354709,-7.884547,-3.648074,0.000000
+0,1,12523,6.354709,-7.884547,-3.648074,0.000000
+0,1,12528,6.276257,-7.766868,-3.648074,0.000000
+0,1,12533,6.276257,-7.766868,-3.648074,0.000000
+0,1,12538,6.040897,-7.570734,-3.648074,0.000000
+0,1,12543,6.040897,-7.570734,-3.648074,0.000000
+0,1,12548,5.844764,-7.492281,-3.569621,0.000000
+0,1,12553,5.844764,-7.492281,-3.569621,0.000000
+0,1,12558,5.844764,-7.766868,-3.334261,0.000000
+0,1,12563,5.844764,-7.766868,-3.334261,0.000000
+0,1,12568,6.119350,-8.669080,-3.177355,0.000000
+0,1,12573,6.119350,-8.669080,-3.177355,0.000000
+0,1,12578,6.668522,-9.453611,-3.059675,0.000000
+0,1,12583,6.668522,-9.453611,-3.059675,0.000000
+0,1,12588,6.903882,-9.688971,-3.530394,0.000000
+0,1,12593,6.903882,-9.688971,-3.530394,0.000000
+0,1,12598,7.531507,-9.924331,-3.804980,0.000000
+0,1,12603,7.531507,-9.924331,-3.804980,0.000000
+0,1,12608,7.806094,-9.963557,-4.001113,0.000000
+0,1,12613,7.806094,-9.963557,-4.001113,0.000000
+0,1,12618,7.884547,-9.688971,-4.118793,0.000000
+0,1,12623,7.884547,-9.688971,-4.118793,0.000000
+0,1,12628,7.884547,-9.100572,-4.432606,0.000000
+0,1,12633,7.884547,-9.100572,-4.432606,0.000000
+0,1,12638,7.963000,-8.512173,-4.589512,0.000000
+0,1,12643,7.963000,-8.512173,-4.589512,0.000000
+0,1,12648,8.002227,-8.041453,-4.746419,0.000000
+0,1,12653,8.002227,-8.041453,-4.746419,0.000000
+0,1,12658,7.963000,-7.570734,-4.824872,0.000000
+0,1,12663,7.963000,-7.570734,-4.824872,0.000000
+0,1,12668,7.845320,-6.903882,-5.099459,0.000000
+0,1,12678,7.727641,-6.393936,-5.256365,0.000000
+0,1,12683,7.727641,-6.393936,-5.256365,0.000000
+0,1,12688,7.492281,-6.040897,-5.138685,0.000000
+0,1,12693,7.492281,-6.040897,-5.138685,0.000000
+0,1,12698,7.335374,-5.805537,-5.099459,0.000000
+0,1,12703,7.335374,-5.805537,-5.099459,0.000000
+0,1,12708,7.178468,-5.962444,-5.099459,0.000000
+0,1,12713,7.178468,-5.962444,-5.099459,0.000000
+0,1,12718,7.100015,-6.237030,-5.099459,0.000000
+0,1,12723,7.100015,-6.237030,-5.099459,0.000000
+0,1,12728,6.864655,-6.511616,-5.138685,0.000000
+0,1,12733,6.864655,-6.511616,-5.138685,0.000000
+0,1,12738,6.668522,-6.590069,-5.021005,0.000000
+0,1,12743,6.668522,-6.590069,-5.021005,0.000000
+0,1,12748,6.550843,-6.550843,-5.021005,0.000000
+0,1,12753,6.550843,-6.550843,-5.021005,0.000000
+0,1,12758,6.472389,-6.590069,-4.981779,0.000000
+0,1,12763,6.472389,-6.590069,-4.981779,0.000000
+0,1,12768,6.433163,-6.668522,-4.942552,0.000000
+0,1,12773,6.433163,-6.668522,-4.942552,0.000000
+0,1,12778,6.315483,-6.668522,-4.824872,0.000000
+0,1,12783,6.315483,-6.668522,-4.824872,0.000000
+0,1,12788,6.276257,-6.825429,-4.628739,0.000000
+0,1,12793,6.276257,-6.825429,-4.628739,0.000000
+0,1,12798,6.158576,-6.982335,-4.628739,0.000000
+0,1,12803,6.158576,-6.982335,-4.628739,0.000000
+0,1,12808,6.080123,-7.060789,-4.393379,0.000000
+0,1,12813,6.080123,-7.060789,-4.393379,0.000000
+0,1,12818,5.844764,-6.982335,-4.314926,0.000000
+0,1,12823,5.844764,-6.982335,-4.314926,0.000000
+0,1,12828,5.687858,-6.943109,-4.236473,0.000000
+0,1,12833,5.687858,-6.943109,-4.236473,0.000000
+0,1,12838,5.452498,-6.786202,-4.158020,0.000000
+0,1,12843,5.452498,-6.786202,-4.158020,0.000000
+0,1,12848,5.374045,-6.668522,-4.079566,0.000000
+0,1,12853,5.374045,-6.668522,-4.079566,0.000000
+0,1,12858,5.374045,-6.550843,-3.883434,0.000000
+0,1,12863,5.374045,-6.550843,-3.883434,0.000000
+0,1,12868,5.374045,-6.472389,-3.765754,0.000000
+0,1,12873,5.374045,-6.472389,-3.765754,0.000000
+0,1,12878,5.138685,-6.315483,-3.648074,0.000000
+0,1,12883,5.138685,-6.315483,-3.648074,0.000000
+0,1,12888,5.060232,-6.197803,-3.569621,0.000000
+0,1,12893,5.060232,-6.197803,-3.569621,0.000000
+0,1,12898,4.981779,-6.197803,-3.451941,0.000000
+0,1,12903,4.981779,-6.197803,-3.451941,0.000000
+0,1,12908,5.021005,-6.158576,-3.412714,0.000000
+0,1,12913,5.021005,-6.158576,-3.412714,0.000000
+0,1,12918,5.021005,-6.158576,-3.412714,0.000000
+0,1,12923,4.746419,-6.276257,-3.138128,0.000000
+0,1,12928,4.746419,-6.276257,-3.138128,0.000000
+0,1,12933,4.550286,-6.315483,-3.098902,0.000000
+0,1,12938,4.550286,-6.315483,-3.098902,0.000000
+0,1,12943,4.471833,-6.433163,-3.020448,0.000000
+0,1,12948,4.471833,-6.433163,-3.020448,0.000000
+0,1,12953,4.314926,-6.472389,-3.020448,0.000000
+0,1,12958,4.314926,-6.472389,-3.020448,0.000000
+0,1,12963,4.314926,-6.629296,-3.098902,0.000000
+0,1,12968,4.314926,-6.629296,-3.098902,0.000000
+0,1,12973,4.354153,-6.590069,-2.941995,0.000000
+0,1,12978,4.354153,-6.590069,-2.941995,0.000000
+0,1,12983,4.550286,-6.786202,-3.020448,0.000000
+0,1,12988,4.550286,-6.786202,-3.020448,0.000000
+0,1,12993,4.785645,-6.746975,-3.098902,0.000000
+0,1,12998,4.785645,-6.746975,-3.098902,0.000000
+0,1,13003,4.903325,-6.668522,-3.177355,0.000000
+0,1,13008,4.903325,-6.668522,-3.177355,0.000000
+0,1,13013,4.824872,-6.550843,-3.020448,0.000000
+0,1,13018,4.824872,-6.550843,-3.020448,0.000000
+0,1,13023,4.981779,-6.668522,-2.941995,0.000000
+0,1,13028,4.981779,-6.668522,-2.941995,0.000000
+0,1,13033,5.060232,-6.511616,-3.098902,0.000000
+0,1,13038,5.060232,-6.511616,-3.098902,0.000000
+0,1,13043,5.021005,-6.668522,-3.255808,0.000000
+0,1,13048,5.021005,-6.668522,-3.255808,0.000000
+0,1,13053,5.060232,-6.668522,-3.412714,0.000000
+0,1,13058,5.060232,-6.668522,-3.412714,0.000000
+0,1,13063,5.138685,-6.668522,-3.451941,0.000000
+0,1,13068,5.138685,-6.668522,-3.451941,0.000000
+0,1,13073,5.256365,-6.746975,-3.608848,0.000000
+0,1,13078,5.256365,-6.746975,-3.608848,0.000000
+0,1,13083,5.491724,-6.786202,-3.648074,0.000000
+0,1,13088,5.491724,-6.786202,-3.648074,0.000000
+0,1,13093,5.570178,-6.746975,-3.648074,0.000000
+0,1,13098,5.570178,-6.746975,-3.648074,0.000000
+0,1,13103,5.766310,-6.943109,-3.608848,0.000000
+0,1,13108,5.766310,-6.943109,-3.608848,0.000000
+0,1,13113,6.158576,-7.060789,-3.648074,0.000000
+0,1,13118,6.158576,-7.060789,-3.648074,0.000000
+0,1,13123,6.276257,-6.825429,-3.765754,0.000000
+0,1,13128,6.276257,-6.825429,-3.765754,0.000000
+0,1,13133,6.629296,-7.060789,-3.765754,0.000000
+0,1,13138,6.629296,-7.060789,-3.765754,0.000000
+0,1,13143,6.903882,-7.296148,-3.883434,0.000000
+0,1,13148,6.903882,-7.296148,-3.883434,0.000000
+0,1,13153,7.021562,-7.217695,-4.040340,0.000000
+0,1,13158,7.021562,-7.217695,-4.040340,0.000000
+0,1,13163,6.982335,-7.296148,-4.079566,0.000000
+0,1,13168,6.982335,-7.296148,-4.079566,0.000000
+0,1,13173,7.139242,-7.296148,-4.275700,0.000000
+0,1,13178,7.139242,-7.296148,-4.275700,0.000000
+0,1,13183,7.139242,-7.492281,-4.471833,0.000000
+0,1,13188,7.139242,-7.492281,-4.471833,0.000000
+0,1,13193,7.021562,-7.217695,-4.864099,0.000000
+0,1,13198,7.021562,-7.217695,-4.864099,0.000000
+0,1,13203,7.100015,-7.139242,-4.785645,0.000000
+0,1,13208,7.100015,-7.139242,-4.785645,0.000000
+0,1,13213,6.864655,-6.746975,-5.021005,0.000000
+0,1,13218,6.864655,-6.746975,-5.021005,0.000000
+0,1,13223,6.707749,-6.668522,-5.021005,0.000000
+0,1,13228,6.707749,-6.668522,-5.021005,0.000000
+0,1,13233,6.511616,-6.943109,-4.942552,0.000000
+0,1,13238,6.511616,-6.943109,-4.942552,0.000000
+0,1,13243,6.903882,-8.159133,-4.864099,0.000000
+0,1,13248,6.903882,-8.159133,-4.864099,0.000000
+0,1,13253,7.217695,-9.335931,-4.550286,0.000000
+0,1,13258,7.217695,-9.335931,-4.550286,0.000000
+0,1,13263,7.217695,-9.806650,-4.589512,0.000000
+0,1,13268,7.217695,-9.806650,-4.589512,0.000000
+0,1,13273,7.217695,-9.571291,-4.746419,0.000000
+0,1,13278,7.217695,-9.571291,-4.746419,0.000000
+0,1,13283,7.649188,-9.885103,-4.903325,0.000000
+0,1,13288,7.649188,-9.885103,-4.903325,0.000000
+0,1,13293,8.159133,-9.806650,-5.021005,0.000000
+0,1,13298,8.159133,-9.806650,-5.021005,0.000000
+0,1,13303,8.590626,-9.414385,-5.138685,0.000000
+0,1,13308,8.590626,-9.414385,-5.138685,0.000000
+0,1,13313,8.276814,-8.080680,-5.217138,0.000000
+0,1,13318,8.276814,-8.080680,-5.217138,0.000000
+0,1,13323,8.002227,-7.335374,-5.687858,0.000000
+0,1,13328,8.002227,-7.335374,-5.687858,0.000000
+0,1,13333,8.002227,-7.492281,-5.805537,0.000000
+0,1,13338,8.002227,-7.492281,-5.805537,0.000000
+0,1,13343,7.531507,-7.531507,-5.962444,0.000000
+0,1,13348,7.531507,-7.531507,-5.962444,0.000000
+0,1,13353,6.943109,-7.374601,-6.354709,0.000000
+0,1,13358,6.943109,-7.374601,-6.354709,0.000000
+0,1,13363,6.237030,-7.374601,-4.314926,0.000000
+0,1,13368,6.237030,-7.374601,-4.314926,0.000000
+0,1,13373,6.237030,-7.374601,-5.099459,0.000000
+0,1,13378,5.687858,-7.688414,-5.177911,0.000000
+0,1,13383,5.687858,-7.688414,-5.177911,0.000000
+0,1,13388,5.530951,-8.276814,-4.354153,0.000000
+0,1,13393,5.530951,-8.276814,-4.354153,0.000000
+0,1,13398,5.609404,-8.747532,-4.158020,0.000000
+0,1,13403,5.609404,-8.747532,-4.158020,0.000000
+0,1,13408,5.295591,-8.433720,-4.040340,0.000000
+0,1,13413,5.295591,-8.433720,-4.040340,0.000000
+0,1,13418,5.138685,-8.276814,-3.648074,0.000000
+0,1,13423,5.138685,-8.276814,-3.648074,0.000000
+0,1,13428,5.060232,-8.237586,-3.373488,0.000000
+0,1,13433,5.060232,-8.237586,-3.373488,0.000000
+0,1,13438,5.256365,-8.355267,-3.373488,0.000000
+0,1,13443,5.256365,-8.355267,-3.373488,0.000000
+0,1,13448,5.570178,-8.551399,-3.412714,0.000000
+0,1,13453,5.570178,-8.551399,-3.412714,0.000000
+0,1,13458,5.570178,-8.551399,-3.648074,0.000000
+0,1,13463,5.570178,-8.551399,-3.648074,0.000000
+0,1,13468,5.805537,-8.512173,-3.687301,0.000000
+0,1,13473,5.805537,-8.512173,-3.687301,0.000000
+0,1,13478,5.766310,-8.512173,-3.765754,0.000000
+0,1,13483,5.766310,-8.512173,-3.765754,0.000000
+0,1,13488,5.687858,-8.355267,-3.765754,0.000000
+0,1,13493,5.687858,-8.355267,-3.765754,0.000000
+0,1,13498,5.374045,-8.316040,-3.726527,0.000000
+0,1,13503,5.374045,-8.316040,-3.726527,0.000000
+0,1,13508,5.099459,-8.119907,-3.765754,0.000000
+0,1,13513,5.099459,-8.119907,-3.765754,0.000000
+0,1,13518,4.942552,-8.119907,-3.765754,0.000000
+0,1,13523,4.942552,-8.119907,-3.765754,0.000000
+0,1,13528,4.824872,-8.041453,-3.687301,0.000000
+0,1,13533,4.824872,-8.041453,-3.687301,0.000000
+0,1,13538,4.746419,-8.002227,-3.608848,0.000000
+0,1,13543,4.746419,-8.002227,-3.608848,0.000000
+0,1,13548,4.667965,-7.923774,-3.451941,0.000000
+0,1,13553,4.667965,-7.923774,-3.451941,0.000000
+0,1,13558,4.746419,-7.884547,-3.373488,0.000000
+0,1,13563,4.746419,-7.884547,-3.373488,0.000000
+0,1,13568,4.981779,-7.727641,-3.098902,0.000000
+0,1,13573,4.981779,-7.727641,-3.098902,0.000000
+0,1,13578,4.903325,-7.570734,-2.863542,0.000000
+0,1,13583,4.903325,-7.570734,-2.863542,0.000000
+0,1,13588,5.060232,-7.492281,-2.785089,0.000000
+0,1,13593,5.060232,-7.492281,-2.785089,0.000000
+0,1,13598,5.021005,-7.374601,-2.353596,0.000000
+0,1,13603,5.021005,-7.374601,-2.353596,0.000000
+0,1,13608,5.177911,-7.335374,-2.353596,0.000000
+0,1,13613,5.177911,-7.335374,-2.353596,0.000000
+0,1,13618,5.138685,-7.492281,-2.196690,0.000000
+0,1,13623,5.138685,-7.492281,-2.196690,0.000000
+0,1,13628,5.060232,-7.100015,-2.039783,0.000000
+0,1,13633,5.060232,-7.100015,-2.039783,0.000000
+0,1,13638,5.021005,-7.178468,-1.725971,0.000000
+0,1,13643,5.021005,-7.178468,-1.725971,0.000000
+0,1,13648,5.060232,-6.943109,-1.765197,0.000000
+0,1,13653,5.060232,-6.943109,-1.765197,0.000000
+0,1,13658,4.942552,-6.629296,-1.765197,0.000000
+0,1,13663,4.942552,-6.629296,-1.765197,0.000000
+0,1,13668,4.942552,-6.511616,-1.569064,0.000000
+0,1,13673,4.942552,-6.511616,-1.569064,0.000000
+0,1,13678,4.824872,-6.433163,-1.608291,0.000000
+0,1,13683,4.824872,-6.433163,-1.608291,0.000000
+0,1,13688,4.746419,-6.354709,-1.804424,0.000000
+0,1,13693,4.746419,-6.354709,-1.804424,0.000000
+0,1,13698,4.824872,-6.472389,-1.843650,0.000000
+0,1,13703,4.824872,-6.472389,-1.843650,0.000000
+0,1,13708,4.903325,-6.511616,-2.000557,0.000000
+0,1,13713,4.903325,-6.511616,-2.000557,0.000000
+0,1,13718,4.942552,-6.668522,-2.196690,0.000000
+0,1,13723,4.942552,-6.668522,-2.196690,0.000000
+0,1,13728,5.060232,-6.668522,-2.235916,0.000000
+0,1,13733,5.060232,-6.668522,-2.235916,0.000000
+0,1,13738,5.177911,-6.746975,-2.353596,0.000000
+0,1,13743,5.177911,-6.746975,-2.353596,0.000000
+0,1,13748,5.177911,-6.786202,-2.196690,0.000000
+0,1,13753,5.177911,-6.786202,-2.196690,0.000000
+0,1,13758,5.256365,-6.903882,-2.392823,0.000000
+0,1,13763,5.256365,-6.903882,-2.392823,0.000000
+0,1,13768,5.217138,-6.943109,-2.510503,0.000000
+0,1,13773,5.217138,-6.943109,-2.510503,0.000000
+0,1,13778,5.256365,-6.982335,-2.588956,0.000000
+0,1,13783,5.256365,-6.982335,-2.588956,0.000000
+0,1,13788,5.177911,-7.021562,-2.785089,0.000000
+0,1,13793,5.177911,-7.021562,-2.785089,0.000000
+0,1,13798,5.256365,-7.256921,-2.824315,0.000000
+0,1,13803,5.256365,-7.256921,-2.824315,0.000000
+0,1,13808,5.256365,-7.335374,-2.941995,0.000000
+0,1,13813,5.256365,-7.335374,-2.941995,0.000000
+0,1,13818,5.256365,-7.492281,-3.138128,0.000000
+0,1,13823,5.256365,-7.492281,-3.138128,0.000000
+0,1,13828,5.491724,-7.609961,-3.216581,0.000000
+0,1,13833,5.491724,-7.609961,-3.216581,0.000000
+0,1,13838,5.491724,-7.609961,-3.216581,0.000000
+0,1,13843,5.570178,-7.649188,-3.216581,0.000000
+0,1,13848,5.570178,-7.649188,-3.216581,0.000000
+0,1,13853,5.648631,-7.766868,-3.255808,0.000000
+0,1,13858,5.648631,-7.766868,-3.255808,0.000000
+0,1,13863,5.687858,-7.806094,-3.373488,0.000000
+0,1,13868,5.687858,-7.806094,-3.373488,0.000000
+0,1,13873,5.609404,-7.727641,-3.491168,0.000000
+0,1,13878,5.609404,-7.727641,-3.491168,0.000000
+0,1,13883,5.609404,-7.727641,-3.569621,0.000000
+0,1,13888,5.609404,-7.727641,-3.569621,0.000000
+0,1,13893,5.570178,-7.806094,-3.648074,0.000000
+0,1,13898,5.570178,-7.806094,-3.648074,0.000000
+0,1,13903,5.570178,-8.237586,-3.883434,0.000000
+0,1,13908,5.570178,-8.237586,-3.883434,0.000000
+0,1,13913,5.727084,-9.257479,-3.765754,0.000000
+0,1,13918,5.727084,-9.257479,-3.765754,0.000000
+0,1,13923,5.883990,-10.238143,-4.001113,0.000000
+0,1,13928,5.883990,-10.238143,-4.001113,0.000000
+0,1,13933,6.001670,-11.061902,-4.158020,0.000000
+0,1,13938,6.001670,-11.061902,-4.158020,0.000000
+0,1,13943,6.237030,-11.611073,-4.275700,0.000000
+0,1,13948,6.237030,-11.611073,-4.275700,0.000000
+0,1,13953,6.472389,-11.689528,-4.589512,0.000000
+0,1,13958,6.472389,-11.689528,-4.589512,0.000000
+0,1,13963,6.354709,-11.375715,-4.864099,0.000000
+0,1,13968,6.354709,-11.375715,-4.864099,0.000000
+0,1,13973,6.237030,-10.708862,-5.177911,0.000000
+0,1,13978,6.237030,-10.708862,-5.177911,0.000000
+0,1,13983,6.393936,-10.238143,-5.530951,0.000000
+0,1,13988,6.393936,-10.238143,-5.530951,0.000000
+0,1,13993,6.237030,-9.767424,-6.315483,0.000000
+0,1,13998,6.237030,-9.767424,-6.315483,0.000000
+0,1,14003,6.629296,-9.688971,-6.158576,0.000000
+0,1,14008,6.629296,-9.688971,-6.158576,0.000000
+0,1,14013,6.158576,-8.708306,-6.943109,0.000000
+0,1,14018,6.158576,-8.708306,-6.943109,0.000000
+0,1,14023,6.080123,-8.119907,-7.021562,0.000000
+0,1,14028,6.080123,-8.119907,-7.021562,0.000000
+0,1,14033,6.119350,-7.884547,-7.178468,0.000000
+0,1,14038,6.119350,-7.884547,-7.178468,0.000000
+0,1,14043,5.805537,-8.080680,-7.060789,0.000000
+0,1,14048,5.805537,-8.080680,-7.060789,0.000000
+0,1,14053,6.001670,-8.669080,-6.668522,0.000000
+0,1,14058,6.001670,-8.669080,-6.668522,0.000000
+0,1,14063,5.844764,-9.139798,-6.119350,0.000000
+0,1,14068,5.844764,-9.139798,-6.119350,0.000000
+0,1,14073,5.727084,-9.100572,-5.805537,0.000000
+0,1,14078,5.727084,-9.100572,-5.805537,0.000000
+0,1,14083,5.609404,-8.904439,-5.374045,0.000000
+0,1,14088,5.609404,-8.904439,-5.374045,0.000000
+0,1,14093,5.687858,-8.512173,-5.177911,0.000000
+0,1,14098,5.687858,-8.512173,-5.177911,0.000000
+0,1,14103,5.962444,-8.355267,-5.060232,0.000000
+0,1,14108,5.962444,-8.355267,-5.060232,0.000000
+0,1,14113,6.158576,-8.159133,-5.060232,0.000000
+0,1,14118,6.158576,-8.159133,-5.060232,0.000000
+0,1,14123,6.158576,-7.845320,-4.981779,0.000000
+0,1,14128,6.158576,-7.845320,-4.981779,0.000000
+0,1,14133,6.001670,-7.453054,-4.785645,0.000000
+0,1,14138,6.001670,-7.453054,-4.785645,0.000000
+0,1,14143,5.648631,-7.217695,-4.667965,0.000000
+0,1,14148,5.648631,-7.217695,-4.667965,0.000000
+0,1,14153,5.452498,-7.217695,-4.511059,0.000000
+0,1,14158,5.452498,-7.217695,-4.511059,0.000000
+0,1,14163,5.060232,-7.296148,-4.393379,0.000000
+0,1,14168,5.060232,-7.296148,-4.393379,0.000000
+0,1,14173,4.785645,-7.374601,-4.236473,0.000000
+0,1,14178,4.785645,-7.374601,-4.236473,0.000000
+0,1,14183,4.354153,-7.139242,-4.001113,0.000000
+0,1,14188,4.354153,-7.139242,-4.001113,0.000000
+0,1,14193,3.922660,-7.060789,-3.648074,0.000000
+0,1,14198,3.922660,-7.060789,-3.648074,0.000000
+0,1,14203,3.648074,-7.060789,-3.373488,0.000000
+0,1,14208,3.648074,-7.060789,-3.373488,0.000000
+0,1,14213,3.451941,-7.100015,-3.255808,0.000000
+0,1,14218,3.451941,-7.100015,-3.255808,0.000000
+0,1,14223,3.334261,-7.139242,-3.059675,0.000000
+0,1,14228,3.334261,-7.139242,-3.059675,0.000000
+0,1,14233,3.295035,-7.021562,-2.824315,0.000000
+0,1,14238,3.295035,-7.021562,-2.824315,0.000000
+0,1,14243,3.138128,-6.982335,-2.706636,0.000000
+0,1,14248,3.138128,-6.982335,-2.706636,0.000000
+0,1,14253,3.098902,-6.943109,-2.432049,0.000000
+0,1,14258,3.098902,-6.943109,-2.432049,0.000000
+0,1,14263,3.138128,-6.943109,-2.353596,0.000000
+0,1,14268,3.138128,-6.943109,-2.353596,0.000000
+0,1,14273,3.216581,-6.982335,-2.392823,0.000000
+0,1,14278,3.216581,-6.982335,-2.392823,0.000000
+0,1,14283,3.334261,-7.060789,-2.314370,0.000000
+0,1,14288,3.334261,-7.060789,-2.314370,0.000000
+0,1,14293,3.334261,-7.060789,-2.314370,0.000000
+0,1,14298,3.334261,-7.021562,-2.353596,0.000000
+0,1,14303,3.334261,-7.021562,-2.353596,0.000000
+0,1,14308,3.451941,-7.021562,-2.353596,0.000000
+0,1,14313,3.451941,-7.021562,-2.353596,0.000000
+0,1,14318,3.726527,-7.178468,-2.588956,0.000000
+0,1,14323,3.726527,-7.178468,-2.588956,0.000000
+0,1,14328,4.040340,-7.178468,-2.706636,0.000000
+0,1,14333,4.040340,-7.178468,-2.706636,0.000000
+0,1,14338,4.275700,-7.100015,-2.745862,0.000000
+0,1,14343,4.275700,-7.100015,-2.745862,0.000000
+0,1,14348,4.628739,-7.100015,-2.941995,0.000000
+0,1,14353,4.628739,-7.100015,-2.941995,0.000000
+0,1,14358,4.981779,-6.943109,-2.941995,0.000000
+0,1,14363,4.981779,-6.943109,-2.941995,0.000000
+0,1,14368,5.099459,-6.943109,-2.981222,0.000000
+0,1,14373,5.099459,-6.943109,-2.981222,0.000000
+0,1,14378,5.256365,-7.021562,-2.902768,0.000000
+0,1,14383,5.256365,-7.021562,-2.902768,0.000000
+0,1,14388,5.413271,-6.982335,-3.098902,0.000000
+0,1,14393,5.413271,-6.982335,-3.098902,0.000000
+0,1,14398,5.570178,-6.943109,-3.177355,0.000000
+0,1,14403,5.570178,-6.943109,-3.177355,0.000000
+0,1,14408,5.687858,-6.864655,-3.255808,0.000000
+0,1,14413,5.687858,-6.864655,-3.255808,0.000000
+0,1,14418,5.883990,-6.825429,-3.451941,0.000000
+0,1,14423,5.883990,-6.825429,-3.451941,0.000000
+0,1,14428,6.001670,-6.825429,-3.608848,0.000000
+0,1,14433,6.001670,-6.825429,-3.608848,0.000000
+0,1,14438,6.197803,-6.668522,-3.608848,0.000000
+0,1,14443,6.197803,-6.668522,-3.608848,0.000000
+0,1,14448,6.393936,-6.707749,-3.844207,0.000000
+0,1,14453,6.393936,-6.707749,-3.844207,0.000000
+0,1,14458,6.550843,-6.550843,-3.883434,0.000000
+0,1,14463,6.550843,-6.550843,-3.883434,0.000000
+0,1,14468,6.550843,-6.393936,-4.707192,0.000000
+0,1,14473,6.550843,-6.393936,-4.707192,0.000000
+0,1,14478,6.864655,-6.315483,-4.236473,0.000000
+0,1,14483,6.864655,-6.315483,-4.236473,0.000000
+0,1,14488,7.256921,-6.119350,-4.354153,0.000000
+0,1,14493,7.256921,-6.119350,-4.354153,0.000000
+0,1,14498,7.413828,-6.472389,-4.589512,0.000000
+0,1,14503,7.413828,-6.472389,-4.589512,0.000000
+0,1,14508,7.374601,-6.119350,-4.471833,0.000000
+0,1,14513,7.374601,-6.119350,-4.471833,0.000000
+0,1,14518,7.570734,-6.197803,-4.785645,0.000000
+0,1,14523,7.570734,-6.197803,-4.785645,0.000000
+0,1,14528,7.845320,-6.276257,-5.021005,0.000000
+0,1,14533,7.845320,-6.276257,-5.021005,0.000000
+0,1,14538,8.002227,-6.001670,-4.942552,0.000000
+0,1,14543,8.002227,-6.001670,-4.942552,0.000000
+0,1,14548,7.963000,-5.923217,-5.217138,0.000000
+0,1,14553,7.963000,-5.923217,-5.217138,0.000000
+0,1,14558,8.119907,-6.001670,-5.491724,0.000000
+0,1,14563,8.119907,-6.001670,-5.491724,0.000000
+0,1,14568,8.237586,-6.668522,-5.452498,0.000000
+0,1,14573,8.237586,-6.668522,-5.452498,0.000000
+0,1,14578,8.786758,-7.374601,-5.530951,0.000000
+0,1,14583,8.786758,-7.374601,-5.530951,0.000000
+0,1,14588,9.061345,-7.766868,-5.883990,0.000000
+0,1,14593,9.061345,-7.766868,-5.883990,0.000000
+0,1,14598,9.492838,-8.629852,-5.962444,0.000000
+0,1,14603,9.492838,-8.629852,-5.962444,0.000000
+0,1,14608,9.767424,-9.022119,-6.080123,0.000000
+0,1,14613,9.767424,-9.022119,-6.080123,0.000000
+0,1,14618,9.924331,-9.375158,-6.276257,0.000000
+0,1,14623,9.924331,-9.375158,-6.276257,0.000000
+0,1,14628,10.120463,-9.532064,-6.746975,0.000000
+0,1,14633,10.120463,-9.532064,-6.746975,0.000000
+0,1,14638,10.512730,-9.375158,-6.629296,0.000000
+0,1,14643,10.512730,-9.375158,-6.629296,0.000000
+0,1,14648,10.198917,-8.433720,-7.100015,0.000000
+0,1,14653,10.198917,-8.433720,-7.100015,0.000000
+0,1,14658,9.885103,-7.923774,-7.021562,0.000000
+0,1,14663,9.885103,-7.923774,-7.021562,0.000000
+0,1,14668,9.179025,-7.570734,-6.433163,0.000000
+0,1,14673,9.179025,-7.570734,-6.433163,0.000000
+0,1,14678,8.394493,-7.178468,-6.825429,0.000000
+0,1,14683,8.394493,-7.178468,-6.825429,0.000000
+0,1,14688,7.570734,-6.707749,-6.393936,0.000000
+0,1,14693,7.570734,-6.707749,-6.393936,0.000000
+0,1,14698,6.903882,-6.237030,-5.766310,0.000000
+0,1,14703,6.903882,-6.237030,-5.766310,0.000000
+0,1,14708,6.511616,-6.550843,-5.256365,0.000000
+0,1,14713,6.511616,-6.550843,-5.256365,0.000000
+0,1,14718,6.315483,-7.178468,-4.864099,0.000000
+0,1,14723,6.315483,-7.178468,-4.864099,0.000000
+0,1,14728,5.923217,-7.923774,-4.471833,0.000000
+0,1,14733,5.923217,-7.923774,-4.471833,0.000000
+0,1,14738,5.766310,-8.198359,-3.961887,0.000000
+0,1,14743,5.766310,-8.198359,-3.961887,0.000000
+0,1,14748,5.766310,-8.198359,-3.451941,0.000000
+0,1,14753,5.609404,-8.316040,-3.451941,0.000000
+0,1,14758,5.609404,-8.316040,-3.451941,0.000000
+0,1,14763,5.687858,-8.512173,-3.295035,0.000000
+0,1,14768,5.687858,-8.512173,-3.295035,0.000000
+0,1,14773,6.001670,-8.786758,-3.216581,0.000000
+0,1,14778,6.001670,-8.786758,-3.216581,0.000000
+0,1,14783,6.472389,-9.375158,-3.177355,0.000000
+0,1,14788,6.472389,-9.375158,-3.177355,0.000000
+0,1,14793,7.021562,-9.728197,-3.177355,0.000000
+0,1,14798,7.021562,-9.728197,-3.177355,0.000000
+0,1,14803,7.178468,-9.767424,-3.412714,0.000000
+0,1,14808,7.178468,-9.767424,-3.412714,0.000000
+0,1,14813,6.864655,-9.453611,-3.177355,0.000000
+0,1,14818,6.864655,-9.453611,-3.177355,0.000000
+0,1,14823,6.315483,-9.022119,-3.373488,0.000000
+0,1,14828,6.315483,-9.022119,-3.373488,0.000000
+0,1,14833,5.923217,-8.982892,-3.451941,0.000000
+0,1,14838,5.923217,-8.982892,-3.451941,0.000000
+0,1,14843,5.687858,-9.139798,-3.844207,0.000000
+0,1,14848,5.687858,-9.139798,-3.844207,0.000000
+0,1,14853,5.413271,-9.257479,-3.961887,0.000000
+0,1,14858,5.413271,-9.257479,-3.961887,0.000000
+0,1,14863,4.981779,-9.335931,-3.922660,0.000000
+0,1,14868,4.981779,-9.335931,-3.922660,0.000000
+0,1,14873,4.746419,-9.218252,-3.648074,0.000000
+0,1,14878,4.746419,-9.218252,-3.648074,0.000000
+0,1,14883,4.550286,-9.139798,-3.530394,0.000000
+0,1,14888,4.550286,-9.139798,-3.530394,0.000000
+0,1,14893,4.432606,-9.139798,-3.177355,0.000000
+0,1,14898,4.432606,-9.139798,-3.177355,0.000000
+0,1,14903,4.511059,-9.139798,-2.902768,0.000000
+0,1,14908,4.511059,-9.139798,-2.902768,0.000000
+0,1,14913,4.393379,-8.825986,-2.588956,0.000000
+0,1,14918,4.393379,-8.825986,-2.588956,0.000000
+0,1,14923,4.432606,-8.472946,-2.392823,0.000000
+0,1,14928,4.432606,-8.472946,-2.392823,0.000000
+0,1,14933,4.511059,-8.159133,-2.314370,0.000000
+0,1,14938,4.511059,-8.159133,-2.314370,0.000000
+0,1,14943,4.628739,-7.884547,-2.157463,0.000000
+0,1,14948,4.628739,-7.884547,-2.157463,0.000000
+0,1,14953,4.628739,-7.688414,-2.000557,0.000000
+0,1,14958,4.628739,-7.688414,-2.000557,0.000000
+0,1,14963,4.550286,-7.413828,-1.804424,0.000000
+0,1,14968,4.550286,-7.413828,-1.804424,0.000000
+0,1,14973,4.432606,-7.100015,-1.725971,0.000000
+0,1,14978,4.432606,-7.100015,-1.725971,0.000000
+0,1,14983,4.432606,-6.825429,-1.725971,0.000000
+0,1,14988,4.432606,-6.825429,-1.725971,0.000000
+0,1,14993,4.471833,-6.550843,-1.647517,0.000000
+0,1,14998,4.471833,-6.550843,-1.647517,0.000000
+0,1,15003,4.471833,-6.276257,-1.765197,0.000000
+0,1,15008,4.471833,-6.276257,-1.765197,0.000000
+0,1,15013,4.550286,-6.197803,-1.882877,0.000000
+0,1,15018,4.550286,-6.197803,-1.882877,0.000000
+0,1,15023,4.864099,-6.119350,-2.000557,0.000000
+0,1,15028,4.864099,-6.119350,-2.000557,0.000000
+0,1,15033,5.021005,-6.080123,-2.196690,0.000000
+0,1,15038,5.021005,-6.080123,-2.196690,0.000000
+0,1,15043,5.021005,-5.962444,-2.235916,0.000000
+0,1,15048,5.021005,-5.962444,-2.235916,0.000000
+0,1,15053,5.021005,-5.962444,-2.353596,0.000000
+0,1,15058,5.021005,-5.962444,-2.353596,0.000000
+0,1,15063,5.177911,-6.001670,-2.471276,0.000000
+0,1,15068,5.177911,-6.001670,-2.471276,0.000000
+0,1,15073,5.217138,-6.001670,-2.510503,0.000000
+0,1,15078,5.217138,-6.001670,-2.510503,0.000000
+0,1,15083,5.217138,-6.040897,-2.510503,0.000000
+0,1,15088,5.217138,-6.040897,-2.510503,0.000000
+0,1,15093,5.177911,-6.080123,-2.785089,0.000000
+0,1,15098,5.177911,-6.080123,-2.785089,0.000000
+0,1,15103,5.138685,-6.354709,-2.863542,0.000000
+0,1,15108,5.138685,-6.354709,-2.863542,0.000000
+0,1,15113,5.177911,-6.472389,-2.941995,0.000000
+0,1,15118,5.177911,-6.472389,-2.941995,0.000000
+0,1,15123,5.295591,-6.472389,-3.216581,0.000000
+0,1,15128,5.295591,-6.472389,-3.216581,0.000000
+0,1,15133,5.413271,-6.629296,-3.255808,0.000000
+0,1,15138,5.413271,-6.629296,-3.255808,0.000000
+0,1,15143,5.648631,-6.629296,-3.530394,0.000000
+0,1,15148,5.648631,-6.629296,-3.530394,0.000000
+0,1,15153,5.883990,-6.746975,-3.687301,0.000000
+0,1,15158,5.883990,-6.746975,-3.687301,0.000000
+0,1,15163,6.080123,-6.707749,-3.961887,0.000000
+0,1,15168,6.080123,-6.707749,-3.961887,0.000000
+0,1,15173,6.119350,-6.590069,-4.079566,0.000000
+0,1,15178,6.119350,-6.590069,-4.079566,0.000000
+0,1,15183,6.080123,-6.629296,-4.158020,0.000000
+0,1,15188,6.080123,-6.629296,-4.158020,0.000000
+0,1,15193,5.923217,-6.590069,-4.197247,0.000000
+0,1,15198,5.923217,-6.590069,-4.197247,0.000000
+0,1,15203,5.923217,-6.746975,-4.197247,0.000000
+0,1,15208,5.883990,-6.629296,-4.197247,0.000000
+0,1,15213,5.883990,-6.629296,-4.197247,0.000000
+0,1,15218,5.609404,-6.707749,-4.197247,0.000000
+0,1,15223,5.609404,-6.707749,-4.197247,0.000000
+0,1,15228,5.452498,-6.472389,-4.158020,0.000000
+0,1,15233,5.452498,-6.472389,-4.158020,0.000000
+0,1,15238,5.413271,-6.550843,-3.961887,0.000000
+0,1,15243,5.413271,-6.550843,-3.961887,0.000000
+0,1,15248,5.413271,-6.629296,-3.922660,0.000000
+0,1,15253,5.413271,-6.629296,-3.922660,0.000000
+0,1,15258,5.570178,-6.746975,-3.687301,0.000000
+0,1,15263,5.570178,-6.746975,-3.687301,0.000000
+0,1,15268,5.844764,-7.217695,-3.648074,0.000000
+0,1,15273,5.844764,-7.217695,-3.648074,0.000000
+0,1,15278,6.276257,-7.649188,-3.648074,0.000000
+0,1,15283,6.276257,-7.649188,-3.648074,0.000000
+0,1,15288,6.590069,-7.923774,-3.648074,0.000000
+0,1,15293,6.590069,-7.923774,-3.648074,0.000000
+0,1,15298,6.786202,-7.963000,-3.687301,0.000000
+0,1,15303,6.786202,-7.963000,-3.687301,0.000000
+0,1,15308,7.060789,-8.433720,-3.883434,0.000000
+0,1,15313,7.060789,-8.433720,-3.883434,0.000000
+0,1,15318,7.296148,-8.629852,-3.569621,0.000000
+0,1,15323,7.296148,-8.629852,-3.569621,0.000000
+0,1,15328,7.609961,-9.022119,-4.275700,0.000000
+0,1,15333,7.609961,-9.022119,-4.275700,0.000000
+0,1,15338,7.845320,-9.296705,-4.471833,0.000000
+0,1,15343,7.845320,-9.296705,-4.471833,0.000000
+0,1,15348,7.923774,-9.139798,-4.746419,0.000000
+0,1,15353,7.923774,-9.139798,-4.746419,0.000000
+0,1,15358,7.806094,-8.904439,-5.099459,0.000000
+0,1,15363,7.806094,-8.904439,-5.099459,0.000000
+0,1,15368,7.806094,-8.708306,-5.177911,0.000000
+0,1,15373,7.806094,-8.708306,-5.177911,0.000000
+0,1,15378,7.649188,-8.590626,-5.530951,0.000000
+0,1,15383,7.649188,-8.590626,-5.530951,0.000000
+0,1,15388,7.413828,-8.394493,-5.805537,0.000000
+0,1,15393,7.413828,-8.394493,-5.805537,0.000000
+0,1,15398,7.100015,-8.237586,-5.805537,0.000000
+0,1,15403,7.100015,-8.237586,-5.805537,0.000000
+0,1,15408,7.100015,-8.119907,-5.923217,0.000000
+0,1,15413,7.100015,-8.119907,-5.923217,0.000000
+0,1,15418,6.825429,-7.923774,-6.080123,0.000000
+0,1,15423,6.825429,-7.923774,-6.080123,0.000000
+0,1,15428,6.511616,-7.884547,-5.883990,0.000000
+0,1,15433,6.511616,-7.884547,-5.883990,0.000000
+0,1,15438,6.237030,-7.609961,-5.844764,0.000000
+0,1,15443,6.237030,-7.609961,-5.844764,0.000000
+0,1,15448,6.119350,-7.609961,-5.491724,0.000000
+0,1,15453,6.119350,-7.609961,-5.491724,0.000000
+0,1,15458,6.119350,-7.531507,-5.334818,0.000000
+0,1,15463,6.119350,-7.531507,-5.334818,0.000000
+0,1,15468,6.040897,-7.256921,-5.217138,0.000000
+0,1,15473,6.040897,-7.256921,-5.217138,0.000000
+0,1,15478,6.197803,-7.060789,-4.864099,0.000000
+0,1,15483,6.197803,-7.060789,-4.864099,0.000000
+0,1,15488,6.197803,-7.178468,-4.785645,0.000000
+0,1,15493,6.197803,-7.178468,-4.785645,0.000000
+0,1,15498,6.119350,-7.178468,-4.432606,0.000000
+0,1,15503,6.119350,-7.178468,-4.432606,0.000000
+0,1,15508,6.040897,-7.178468,-4.354153,0.000000
+0,1,15513,6.040897,-7.178468,-4.354153,0.000000
+0,1,15518,6.001670,-7.139242,-4.197247,0.000000
+0,1,15523,6.001670,-7.139242,-4.197247,0.000000
+0,1,15528,5.883990,-7.060789,-4.001113,0.000000
+0,1,15533,5.883990,-7.060789,-4.001113,0.000000
+0,1,15538,5.687858,-6.903882,-3.844207,0.000000
+0,1,15543,5.687858,-6.903882,-3.844207,0.000000
+0,1,15548,5.491724,-6.786202,-3.648074,0.000000
+0,1,15553,5.491724,-6.786202,-3.648074,0.000000
+0,1,15558,5.217138,-6.825429,-3.491168,0.000000
+0,1,15563,5.217138,-6.825429,-3.491168,0.000000
+0,1,15568,4.981779,-6.629296,-3.530394,0.000000
+0,1,15573,4.981779,-6.629296,-3.530394,0.000000
+0,1,15578,4.864099,-6.590069,-3.373488,0.000000
+0,1,15583,4.864099,-6.590069,-3.373488,0.000000
+0,1,15588,4.707192,-6.590069,-3.373488,0.000000
+0,1,15593,4.707192,-6.590069,-3.373488,0.000000
+0,1,15598,4.550286,-6.629296,-3.334261,0.000000
+0,1,15603,4.550286,-6.629296,-3.334261,0.000000
+0,1,15608,4.550286,-6.668522,-3.138128,0.000000
+0,1,15613,4.550286,-6.668522,-3.138128,0.000000
+0,1,15618,4.354153,-6.550843,-2.902768,0.000000
+0,1,15623,4.354153,-6.550843,-2.902768,0.000000
+0,1,15628,4.197247,-6.590069,-2.824315,0.000000
+0,1,15633,4.197247,-6.590069,-2.824315,0.000000
+0,1,15638,4.118793,-6.668522,-2.785089,0.000000
+0,1,15643,4.118793,-6.668522,-2.785089,0.000000
+0,1,15648,4.040340,-6.707749,-2.785089,0.000000
+0,1,15653,4.040340,-6.707749,-2.785089,0.000000
+0,1,15658,4.040340,-6.707749,-2.863542,0.000000
+0,1,15663,4.236473,-6.707749,-2.863542,0.000000
+0,1,15668,4.236473,-6.707749,-2.863542,0.000000
+0,1,15673,4.354153,-6.590069,-2.941995,0.000000
+0,1,15678,4.354153,-6.590069,-2.941995,0.000000
+0,1,15683,4.628739,-6.511616,-3.098902,0.000000
+0,1,15688,4.628739,-6.511616,-3.098902,0.000000
+0,1,15693,5.021005,-6.354709,-3.295035,0.000000
+0,1,15698,5.021005,-6.354709,-3.295035,0.000000
+0,1,15703,5.256365,-6.276257,-3.255808,0.000000
+0,1,15708,5.256365,-6.276257,-3.255808,0.000000
+0,1,15713,5.570178,-6.119350,-3.295035,0.000000
+0,1,15718,5.570178,-6.119350,-3.295035,0.000000
+0,1,15723,5.727084,-6.158576,-3.373488,0.000000
+0,1,15728,5.727084,-6.158576,-3.373488,0.000000
+0,1,15733,5.923217,-6.119350,-3.334261,0.000000
+0,1,15738,5.923217,-6.119350,-3.334261,0.000000
+0,1,15743,6.040897,-6.158576,-3.491168,0.000000
+0,1,15748,6.040897,-6.158576,-3.491168,0.000000
+0,1,15753,6.276257,-6.158576,-3.608848,0.000000
+0,1,15758,6.276257,-6.158576,-3.608848,0.000000
+0,1,15763,6.354709,-6.158576,-3.687301,0.000000
+0,1,15768,6.354709,-6.158576,-3.687301,0.000000
+0,1,15773,6.276257,-6.276257,-3.844207,0.000000
+0,1,15778,6.276257,-6.276257,-3.844207,0.000000
+0,1,15783,6.354709,-6.354709,-3.922660,0.000000
+0,1,15788,6.354709,-6.354709,-3.922660,0.000000
+0,1,15793,6.354709,-6.433163,-4.040340,0.000000
+0,1,15798,6.354709,-6.433163,-4.040340,0.000000
+0,1,15803,6.354709,-6.550843,-4.275700,0.000000
+0,1,15808,6.354709,-6.550843,-4.275700,0.000000
+0,1,15813,6.354709,-6.550843,-4.432606,0.000000
+0,1,15818,6.354709,-6.550843,-4.432606,0.000000
+0,1,15823,6.707749,-6.746975,-4.471833,0.000000
+0,1,15828,6.707749,-6.746975,-4.471833,0.000000
+0,1,15833,6.825429,-6.707749,-4.550286,0.000000
+0,1,15838,6.825429,-6.707749,-4.550286,0.000000
+0,1,15843,7.021562,-6.864655,-4.393379,0.000000
+0,1,15848,7.021562,-6.864655,-4.393379,0.000000
+0,1,15853,7.139242,-6.982335,-4.667965,0.000000
+0,1,15858,7.139242,-6.982335,-4.667965,0.000000
+0,1,15863,7.531507,-7.100015,-4.707192,0.000000
+0,1,15868,7.531507,-7.100015,-4.707192,0.000000
+0,1,15873,8.041453,-6.864655,-4.903325,0.000000
+0,1,15878,8.041453,-6.864655,-4.903325,0.000000
+0,1,15883,8.276814,-6.746975,-4.981779,0.000000
+0,1,15888,8.276814,-6.746975,-4.981779,0.000000
+0,1,15893,8.629852,-6.472389,-5.138685,0.000000
+0,1,15898,8.629852,-6.472389,-5.138685,0.000000
+0,1,15903,8.865212,-6.472389,-5.256365,0.000000
+0,1,15908,8.865212,-6.472389,-5.256365,0.000000
+0,1,15913,8.786758,-6.237030,-5.413271,0.000000
+0,1,15918,8.786758,-6.237030,-5.413271,0.000000
+0,1,15923,8.786758,-6.237030,-5.452498,0.000000
+0,1,15928,8.786758,-6.237030,-5.452498,0.000000
+0,1,15933,8.669080,-6.354709,-5.295591,0.000000
+0,1,15938,8.669080,-6.354709,-5.295591,0.000000
+0,1,15943,8.629852,-6.982335,-5.217138,0.000000
+0,1,15948,8.629852,-6.982335,-5.217138,0.000000
+0,1,15953,8.708306,-7.688414,-5.060232,0.000000
+0,1,15958,8.708306,-7.688414,-5.060232,0.000000
+0,1,15963,8.708306,-8.119907,-5.256365,0.000000
+0,1,15968,8.708306,-8.119907,-5.256365,0.000000
+0,1,15973,8.825986,-8.472946,-5.295591,0.000000
+0,1,15978,8.825986,-8.472946,-5.295591,0.000000
+0,1,15983,8.982892,-8.237586,-5.413271,0.000000
+0,1,15988,8.982892,-8.237586,-5.413271,0.000000
+0,1,15993,8.943666,-7.884547,-5.727084,0.000000
+0,1,15998,8.943666,-7.884547,-5.727084,0.000000
+0,1,16003,8.982892,-7.335374,-5.844764,0.000000
+0,1,16008,8.982892,-7.335374,-5.844764,0.000000
+0,1,16013,8.747532,-7.256921,-5.883990,0.000000
+0,1,16018,8.747532,-7.256921,-5.883990,0.000000
+0,1,16023,8.316040,-7.531507,-5.883990,0.000000
+0,1,16028,8.316040,-7.531507,-5.883990,0.000000
+0,1,16033,7.845320,-7.727641,-6.040897,0.000000
+0,1,16038,7.845320,-7.727641,-6.040897,0.000000
+0,1,16043,7.374601,-7.727641,-6.001670,0.000000
+0,1,16048,7.374601,-7.727641,-6.001670,0.000000
+0,1,16053,6.786202,-7.884547,-5.805537,0.000000
+0,1,16058,6.786202,-7.884547,-5.805537,0.000000
+0,1,16063,6.393936,-7.806094,-5.452498,0.000000
+0,1,16068,6.393936,-7.806094,-5.452498,0.000000
+0,1,16073,5.805537,-7.609961,-5.099459,0.000000
+0,1,16078,5.805537,-7.609961,-5.099459,0.000000
+0,1,16083,5.491724,-7.374601,-4.628739,0.000000
+0,1,16178,5.374045,-7.923774,-2.902768,0.000000
+0,1,16183,5.374045,-7.923774,-2.902768,0.000000
+0,1,16188,5.334818,-8.041453,-2.824315,0.000000
+0,1,16193,5.334818,-8.041453,-2.824315,0.000000
+0,1,16198,5.295591,-8.119907,-2.981222,0.000000
+0,1,16203,5.295591,-8.119907,-2.981222,0.000000
+0,1,16208,5.256365,-8.159133,-2.941995,0.000000
+0,1,16213,5.256365,-8.159133,-2.941995,0.000000
+0,1,16218,5.217138,-8.041453,-3.177355,0.000000
+0,1,16223,5.217138,-8.041453,-3.177355,0.000000
+0,1,16228,5.138685,-7.845320,-3.491168,0.000000
+0,1,16233,5.138685,-7.845320,-3.491168,0.000000
+0,1,16238,5.021005,-7.609961,-3.648074,0.000000
+0,1,16243,5.021005,-7.609961,-3.648074,0.000000
+0,1,16248,5.099459,-7.570734,-3.608848,0.000000
+0,1,16253,5.099459,-7.570734,-3.608848,0.000000
+0,1,16258,5.060232,-7.531507,-3.844207,0.000000
+0,1,16263,5.060232,-7.531507,-3.844207,0.000000
+0,1,16268,5.177911,-7.453054,-3.844207,0.000000
+0,1,16273,5.177911,-7.453054,-3.844207,0.000000
+0,1,16278,5.295591,-7.453054,-3.883434,0.000000
+0,1,16283,5.295591,-7.453054,-3.883434,0.000000
+0,1,16288,5.374045,-7.374601,-3.883434,0.000000
+0,1,16293,5.374045,-7.374601,-3.883434,0.000000
+0,1,16298,5.452498,-7.413828,-3.844207,0.000000
+0,1,16303,5.452498,-7.413828,-3.844207,0.000000
+0,1,16308,5.491724,-7.335374,-3.726527,0.000000
+0,1,16313,5.491724,-7.335374,-3.726527,0.000000
+0,1,16318,5.491724,-7.100015,-3.804980,0.000000
+0,1,16323,5.491724,-7.100015,-3.804980,0.000000
+0,1,16328,5.962444,-7.256921,-3.687301,0.000000
+0,1,16333,5.962444,-7.256921,-3.687301,0.000000
+0,1,16338,6.080123,-7.021562,-3.726527,0.000000
+0,1,16343,6.080123,-7.021562,-3.726527,0.000000
+0,1,16348,6.276257,-6.864655,-3.491168,0.000000
+0,1,16353,6.276257,-6.864655,-3.491168,0.000000
+0,1,16358,6.433163,-6.707749,-3.687301,0.000000
+0,1,16363,6.433163,-6.707749,-3.687301,0.000000
+0,1,16368,6.237030,-6.746975,-3.412714,0.000000
+0,1,16373,6.237030,-6.746975,-3.412714,0.000000
+0,1,16378,6.158576,-6.393936,-3.491168,0.000000
+0,1,16383,6.158576,-6.393936,-3.491168,0.000000
+0,1,16388,6.040897,-6.315483,-3.334261,0.000000
+0,1,16393,6.040897,-6.315483,-3.334261,0.000000
+0,1,16398,5.766310,-6.237030,-3.177355,0.000000
+0,1,16403,5.766310,-6.237030,-3.177355,0.000000
+0,1,16408,5.609404,-6.001670,-3.138128,0.000000
+0,1,16413,5.609404,-6.001670,-3.138128,0.000000
+0,1,16418,5.374045,-5.727084,-3.020448,0.000000
+0,1,16423,5.374045,-5.727084,-3.020448,0.000000
+0,1,16428,5.177911,-5.687858,-2.981222,0.000000
+0,1,16433,5.177911,-5.687858,-2.981222,0.000000
+0,1,16438,5.099459,-5.570178,-3.059675,0.000000
+0,1,16443,5.099459,-5.570178,-3.059675,0.000000
+0,1,16448,5.060232,-5.609404,-2.902768,0.000000
+0,1,16453,5.060232,-5.609404,-2.902768,0.000000
+0,1,16458,5.060232,-5.570178,-2.981222,0.000000
+0,1,16463,5.060232,-5.570178,-2.981222,0.000000
+0,1,16468,5.138685,-5.570178,-2.981222,0.000000
+0,1,16473,5.138685,-5.570178,-2.981222,0.000000
+0,1,16478,5.099459,-5.648631,-2.981222,0.000000
+0,1,16483,5.099459,-5.648631,-2.981222,0.000000
+0,1,16488,5.099459,-5.687858,-2.981222,0.000000
+0,1,16493,5.099459,-5.687858,-2.981222,0.000000
+0,1,16498,5.217138,-5.766310,-2.981222,0.000000
+0,1,16503,5.217138,-5.766310,-2.981222,0.000000
+0,1,16508,5.256365,-5.962444,-3.098902,0.000000
+0,1,16513,5.256365,-5.962444,-3.098902,0.000000
+0,1,16518,5.530951,-6.119350,-3.255808,0.000000
+0,1,16523,5.530951,-6.119350,-3.255808,0.000000
+0,1,16528,5.883990,-6.276257,-3.687301,0.000000
+0,1,16533,5.883990,-6.276257,-3.687301,0.000000
+0,1,16538,6.080123,-6.433163,-3.844207,0.000000
+0,1,16543,6.080123,-6.433163,-3.844207,0.000000
+0,1,16548,6.119350,-6.590069,-4.079566,0.000000
+0,1,16553,6.119350,-6.590069,-4.079566,0.000000
+0,1,16558,6.119350,-6.903882,-4.197247,0.000000
+0,1,16563,6.237030,-6.864655,-4.197247,0.000000
+0,1,16568,6.237030,-6.864655,-4.197247,0.000000
+0,1,16573,6.158576,-6.825429,-4.158020,0.000000
+0,1,16578,6.158576,-6.825429,-4.158020,0.000000
+0,1,16583,6.040897,-6.864655,-4.236473,0.000000
+0,1,16588,6.040897,-6.864655,-4.236473,0.000000
+0,1,16593,6.080123,-6.943109,-4.236473,0.000000
+0,1,16598,6.080123,-6.943109,-4.236473,0.000000
+0,1,16603,6.158576,-6.943109,-4.197247,0.000000
+0,1,16608,6.158576,-6.943109,-4.197247,0.000000
+0,1,16613,6.197803,-6.982335,-4.314926,0.000000
+0,1,16618,6.197803,-6.982335,-4.314926,0.000000
+0,1,16623,6.315483,-7.139242,-4.354153,0.000000
+0,1,16628,6.315483,-7.139242,-4.354153,0.000000
+0,1,16633,6.433163,-7.923774,-4.432606,0.000000
+0,1,16638,6.433163,-7.923774,-4.432606,0.000000
+0,1,16643,6.550843,-8.786758,-4.432606,0.000000
+0,1,16648,6.550843,-8.786758,-4.432606,0.000000
+0,1,16653,6.629296,-9.100572,-4.628739,0.000000
+0,1,16658,6.629296,-9.100572,-4.628739,0.000000
+0,1,16663,6.629296,-8.982892,-4.707192,0.000000
+0,1,16668,6.629296,-8.982892,-4.707192,0.000000
+0,1,16673,6.511616,-8.669080,-5.060232,0.000000
+0,1,16678,6.511616,-8.669080,-5.060232,0.000000
+0,1,16683,6.315483,-8.747532,-5.256365,0.000000
+0,1,16688,6.315483,-8.747532,-5.256365,0.000000
+0,1,16693,6.197803,-8.747532,-5.413271,0.000000
+0,1,16698,6.197803,-8.747532,-5.413271,0.000000
+0,1,16703,6.158576,-8.825986,-5.530951,0.000000
+0,1,16708,6.158576,-8.825986,-5.530951,0.000000
+0,1,16713,5.962444,-8.629852,-5.805537,0.000000
+0,1,16718,5.962444,-8.629852,-5.805537,0.000000
+0,1,16723,5.883990,-8.276814,-5.452498,0.000000
+0,1,16728,5.883990,-8.276814,-5.452498,0.000000
+0,1,16733,5.570178,-7.884547,-5.766310,0.000000
+0,1,16738,5.570178,-7.884547,-5.766310,0.000000
+0,1,16743,5.413271,-7.609961,-5.452498,0.000000
+0,1,16748,5.413271,-7.609961,-5.452498,0.000000
+0,1,16753,5.334818,-7.021562,-4.864099,0.000000
+0,1,16758,5.334818,-7.021562,-4.864099,0.000000
+0,1,16763,5.021005,-6.354709,-4.707192,0.000000
+0,1,16768,5.021005,-6.354709,-4.707192,0.000000
+0,1,16773,4.903325,-6.472389,-4.275700,0.000000
+0,1,16778,4.903325,-6.472389,-4.275700,0.000000
+0,1,16783,4.981779,-6.746975,-4.197247,0.000000
+0,1,16788,4.981779,-6.746975,-4.197247,0.000000
+0,1,16793,5.021005,-7.492281,-4.158020,0.000000
+0,1,16798,5.021005,-7.492281,-4.158020,0.000000
+0,1,16803,5.060232,-7.649188,-4.275700,0.000000
+0,1,16808,5.060232,-7.649188,-4.275700,0.000000
+0,1,16813,5.138685,-7.806094,-4.393379,0.000000
+0,1,16818,5.138685,-7.806094,-4.393379,0.000000
+0,1,16823,5.413271,-7.845320,-4.824872,0.000000
+0,1,16828,5.413271,-7.845320,-4.824872,0.000000
+0,1,16833,5.766310,-7.806094,-4.903325,0.000000
+0,1,16838,5.766310,-7.806094,-4.903325,0.000000
+0,1,16843,6.119350,-7.766868,-5.099459,0.000000
+0,1,16848,6.119350,-7.766868,-5.099459,0.000000
+0,1,16853,6.393936,-7.570734,-4.942552,0.000000
+0,1,16858,6.393936,-7.570734,-4.942552,0.000000
+0,1,16863,6.315483,-7.374601,-4.942552,0.000000
+0,1,16868,6.315483,-7.374601,-4.942552,0.000000
+0,1,16873,6.315483,-7.256921,-4.707192,0.000000
+0,1,16878,6.315483,-7.256921,-4.707192,0.000000
+0,1,16883,6.197803,-7.100015,-4.589512,0.000000
+0,1,16888,6.197803,-7.100015,-4.589512,0.000000
+0,1,16893,6.080123,-6.864655,-4.393379,0.000000
+0,1,16898,6.080123,-6.864655,-4.393379,0.000000
+0,1,16903,5.766310,-6.825429,-4.432606,0.000000
+0,1,16908,5.766310,-6.825429,-4.432606,0.000000
+0,1,16913,5.805537,-6.746975,-4.314926,0.000000
+0,1,16918,5.805537,-6.746975,-4.314926,0.000000
+0,1,16923,6.001670,-6.629296,-4.354153,0.000000
+0,1,16928,6.001670,-6.629296,-4.354153,0.000000
+0,1,16933,6.001670,-6.550843,-4.550286,0.000000
+0,1,16938,6.001670,-6.550843,-4.550286,0.000000
+0,1,16943,6.276257,-6.511616,-4.746419,0.000000
+0,1,16948,6.276257,-6.511616,-4.746419,0.000000
+0,1,16953,6.237030,-6.393936,-4.942552,0.000000
+0,1,16958,6.237030,-6.393936,-4.942552,0.000000
+0,1,16963,6.237030,-6.354709,-4.746419,0.000000
+0,1,16968,6.237030,-6.354709,-4.746419,0.000000
+0,1,16973,6.590069,-6.746975,-5.177911,0.000000
+0,1,16978,6.590069,-6.746975,-5.177911,0.000000
+0,1,16983,5.805537,-5.923217,-4.589512,0.000000
+0,1,16988,5.805537,-5.923217,-4.589512,0.000000
+0,1,16993,5.530951,-5.766310,-4.550286,0.000000
+0,1,16998,5.530951,-5.766310,-4.550286,0.000000
+0,1,17003,5.530951,-5.844764,-4.236473,0.000000
+0,1,17008,5.530951,-5.844764,-4.236473,0.000000
+0,1,17013,5.530951,-5.844764,-4.236473,0.000000
+0,1,17018,5.256365,-5.844764,-4.354153,0.000000
+0,1,17023,5.256365,-5.844764,-4.354153,0.000000
+0,1,17028,5.413271,-6.315483,-4.511059,0.000000
+0,1,17033,5.413271,-6.315483,-4.511059,0.000000
+0,1,17038,5.570178,-6.590069,-4.667965,0.000000
+0,1,17043,5.570178,-6.590069,-4.667965,0.000000
+0,1,17048,5.727084,-6.629296,-4.942552,0.000000
+0,1,17053,5.727084,-6.629296,-4.942552,0.000000
+0,1,17058,6.001670,-6.472389,-5.217138,0.000000
+0,1,17063,6.001670,-6.472389,-5.217138,0.000000
+0,1,17068,5.844764,-6.237030,-5.491724,0.000000
+0,1,17073,5.844764,-6.237030,-5.491724,0.000000
+0,1,17078,5.805537,-6.237030,-5.374045,0.000000
+0,1,17083,5.805537,-6.237030,-5.374045,0.000000
+0,1,17088,5.766310,-6.354709,-5.060232,0.000000
+0,1,17093,5.766310,-6.354709,-5.060232,0.000000
+0,1,17098,5.491724,-6.001670,-5.021005,0.000000
+0,1,17103,5.491724,-6.001670,-5.021005,0.000000
+0,1,17108,5.491724,-5.883990,-5.099459,0.000000
+0,1,17113,5.491724,-5.883990,-5.099459,0.000000
+0,1,17118,5.727084,-5.844764,-4.981779,0.000000
+0,1,17123,5.727084,-5.844764,-4.981779,0.000000
+0,1,17128,6.001670,-5.883990,-4.824872,0.000000
+0,1,17133,6.001670,-5.883990,-4.824872,0.000000
+0,1,17138,6.354709,-5.805537,-4.628739,0.000000
+0,1,17143,6.354709,-5.805537,-4.628739,0.000000
+0,1,17148,6.354709,-5.766310,-4.628739,0.000000
+0,1,17153,6.354709,-5.766310,-4.628739,0.000000
+0,1,17158,6.433163,-5.805537,-4.550286,0.000000
+0,1,17163,6.433163,-5.805537,-4.550286,0.000000
+0,1,17168,6.590069,-5.530951,-4.589512,0.000000
+0,1,17173,6.590069,-5.530951,-4.589512,0.000000
+0,1,17178,6.707749,-5.530951,-4.550286,0.000000
+0,1,17183,6.707749,-5.530951,-4.550286,0.000000
+0,1,17188,7.021562,-5.648631,-4.511059,0.000000
+0,1,17193,7.021562,-5.648631,-4.511059,0.000000
+0,1,17198,7.296148,-5.727084,-4.589512,0.000000
+0,1,17203,7.296148,-5.727084,-4.589512,0.000000
+0,1,17208,7.531507,-5.766310,-4.824872,0.000000
+0,1,17213,7.531507,-5.766310,-4.824872,0.000000
+0,1,17218,7.531507,-5.805537,-4.942552,0.000000
+0,1,17223,7.531507,-5.805537,-4.942552,0.000000
+0,1,17228,7.531507,-6.001670,-5.177911,0.000000
+0,1,17233,7.531507,-6.001670,-5.177911,0.000000
+0,1,17238,7.570734,-6.119350,-5.177911,0.000000
+0,1,17243,7.570734,-6.119350,-5.177911,0.000000
+0,1,17248,7.531507,-6.237030,-5.217138,0.000000
+0,1,17253,7.531507,-6.237030,-5.217138,0.000000
+0,1,17258,7.374601,-6.354709,-5.177911,0.000000
+0,1,17263,7.374601,-6.354709,-5.177911,0.000000
+0,1,17268,7.296148,-6.472389,-5.177911,0.000000
+0,1,17273,7.296148,-6.472389,-5.177911,0.000000
+0,1,17278,7.256921,-6.511616,-5.217138,0.000000
+0,1,17283,7.256921,-6.511616,-5.217138,0.000000
+0,1,17288,7.335374,-6.472389,-5.099459,0.000000
+0,1,17293,7.335374,-6.472389,-5.099459,0.000000
+0,1,17298,7.649188,-6.629296,-4.981779,0.000000
+0,1,17303,7.649188,-6.629296,-4.981779,0.000000
+0,1,17308,7.845320,-6.511616,-5.099459,0.000000
+0,1,17313,7.845320,-6.511616,-5.099459,0.000000
+0,1,17318,7.963000,-6.433163,-4.981779,0.000000
+0,1,17323,7.963000,-6.433163,-4.981779,0.000000
+0,1,17328,8.080680,-6.315483,-4.981779,0.000000
+0,1,17333,8.080680,-6.315483,-4.981779,0.000000
+0,1,17338,8.237586,-6.433163,-4.903325,0.000000
+0,1,17343,8.237586,-6.433163,-4.903325,0.000000
+0,1,17348,8.355267,-6.629296,-4.903325,0.000000
+0,1,17353,8.355267,-6.629296,-4.903325,0.000000
+0,1,17358,8.472946,-7.100015,-4.746419,0.000000
+0,1,17363,8.472946,-7.100015,-4.746419,0.000000
+0,1,17368,8.629852,-7.963000,-4.864099,0.000000
+0,1,17373,8.629852,-7.963000,-4.864099,0.000000
+0,1,17378,8.786758,-8.590626,-5.021005,0.000000
+0,1,17383,8.786758,-8.590626,-5.021005,0.000000
+0,1,17388,8.669080,-8.512173,-5.295591,0.000000
+0,1,17393,8.669080,-8.512173,-5.295591,0.000000
+0,1,17398,8.041453,-8.119907,-5.138685,0.000000
+0,1,17403,8.041453,-8.119907,-5.138685,0.000000
+0,1,17408,8.119907,-8.237586,-5.374045,0.000000
+0,1,17413,8.119907,-8.237586,-5.374045,0.000000
+0,1,17418,7.963000,-8.747532,-5.805537,0.000000
+0,1,17423,7.963000,-8.747532,-5.805537,0.000000
+0,1,17428,7.766868,-8.590626,-6.001670,0.000000
+0,1,17433,7.766868,-8.590626,-6.001670,0.000000
+0,1,17438,7.413828,-8.316040,-6.158576,0.000000
+0,1,17443,7.413828,-8.316040,-6.158576,0.000000
+0,1,17448,6.903882,-7.806094,-6.276257,0.000000
+0,1,17453,6.903882,-7.806094,-6.276257,0.000000
+0,1,17458,6.433163,-7.531507,-6.315483,0.000000
+0,1,17463,6.550843,-7.531507,-6.315483,0.000000
+0,1,17468,6.550843,-7.531507,-6.315483,0.000000
+0,1,17473,6.197803,-7.296148,-6.237030,0.000000
+0,1,17478,6.197803,-7.296148,-6.237030,0.000000
+0,1,17483,5.452498,-6.864655,-5.727084,0.000000
+0,1,17488,5.452498,-6.864655,-5.727084,0.000000
+0,1,17493,4.785645,-6.393936,-5.374045,0.000000
+0,1,17498,4.785645,-6.393936,-5.374045,0.000000
+0,1,17503,4.432606,-6.158576,-4.785645,0.000000
+0,1,17508,4.432606,-6.158576,-4.785645,0.000000
+0,1,17513,4.197247,-6.472389,-4.275700,0.000000
+0,1,17518,4.197247,-6.472389,-4.275700,0.000000
+0,1,17523,4.079566,-6.943109,-3.922660,0.000000
+0,1,17528,4.079566,-6.943109,-3.922660,0.000000
+0,1,17533,3.922660,-7.139242,-3.569621,0.000000
+0,1,17538,3.922660,-7.139242,-3.569621,0.000000
+0,1,17543,3.687301,-7.413828,-3.138128,0.000000
+0,1,17548,3.687301,-7.413828,-3.138128,0.000000
+0,1,17553,3.451941,-7.531507,-2.981222,0.000000
+0,1,17558,3.451941,-7.531507,-2.981222,0.000000
+0,1,17563,3.451941,-7.845320,-2.863542,0.000000
+0,1,17568,3.451941,-7.845320,-2.863542,0.000000
+0,1,17573,3.687301,-7.963000,-2.941995,0.000000
+0,1,17578,3.687301,-7.963000,-2.941995,0.000000
+0,1,17583,3.883434,-8.002227,-3.177355,0.000000
+0,1,17588,3.883434,-8.002227,-3.177355,0.000000
+0,1,17593,4.158020,-7.688414,-3.530394,0.000000
+0,1,17598,4.158020,-7.688414,-3.530394,0.000000
+0,1,17603,4.471833,-7.374601,-3.765754,0.000000
+0,1,17608,4.471833,-7.374601,-3.765754,0.000000
+0,1,17613,4.707192,-6.864655,-3.922660,0.000000
+0,1,17618,4.707192,-6.864655,-3.922660,0.000000
+0,1,17623,4.942552,-6.472389,-4.158020,0.000000
+0,1,17628,4.942552,-6.472389,-4.158020,0.000000
+0,1,17633,5.060232,-6.158576,-4.393379,0.000000
+0,1,17638,5.060232,-6.158576,-4.393379,0.000000
+0,1,17643,4.981779,-5.883990,-4.471833,0.000000
+0,1,17648,4.981779,-5.883990,-4.471833,0.000000
+0,1,17653,4.981779,-5.727084,-4.550286,0.000000
+0,1,17658,4.981779,-5.727084,-4.550286,0.000000
+0,1,17663,4.981779,-5.766310,-4.746419,0.000000
+0,1,17668,4.981779,-5.766310,-4.746419,0.000000
+0,1,17673,4.824872,-5.962444,-4.707192,0.000000
+0,1,17678,4.824872,-5.962444,-4.707192,0.000000
+0,1,17683,4.471833,-6.197803,-4.550286,0.000000
+0,1,17688,4.471833,-6.197803,-4.550286,0.000000
+0,1,17693,4.079566,-6.315483,-4.432606,0.000000
+0,1,17698,4.079566,-6.315483,-4.432606,0.000000
+0,1,17703,3.765754,-6.472389,-4.314926,0.000000
+0,1,17708,3.765754,-6.472389,-4.314926,0.000000
+0,1,17713,3.726527,-6.590069,-4.314926,0.000000
+0,1,17718,3.726527,-6.590069,-4.314926,0.000000
+0,1,17723,3.687301,-6.668522,-4.236473,0.000000
+0,1,17728,3.687301,-6.668522,-4.236473,0.000000
+0,1,17733,3.765754,-6.746975,-4.236473,0.000000
+0,1,17738,3.765754,-6.746975,-4.236473,0.000000
+0,1,17743,4.001113,-6.590069,-4.197247,0.000000
+0,1,17748,4.001113,-6.590069,-4.197247,0.000000
+0,1,17753,4.275700,-6.511616,-4.079566,0.000000
+0,1,17758,4.275700,-6.511616,-4.079566,0.000000
+0,1,17763,4.511059,-6.315483,-4.118793,0.000000
+0,1,17768,4.511059,-6.315483,-4.118793,0.000000
+0,1,17773,4.785645,-6.354709,-4.236473,0.000000
+0,1,17778,4.785645,-6.354709,-4.236473,0.000000
+0,1,17783,5.060232,-6.354709,-4.275700,0.000000
+0,1,17788,5.060232,-6.354709,-4.275700,0.000000
+0,1,17793,5.099459,-6.393936,-4.158020,0.000000
+0,1,17798,5.099459,-6.393936,-4.158020,0.000000
+0,1,17803,5.099459,-6.433163,-4.040340,0.000000
+0,1,17808,5.099459,-6.433163,-4.040340,0.000000
+0,1,17813,5.177911,-6.433163,-4.001113,0.000000
+0,1,17818,5.177911,-6.433163,-4.001113,0.000000
+0,1,17823,5.217138,-6.472389,-3.687301,0.000000
+0,1,17828,5.217138,-6.472389,-3.687301,0.000000
+0,1,17833,5.452498,-6.825429,-4.001113,0.000000
+0,1,17838,5.452498,-6.825429,-4.001113,0.000000
+0,1,17843,5.609404,-6.982335,-4.079566,0.000000
+0,1,17848,5.609404,-6.982335,-4.079566,0.000000
+0,1,17853,5.883990,-7.021562,-3.883434,0.000000
+0,1,17858,5.883990,-7.021562,-3.883434,0.000000
+0,1,17863,6.001670,-7.060789,-3.961887,0.000000
+0,1,17868,6.001670,-7.060789,-3.961887,0.000000
+0,1,17873,6.237030,-7.531507,-3.608848,0.000000
+0,1,17878,6.237030,-7.531507,-3.608848,0.000000
+0,1,17883,6.354709,-7.256921,-3.569621,0.000000
+0,1,17888,6.354709,-7.256921,-3.569621,0.000000
+0,1,17893,6.550843,-7.256921,-3.373488,0.000000
+0,1,17898,6.550843,-7.256921,-3.373488,0.000000
+0,1,17903,6.864655,-7.296148,-3.295035,0.000000
+0,1,17908,6.864655,-7.296148,-3.295035,0.000000
+0,1,17913,7.139242,-7.374601,-3.451941,0.000000
+0,1,17918,7.139242,-7.374601,-3.451941,0.000000
+0,1,17923,7.139242,-7.374601,-3.451941,0.000000
+0,1,17928,7.296148,-7.531507,-3.569621,0.000000
+0,1,17933,7.296148,-7.531507,-3.569621,0.000000
+0,1,17938,7.256921,-7.609961,-3.412714,0.000000
+0,1,17943,7.256921,-7.609961,-3.412714,0.000000
+0,1,17948,7.296148,-7.766868,-3.530394,0.000000
+0,1,17953,7.296148,-7.766868,-3.530394,0.000000
+0,1,17958,7.217695,-7.609961,-3.608848,0.000000
+0,1,17963,7.217695,-7.609961,-3.608848,0.000000
+0,1,17968,7.139242,-7.649188,-3.687301,0.000000
+0,1,17973,7.139242,-7.649188,-3.687301,0.000000
+0,1,17978,7.100015,-7.649188,-3.844207,0.000000
+0,1,17983,7.100015,-7.649188,-3.844207,0.000000
+0,1,17988,7.217695,-7.649188,-4.001113,0.000000
+0,1,17993,7.217695,-7.649188,-4.001113,0.000000
+0,1,17998,7.021562,-7.609961,-4.001113,0.000000
+0,1,18003,7.021562,-7.609961,-4.001113,0.000000
+0,1,18008,6.982335,-7.845320,-3.765754,0.000000
+0,1,18013,6.982335,-7.845320,-3.765754,0.000000
+0,1,18018,7.139242,-8.512173,-3.530394,0.000000
+0,1,18023,7.139242,-8.512173,-3.530394,0.000000
+0,1,18028,7.492281,-8.825986,-3.451941,0.000000
+0,1,18033,7.492281,-8.825986,-3.451941,0.000000
+0,1,18038,7.688414,-9.296705,-3.804980,0.000000
+0,1,18043,7.688414,-9.296705,-3.804980,0.000000
+0,1,18048,7.884547,-9.532064,-4.158020,0.000000
+0,1,18053,7.884547,-9.532064,-4.158020,0.000000
+0,1,18058,7.963000,-8.943666,-4.511059,0.000000
+0,1,18063,7.963000,-8.943666,-4.511059,0.000000
+0,1,18068,7.806094,-8.394493,-4.785645,0.000000
+0,1,18073,7.806094,-8.394493,-4.785645,0.000000
+0,1,18078,7.806094,-7.923774,-4.942552,0.000000
+0,1,18083,7.806094,-7.923774,-4.942552,0.000000
+0,1,18088,7.766868,-7.570734,-5.217138,0.000000
+0,1,18093,7.766868,-7.570734,-5.217138,0.000000
+0,1,18098,7.806094,-7.139242,-5.530951,0.000000
+0,1,18103,7.806094,-7.139242,-5.530951,0.000000
+0,1,18108,7.845320,-6.746975,-5.805537,0.000000
+0,1,18113,7.845320,-6.746975,-5.805537,0.000000
+0,1,18118,7.688414,-6.237030,-6.040897,0.000000
+0,1,18123,7.688414,-6.237030,-6.040897,0.000000
+0,1,18128,7.531507,-5.609404,-5.962444,0.000000
+0,1,18133,7.531507,-5.609404,-5.962444,0.000000
+0,1,18138,7.217695,-5.060232,-5.727084,0.000000
+0,1,18143,7.217695,-5.060232,-5.727084,0.000000
+0,1,18148,7.021562,-4.864099,-5.570178,0.000000
+0,1,18153,7.021562,-4.864099,-5.570178,0.000000
+0,1,18158,6.943109,-5.021005,-5.256365,0.000000
+0,1,18163,6.943109,-5.021005,-5.256365,0.000000
+0,1,18168,6.393936,-5.217138,-5.177911,0.000000
+0,1,18173,6.393936,-5.217138,-5.177911,0.000000
+0,1,18178,6.433163,-5.648631,-4.903325,0.000000
+0,1,18183,6.433163,-5.648631,-4.903325,0.000000
+0,1,18188,6.001670,-5.609404,-4.707192,0.000000
+0,1,18193,6.001670,-5.609404,-4.707192,0.000000
+0,1,18198,6.001670,-5.766310,-4.942552,0.000000
+0,1,18203,6.001670,-5.766310,-4.942552,0.000000
+0,1,18208,5.962444,-6.001670,-4.471833,0.000000
+0,1,18213,5.962444,-6.001670,-4.471833,0.000000
+0,1,18218,5.687858,-6.472389,-4.707192,0.000000
+0,1,18223,5.687858,-6.472389,-4.707192,0.000000
+0,1,18228,5.609404,-6.511616,-4.118793,0.000000
+0,1,18233,5.609404,-6.511616,-4.118793,0.000000
+0,1,18238,5.609404,-6.590069,-4.236473,0.000000
+0,1,18243,5.609404,-6.590069,-4.236473,0.000000
+0,1,18248,5.570178,-6.433163,-4.118793,0.000000
+0,1,18253,5.570178,-6.433163,-4.118793,0.000000
+0,1,18258,5.491724,-6.472389,-4.314926,0.000000
+0,1,18263,5.491724,-6.472389,-4.314926,0.000000
+0,1,18268,5.413271,-6.315483,-4.393379,0.000000
+0,1,18273,5.413271,-6.315483,-4.393379,0.000000
+0,1,18278,5.452498,-6.040897,-4.118793,0.000000
+0,1,18283,5.452498,-6.040897,-4.118793,0.000000
+0,1,18288,5.491724,-6.080123,-4.236473,0.000000
+0,1,18293,5.491724,-6.080123,-4.236473,0.000000
+0,1,18298,5.334818,-5.883990,-4.158020,0.000000
+0,1,18303,5.334818,-5.883990,-4.158020,0.000000
+0,1,18308,5.334818,-5.727084,-4.354153,0.000000
+0,1,18313,5.334818,-5.727084,-4.354153,0.000000
+0,1,18318,5.295591,-5.844764,-4.197247,0.000000
+0,1,18323,5.295591,-5.844764,-4.197247,0.000000
+0,1,18328,5.491724,-5.844764,-4.314926,0.000000
+0,1,18333,5.491724,-5.844764,-4.314926,0.000000
+0,1,18338,5.452498,-5.962444,-4.236473,0.000000
+0,1,18343,5.452498,-5.962444,-4.236473,0.000000
+0,1,18348,5.334818,-5.883990,-4.001113,0.000000
+0,1,18353,5.334818,-5.883990,-4.001113,0.000000
+0,1,18358,5.295591,-6.001670,-4.158020,0.000000
+0,1,18363,5.295591,-6.001670,-4.158020,0.000000
+0,1,18368,5.413271,-6.080123,-4.511059,0.000000
+0,1,18373,5.413271,-6.080123,-4.511059,0.000000
+0,1,18378,5.570178,-6.315483,-4.432606,0.000000
+0,1,18383,5.530951,-6.315483,-4.432606,0.000000
+0,1,18388,5.530951,-6.315483,-4.432606,0.000000
+0,1,18393,5.727084,-6.119350,-3.961887,0.000000
+0,1,18398,5.727084,-6.119350,-3.961887,0.000000
+0,1,18403,5.491724,-6.315483,-4.158020,0.000000
+0,1,18408,5.491724,-6.315483,-4.158020,0.000000
+0,1,18413,5.491724,-6.080123,-3.844207,0.000000
+0,1,18418,5.491724,-6.080123,-3.844207,0.000000
+0,1,18423,5.374045,-6.040897,-3.804980,0.000000
+0,1,18428,5.374045,-6.040897,-3.804980,0.000000
+0,1,18433,5.217138,-6.237030,-4.001113,0.000000
+0,1,18438,5.217138,-6.237030,-4.001113,0.000000
+0,1,18443,5.256365,-6.550843,-3.883434,0.000000
+0,1,18448,5.256365,-6.550843,-3.883434,0.000000
+0,1,18453,5.530951,-6.668522,-4.040340,0.000000
+0,1,18458,5.530951,-6.668522,-4.040340,0.000000
+0,1,18463,5.099459,-6.040897,-3.138128,0.000000
+0,1,18468,5.099459,-6.040897,-3.138128,0.000000
+0,1,18473,5.099459,-6.040897,-4.354153,0.000000
+0,1,18478,5.099459,-6.040897,-4.354153,0.000000
+0,1,18483,5.295591,-6.354709,-3.765754,0.000000
+0,1,18488,5.295591,-6.354709,-3.765754,0.000000
+0,1,18493,5.766310,-6.433163,-4.589512,0.000000
+0,1,18498,5.766310,-6.433163,-4.589512,0.000000
+0,1,18503,5.570178,-6.433163,-4.197247,0.000000
+0,1,18508,5.570178,-6.433163,-4.197247,0.000000
+0,1,18513,5.609404,-6.590069,-4.275700,0.000000
+0,1,18518,5.609404,-6.590069,-4.275700,0.000000
+0,1,18523,5.570178,-7.060789,-4.275700,0.000000
+0,1,18528,5.570178,-7.060789,-4.275700,0.000000
+0,1,18533,5.844764,-7.256921,-4.511059,0.000000
+0,1,18538,5.844764,-7.256921,-4.511059,0.000000
+0,1,18543,6.040897,-7.139242,-4.354153,0.000000
+0,1,18548,6.040897,-7.139242,-4.354153,0.000000
+0,1,18553,6.393936,-7.217695,-4.432606,0.000000
+0,1,18558,6.393936,-7.217695,-4.432606,0.000000
+0,1,18563,6.668522,-7.766868,-4.589512,0.000000
+0,1,18568,6.668522,-7.766868,-4.589512,0.000000
+0,1,18573,6.825429,-7.923774,-4.471833,0.000000
+0,1,18578,6.825429,-7.923774,-4.471833,0.000000
+0,1,18583,6.786202,-7.727641,-4.707192,0.000000
+0,1,18588,6.786202,-7.727641,-4.707192,0.000000
+0,1,18593,6.982335,-7.923774,-4.785645,0.000000
+0,1,18598,6.982335,-7.923774,-4.785645,0.000000
+0,1,18603,7.139242,-7.845320,-4.746419,0.000000
+0,1,18608,7.139242,-7.845320,-4.746419,0.000000
+0,1,18613,7.178468,-7.766868,-4.942552,0.000000
+0,1,18618,7.178468,-7.766868,-4.942552,0.000000
+0,1,18623,6.982335,-7.453054,-4.942552,0.000000
+0,1,18628,6.982335,-7.453054,-4.942552,0.000000
+0,1,18633,6.943109,-7.139242,-4.824872,0.000000
+0,1,18638,6.943109,-7.139242,-4.824872,0.000000
+0,1,18643,6.982335,-7.413828,-5.099459,0.000000
+0,1,18648,6.982335,-7.413828,-5.099459,0.000000
+0,1,18653,7.139242,-8.512173,-4.864099,0.000000
+0,1,18658,7.139242,-8.512173,-4.864099,0.000000
+0,1,18663,7.492281,-9.375158,-5.060232,0.000000
+0,1,18668,7.492281,-9.375158,-5.060232,0.000000
+0,1,18673,7.453054,-9.610518,-5.374045,0.000000
+0,1,18678,7.453054,-9.610518,-5.374045,0.000000
+0,1,18683,7.649188,-9.414385,-5.256365,0.000000
+0,1,18688,7.649188,-9.414385,-5.256365,0.000000
+0,1,18693,7.923774,-8.943666,-5.727084,0.000000
+0,1,18698,7.923774,-8.943666,-5.727084,0.000000
+0,1,18703,7.806094,-9.061345,-5.727084,0.000000
+0,1,18708,7.806094,-9.061345,-5.727084,0.000000
+0,1,18713,7.884547,-8.080680,-5.962444,0.000000
+0,1,18718,7.884547,-8.080680,-5.962444,0.000000
+0,1,18723,8.080680,-7.884547,-5.883990,0.000000
+0,1,18728,8.080680,-7.884547,-5.883990,0.000000
+0,1,18733,8.002227,-7.609961,-6.433163,0.000000
+0,1,18738,8.002227,-7.609961,-6.433163,0.000000
+0,1,18743,7.923774,-7.766868,-6.276257,0.000000
+0,1,18748,7.923774,-7.766868,-6.276257,0.000000
+0,1,18753,7.453054,-6.472389,-6.393936,0.000000
+0,1,18758,7.453054,-6.472389,-6.393936,0.000000
+0,1,18763,6.943109,-6.668522,-6.040897,0.000000
+0,1,18768,6.943109,-6.668522,-6.040897,0.000000
+0,1,18773,6.511616,-6.629296,-5.452498,0.000000
+0,1,18778,6.511616,-6.629296,-5.452498,0.000000
+0,1,18783,6.001670,-7.374601,-4.864099,0.000000
+0,1,18788,6.001670,-7.374601,-4.864099,0.000000
+0,1,18793,6.237030,-7.649188,-4.511059,0.000000
+0,1,18798,6.237030,-7.649188,-4.511059,0.000000
+0,1,18803,5.491724,-7.453054,-4.197247,0.000000
+0,1,18808,5.491724,-7.453054,-4.197247,0.000000
+0,1,18813,5.217138,-7.453054,-3.804980,0.000000
+0,1,18818,5.217138,-7.453054,-3.804980,0.000000
+0,1,18823,4.981779,-7.609961,-3.334261,0.000000
+0,1,18828,4.981779,-7.609961,-3.334261,0.000000
+0,1,18833,4.903325,-7.688414,-3.295035,0.000000
+0,1,18838,4.903325,-7.688414,-3.295035,0.000000
+0,1,18843,4.903325,-7.688414,-3.138128,0.000000
+0,1,18848,4.746419,-7.531507,-3.020448,0.000000
+0,1,18853,4.746419,-7.531507,-3.020448,0.000000
+0,1,18858,4.628739,-7.453054,-3.098902,0.000000
+0,1,18863,4.628739,-7.453054,-3.098902,0.000000
+0,1,18868,4.589512,-7.335374,-3.059675,0.000000
+0,1,18873,4.589512,-7.335374,-3.059675,0.000000
+0,1,18878,4.667965,-7.374601,-3.098902,0.000000
+0,1,18883,4.667965,-7.374601,-3.098902,0.000000
+0,1,18888,4.550286,-7.374601,-3.334261,0.000000
+0,1,18893,4.550286,-7.374601,-3.334261,0.000000
+0,1,18898,4.471833,-7.296148,-3.373488,0.000000
+0,1,18903,4.471833,-7.296148,-3.373488,0.000000
+0,1,18908,4.393379,-7.060789,-3.451941,0.000000
+0,1,18913,4.393379,-7.060789,-3.451941,0.000000
+0,1,18918,4.275700,-6.903882,-3.569621,0.000000
+0,1,18923,4.275700,-6.903882,-3.569621,0.000000
+0,1,18928,4.197247,-6.825429,-3.608848,0.000000
+0,1,18933,4.197247,-6.825429,-3.608848,0.000000
+0,1,18938,4.314926,-6.668522,-3.765754,0.000000
+0,1,18943,4.314926,-6.668522,-3.765754,0.000000
+0,1,18948,4.197247,-6.629296,-3.844207,0.000000
+0,1,18953,4.197247,-6.629296,-3.844207,0.000000
+0,1,18958,4.158020,-6.550843,-4.001113,0.000000
+0,1,18963,4.158020,-6.550843,-4.001113,0.000000
+0,1,18968,4.118793,-6.433163,-4.118793,0.000000
+0,1,18973,4.118793,-6.433163,-4.118793,0.000000
+0,1,18978,4.197247,-6.550843,-4.197247,0.000000
+0,1,18983,4.197247,-6.550843,-4.197247,0.000000
+0,1,18988,4.158020,-6.590069,-4.158020,0.000000
+0,1,18993,4.158020,-6.590069,-4.158020,0.000000
+0,1,18998,4.158020,-6.590069,-4.001113,0.000000
+0,1,19003,4.158020,-6.590069,-4.001113,0.000000
+0,1,19008,4.314926,-6.511616,-3.922660,0.000000
+0,1,19013,4.314926,-6.511616,-3.922660,0.000000
+0,1,19018,4.393379,-6.472389,-3.844207,0.000000
+0,1,19023,4.393379,-6.472389,-3.844207,0.000000
+0,1,19028,4.550286,-6.393936,-3.608848,0.000000
+0,1,19033,4.550286,-6.393936,-3.608848,0.000000
+0,1,19038,4.589512,-6.354709,-3.491168,0.000000
+0,1,19043,4.589512,-6.354709,-3.491168,0.000000
+0,1,19048,4.667965,-6.472389,-3.412714,0.000000
+0,1,19053,4.667965,-6.472389,-3.412714,0.000000
+0,1,19058,4.785645,-6.393936,-3.216581,0.000000
+0,1,19063,4.785645,-6.393936,-3.216581,0.000000
+0,1,19068,4.824872,-6.393936,-3.216581,0.000000
+0,1,19073,4.824872,-6.393936,-3.216581,0.000000
+0,1,19078,4.942552,-6.433163,-3.216581,0.000000
+0,1,19083,4.942552,-6.433163,-3.216581,0.000000
+0,1,19088,5.060232,-6.354709,-3.334261,0.000000
+0,1,19093,5.060232,-6.354709,-3.334261,0.000000
+0,1,19098,5.099459,-6.276257,-3.255808,0.000000
+0,1,19103,5.099459,-6.276257,-3.255808,0.000000
+0,1,19108,5.138685,-6.237030,-3.334261,0.000000
+0,1,19113,5.138685,-6.237030,-3.334261,0.000000
+0,1,19118,5.138685,-6.354709,-3.295035,0.000000
+0,1,19123,5.138685,-6.354709,-3.295035,0.000000
+0,1,19128,5.138685,-6.550843,-3.255808,0.000000
+0,1,19133,5.138685,-6.550843,-3.255808,0.000000
+0,1,19138,5.138685,-6.786202,-3.373488,0.000000
+0,1,19143,5.138685,-6.786202,-3.373488,0.000000
+0,1,19148,5.217138,-7.100015,-3.569621,0.000000
+0,1,19153,5.217138,-7.100015,-3.569621,0.000000
+0,1,19158,5.452498,-7.217695,-3.569621,0.000000
+0,1,19163,5.452498,-7.217695,-3.569621,0.000000
+0,1,19168,5.570178,-7.256921,-3.687301,0.000000
+0,1,19173,5.570178,-7.256921,-3.687301,0.000000
+0,1,19178,5.609404,-7.256921,-3.608848,0.000000
+0,1,19183,5.609404,-7.256921,-3.608848,0.000000
+0,1,19188,5.883990,-7.649188,-3.765754,0.000000
+0,1,19193,5.883990,-7.649188,-3.765754,0.000000
+0,1,19198,6.119350,-7.688414,-4.158020,0.000000
+0,1,19203,6.119350,-7.688414,-4.158020,0.000000
+0,1,19208,6.276257,-8.159133,-4.550286,0.000000
+0,1,19213,6.276257,-8.159133,-4.550286,0.000000
+0,1,19218,6.550843,-8.119907,-4.001113,0.000000
+0,1,19223,6.550843,-8.119907,-4.001113,0.000000
+0,1,19228,6.668522,-8.237586,-4.589512,0.000000
+0,1,19233,6.668522,-8.237586,-4.589512,0.000000
+0,1,19238,6.746975,-8.237586,-4.550286,0.000000
+0,1,19243,6.746975,-8.237586,-4.550286,0.000000
+0,1,19248,6.903882,-8.198359,-4.864099,0.000000
+0,1,19253,6.903882,-8.198359,-4.864099,0.000000
+0,1,19258,7.021562,-8.119907,-4.903325,0.000000
+0,1,19263,7.021562,-8.119907,-4.903325,0.000000
+0,1,19268,7.139242,-8.080680,-5.060232,0.000000
+0,1,19273,7.139242,-8.080680,-5.060232,0.000000
+0,1,19278,7.100015,-8.041453,-4.981779,0.000000
+0,1,19283,7.100015,-8.041453,-4.981779,0.000000
+0,1,19288,6.982335,-7.806094,-4.942552,0.000000
+0,1,19293,6.982335,-7.806094,-4.942552,0.000000
+0,1,19298,6.982335,-7.806094,-4.942552,0.000000
+0,1,19303,6.943109,-7.570734,-4.589512,0.000000
+0,1,19308,6.943109,-7.570734,-4.589512,0.000000
+0,1,19313,6.707749,-7.649188,-4.354153,0.000000
+0,1,19318,6.707749,-7.649188,-4.354153,0.000000
+0,1,19323,6.943109,-7.963000,-4.275700,0.000000
+0,1,19328,6.943109,-7.963000,-4.275700,0.000000
+0,1,19333,7.609961,-9.139798,-4.275700,0.000000
+0,1,19338,7.609961,-9.139798,-4.275700,0.000000
+0,1,19343,7.845320,-9.649744,-4.550286,0.000000
+0,1,19348,7.845320,-9.649744,-4.550286,0.000000
+0,1,19353,8.276814,-10.002784,-4.707192,0.000000
+0,1,19358,8.276814,-10.002784,-4.707192,0.000000
+0,1,19363,8.551399,-9.924331,-4.981779,0.000000
+0,1,19368,8.551399,-9.924331,-4.981779,0.000000
+0,1,19373,8.551399,-9.414385,-5.177911,0.000000
+0,1,19378,8.551399,-9.414385,-5.177911,0.000000
+0,1,19383,8.394493,-8.472946,-5.256365,0.000000
+0,1,19388,8.394493,-8.472946,-5.256365,0.000000
+0,1,19393,7.923774,-7.727641,-5.295591,0.000000
+0,1,19398,7.923774,-7.727641,-5.295591,0.000000
+0,1,19403,7.727641,-7.256921,-5.177911,0.000000
+0,1,19408,7.727641,-7.256921,-5.177911,0.000000
+0,1,19413,7.531507,-6.629296,-5.295591,0.000000
+0,1,19418,7.531507,-6.629296,-5.295591,0.000000
+0,1,19423,7.335374,-6.158576,-5.374045,0.000000
+0,1,19428,7.335374,-6.158576,-5.374045,0.000000
+0,1,19433,6.982335,-5.452498,-5.060232,0.000000
+0,1,19438,6.982335,-5.452498,-5.060232,0.000000
+0,1,19443,6.550843,-5.021005,-4.824872,0.000000
+0,1,19448,6.550843,-5.021005,-4.824872,0.000000
+0,1,19453,6.276257,-4.903325,-4.471833,0.000000
+0,1,19458,6.276257,-4.903325,-4.471833,0.000000
+0,1,19463,6.315483,-5.334818,-4.550286,0.000000
+0,1,19468,6.315483,-5.334818,-4.550286,0.000000
+0,1,19473,6.903882,-6.040897,-4.667965,0.000000
+0,1,19478,6.903882,-6.040897,-4.667965,0.000000
+0,1,19483,6.590069,-6.001670,-4.864099,0.000000
+0,1,19488,6.590069,-6.001670,-4.864099,0.000000
+0,1,19493,6.943109,-5.962444,-4.432606,0.000000
+0,1,19498,6.943109,-5.962444,-4.432606,0.000000
+0,1,19503,6.903882,-5.687858,-4.511059,0.000000
+0,1,19508,6.903882,-5.687858,-4.511059,0.000000
+0,1,19513,7.178468,-5.844764,-4.589512,0.000000
+0,1,19518,7.178468,-5.844764,-4.589512,0.000000
+0,1,19523,7.374601,-5.923217,-4.981779,0.000000
+0,1,19528,7.374601,-5.923217,-4.981779,0.000000
+0,1,19533,7.256921,-5.687858,-4.746419,0.000000
+0,1,19538,7.256921,-5.687858,-4.746419,0.000000
+0,1,19543,7.296148,-5.727084,-4.824872,0.000000
+0,1,19548,7.296148,-5.727084,-4.824872,0.000000
+0,1,19553,7.021562,-5.805537,-4.785645,0.000000
+0,1,19558,7.021562,-5.805537,-4.785645,0.000000
+0,1,19563,6.786202,-5.844764,-4.864099,0.000000
+0,1,19568,6.786202,-5.844764,-4.864099,0.000000
+0,1,19573,6.550843,-5.805537,-4.746419,0.000000
+0,1,19578,6.550843,-5.805537,-4.746419,0.000000
+0,1,19583,6.158576,-5.727084,-4.550286,0.000000
+0,1,19593,6.040897,-5.609404,-4.432606,0.000000
+0,1,19598,6.040897,-5.609404,-4.432606,0.000000
+0,1,19603,5.805537,-5.530951,-4.314926,0.000000
+0,1,19608,5.805537,-5.530951,-4.314926,0.000000
+0,1,19613,5.609404,-5.491724,-3.922660,0.000000
+0,1,19618,5.609404,-5.491724,-3.922660,0.000000
+0,1,19623,5.413271,-5.413271,-3.804980,0.000000
+0,1,19628,5.413271,-5.413271,-3.804980,0.000000
+0,1,19633,5.334818,-5.334818,-3.726527,0.000000
+0,1,19638,5.334818,-5.334818,-3.726527,0.000000
+0,1,19643,5.334818,-5.256365,-3.608848,0.000000
+0,1,19648,5.334818,-5.256365,-3.608848,0.000000
+0,1,19653,5.060232,-5.491724,-3.648074,0.000000
+0,1,19658,5.060232,-5.491724,-3.648074,0.000000
+0,1,19663,5.021005,-5.570178,-3.648074,0.000000
+0,1,19668,5.021005,-5.570178,-3.648074,0.000000
+0,1,19673,5.060232,-5.530951,-3.569621,0.000000
+0,1,19678,5.060232,-5.530951,-3.569621,0.000000
+0,1,19683,5.099459,-5.648631,-3.530394,0.000000
+0,1,19688,5.099459,-5.648631,-3.530394,0.000000
+0,1,19693,5.060232,-5.727084,-3.451941,0.000000
+0,1,19698,5.060232,-5.727084,-3.451941,0.000000
+0,1,19703,5.177911,-5.844764,-3.491168,0.000000
+0,1,19708,5.177911,-5.844764,-3.491168,0.000000
+0,1,19713,5.256365,-5.923217,-3.216581,0.000000
+0,1,19718,5.256365,-5.923217,-3.216581,0.000000
+0,1,19723,5.295591,-6.040897,-3.373488,0.000000
+0,1,19728,5.295591,-6.040897,-3.373488,0.000000
+0,1,19733,5.452498,-6.197803,-3.373488,0.000000
+0,1,19738,5.452498,-6.197803,-3.373488,0.000000
+0,1,19743,5.648631,-6.197803,-3.726527,0.000000
+0,1,19748,5.648631,-6.197803,-3.726527,0.000000
+0,1,19753,5.648631,-6.197803,-3.883434,0.000000
+0,1,19758,5.766310,-6.080123,-3.922660,0.000000
+0,1,19763,5.766310,-6.080123,-3.922660,0.000000
+0,1,19768,5.844764,-5.962444,-3.804980,0.000000
+0,1,19773,5.844764,-5.962444,-3.804980,0.000000
+0,1,19778,5.883990,-5.883990,-3.961887,0.000000
+0,1,19783,5.883990,-5.883990,-3.961887,0.000000
+0,1,19788,5.805537,-5.687858,-3.961887,0.000000
+0,1,19793,5.805537,-5.687858,-3.961887,0.000000
+0,1,19798,5.687858,-5.727084,-3.844207,0.000000
+0,1,19803,5.687858,-5.727084,-3.844207,0.000000
+0,1,19808,5.805537,-5.962444,-4.118793,0.000000
+0,1,19813,5.805537,-5.962444,-4.118793,0.000000
+0,1,19818,5.844764,-6.080123,-4.118793,0.000000
+0,1,19823,5.844764,-6.080123,-4.118793,0.000000
+0,1,19828,5.766310,-6.315483,-4.079566,0.000000
+0,1,19833,5.766310,-6.315483,-4.079566,0.000000
+0,1,19838,5.923217,-6.511616,-4.314926,0.000000
+0,1,19843,5.923217,-6.511616,-4.314926,0.000000
+0,1,19848,6.158576,-6.864655,-4.354153,0.000000
+0,1,19853,6.158576,-6.864655,-4.354153,0.000000
+0,1,19858,6.472389,-7.060789,-4.393379,0.000000
+0,1,19863,6.472389,-7.060789,-4.393379,0.000000
+0,1,19868,6.825429,-7.217695,-4.393379,0.000000
+0,1,19873,6.825429,-7.217695,-4.393379,0.000000
+0,1,19878,7.178468,-7.335374,-4.471833,0.000000
+0,1,19883,7.178468,-7.335374,-4.471833,0.000000
+0,1,19888,7.374601,-7.335374,-4.471833,0.000000
+0,1,19893,7.374601,-7.335374,-4.471833,0.000000
+0,1,19898,7.453054,-7.413828,-4.628739,0.000000
+0,1,19903,7.453054,-7.413828,-4.628739,0.000000
+0,1,19908,7.570734,-7.178468,-4.746419,0.000000
+0,1,19913,7.570734,-7.178468,-4.746419,0.000000
+0,1,19918,7.492281,-7.021562,-4.824872,0.000000
+0,1,19923,7.492281,-7.021562,-4.824872,0.000000
+0,1,19928,7.492281,-6.903882,-4.864099,0.000000
+0,1,19933,7.492281,-6.903882,-4.864099,0.000000
+0,1,19938,7.570734,-7.060789,-5.021005,0.000000
+0,1,19943,7.570734,-7.060789,-5.021005,0.000000
+0,1,19948,7.609961,-7.923774,-4.707192,0.000000
+0,1,19953,7.609961,-7.923774,-4.707192,0.000000
+0,1,19958,8.002227,-9.139798,-4.746419,0.000000
+0,1,19963,8.002227,-9.139798,-4.746419,0.000000
+0,1,19968,7.963000,-9.375158,-4.903325,0.000000
+0,1,19973,7.963000,-9.375158,-4.903325,0.000000
+0,1,19978,8.002227,-9.414385,-5.491724,0.000000
+0,1,19983,8.002227,-9.414385,-5.491724,0.000000
+0,1,19988,8.237586,-9.139798,-5.530951,0.000000
+0,1,19993,8.237586,-9.139798,-5.530951,0.000000
+0,1,19998,8.786758,-8.943666,-5.766310,0.000000
+0,1,20003,8.786758,-8.943666,-5.766310,0.000000
+0,1,20008,9.022119,-8.982892,-5.256365,0.000000
+0,1,20013,9.022119,-8.982892,-5.256365,0.000000
+0,1,20018,8.943666,-8.041453,-6.393936,0.000000
+0,1,20023,8.943666,-8.041453,-6.393936,0.000000
+0,1,20028,8.904439,-7.727641,-6.040897,0.000000
+0,1,20033,8.904439,-7.727641,-6.040897,0.000000
+0,1,20038,8.512173,-7.296148,-4.981779,0.000000
+0,1,20043,8.512173,-7.296148,-4.981779,0.000000
+0,1,20048,7.806094,-7.100015,-6.119350,0.000000
+0,1,20053,7.806094,-7.100015,-6.119350,0.000000
+0,1,20058,7.100015,-6.982335,-5.883990,0.000000
+0,1,20063,7.100015,-6.982335,-5.883990,0.000000
+0,1,20068,6.119350,-7.060789,-5.805537,0.000000
+0,1,20073,6.119350,-7.060789,-5.805537,0.000000
+0,1,20078,5.138685,-6.864655,-5.844764,0.000000
+0,1,20083,5.138685,-6.864655,-5.844764,0.000000
+0,1,20088,4.785645,-6.825429,-4.864099,0.000000
+0,1,20093,4.785645,-6.825429,-4.864099,0.000000
+0,1,20098,5.021005,-8.237586,-4.275700,0.000000
+0,1,20103,5.021005,-8.237586,-4.275700,0.000000
+0,1,20108,4.511059,-8.119907,-4.550286,0.000000
+0,1,20113,4.511059,-8.119907,-4.550286,0.000000
+0,1,20118,4.314926,-7.845320,-3.883434,0.000000
+0,1,20123,4.314926,-7.845320,-3.883434,0.000000
+0,1,20128,4.275700,-7.727641,-3.765754,0.000000
+0,1,20133,4.275700,-7.727641,-3.765754,0.000000
+0,1,20138,4.628739,-7.963000,-3.530394,0.000000
+0,1,20143,4.628739,-7.963000,-3.530394,0.000000
+0,1,20148,4.667965,-7.649188,-3.569621,0.000000
+0,1,20153,4.667965,-7.649188,-3.569621,0.000000
+0,1,20158,4.864099,-7.531507,-3.569621,0.000000
+0,1,20163,4.864099,-7.531507,-3.569621,0.000000
+0,1,20168,4.942552,-7.374601,-3.412714,0.000000
+0,1,20173,4.942552,-7.374601,-3.412714,0.000000
+0,1,20178,5.217138,-7.256921,-3.530394,0.000000
+0,1,20183,5.217138,-7.256921,-3.530394,0.000000
+0,1,20188,5.374045,-7.100015,-3.687301,0.000000
+0,1,20193,5.374045,-7.100015,-3.687301,0.000000
+0,1,20198,5.295591,-6.825429,-3.648074,0.000000
+0,1,20203,5.295591,-6.825429,-3.648074,0.000000
+0,1,20208,5.295591,-6.668522,-3.765754,0.000000
+0,1,20213,5.138685,-6.629296,-3.765754,0.000000
+0,1,20218,5.138685,-6.629296,-3.765754,0.000000
+0,1,20223,4.981779,-6.590069,-3.726527,0.000000
+0,1,20228,4.981779,-6.590069,-3.726527,0.000000
+0,1,20233,4.707192,-6.511616,-3.804980,0.000000
+0,1,20238,4.707192,-6.511616,-3.804980,0.000000
+0,1,20243,4.471833,-6.472389,-3.961887,0.000000
+0,1,20248,4.471833,-6.472389,-3.961887,0.000000
+0,1,20253,4.314926,-6.511616,-3.961887,0.000000
+0,1,20258,4.314926,-6.511616,-3.961887,0.000000
+0,1,20263,4.275700,-6.746975,-4.118793,0.000000
+0,1,20268,4.275700,-6.746975,-4.118793,0.000000
+0,1,20273,4.236473,-6.668522,-3.922660,0.000000
+0,1,20278,4.236473,-6.668522,-3.922660,0.000000
+0,1,20283,4.118793,-6.354709,-3.961887,0.000000
+0,1,20288,4.118793,-6.354709,-3.961887,0.000000
+0,1,20293,4.197247,-6.550843,-3.844207,0.000000
+0,1,20298,4.197247,-6.550843,-3.844207,0.000000
+0,1,20303,4.197247,-6.590069,-3.687301,0.000000
+0,1,20308,4.197247,-6.590069,-3.687301,0.000000
+0,1,20313,4.432606,-6.590069,-3.491168,0.000000
+0,1,20318,4.432606,-6.590069,-3.491168,0.000000
+0,1,20323,4.236473,-6.511616,-3.530394,0.000000
+0,1,20328,4.236473,-6.511616,-3.530394,0.000000
+0,1,20333,4.354153,-6.433163,-3.491168,0.000000
+0,1,20338,4.354153,-6.433163,-3.491168,0.000000
+0,1,20343,4.511059,-6.393936,-3.687301,0.000000
+0,1,20348,4.511059,-6.393936,-3.687301,0.000000
+0,1,20353,4.707192,-6.472389,-3.373488,0.000000
+0,1,20358,4.707192,-6.472389,-3.373488,0.000000
+0,1,20363,4.667965,-6.472389,-3.451941,0.000000
+0,1,20368,4.667965,-6.472389,-3.451941,0.000000
+0,1,20373,4.785645,-6.472389,-3.334261,0.000000
+0,1,20378,4.785645,-6.472389,-3.334261,0.000000
+0,1,20383,4.942552,-6.433163,-3.295035,0.000000
+0,1,20388,4.942552,-6.433163,-3.295035,0.000000
+0,1,20393,5.021005,-6.393936,-3.334261,0.000000
+0,1,20398,5.021005,-6.393936,-3.334261,0.000000
+0,1,20403,5.138685,-6.393936,-3.334261,0.000000
+0,1,20408,5.138685,-6.393936,-3.334261,0.000000
+0,1,20413,5.374045,-6.472389,-3.451941,0.000000
+0,1,20418,5.374045,-6.472389,-3.451941,0.000000
+0,1,20423,5.452498,-6.472389,-3.491168,0.000000
+0,1,20428,5.452498,-6.472389,-3.491168,0.000000
+0,1,20433,5.530951,-6.629296,-3.608848,0.000000
+0,1,20438,5.530951,-6.629296,-3.608848,0.000000
+0,1,20443,5.609404,-6.629296,-3.726527,0.000000
+0,1,20448,5.609404,-6.629296,-3.726527,0.000000
+0,1,20453,5.648631,-6.707749,-3.687301,0.000000
+0,1,20458,5.648631,-6.707749,-3.687301,0.000000
+0,1,20463,5.648631,-6.864655,-3.804980,0.000000
+0,1,20468,5.648631,-6.864655,-3.804980,0.000000
+0,1,20473,5.687858,-6.982335,-3.687301,0.000000
+0,1,20478,5.687858,-6.982335,-3.687301,0.000000
+0,1,20483,5.883990,-7.139242,-3.883434,0.000000
+0,1,20488,5.883990,-7.139242,-3.883434,0.000000
+0,1,20493,5.923217,-7.453054,-3.922660,0.000000
+0,1,20498,5.923217,-7.453054,-3.922660,0.000000
+0,1,20503,6.197803,-7.609961,-4.158020,0.000000
+0,1,20508,6.197803,-7.609961,-4.158020,0.000000
+0,1,20513,6.315483,-7.845320,-4.236473,0.000000
+0,1,20518,6.315483,-7.845320,-4.236473,0.000000
+0,1,20523,6.472389,-7.923774,-4.511059,0.000000
+0,1,20528,6.472389,-7.923774,-4.511059,0.000000
+0,1,20533,6.629296,-8.119907,-4.550286,0.000000
+0,1,20538,6.629296,-8.119907,-4.550286,0.000000
+0,1,20543,6.825429,-8.080680,-4.550286,0.000000
+0,1,20548,6.825429,-8.080680,-4.550286,0.000000
+0,1,20553,7.021562,-8.041453,-4.707192,0.000000
+0,1,20558,7.021562,-8.041453,-4.707192,0.000000
+0,1,20563,7.021562,-7.806094,-4.785645,0.000000
+0,1,20568,7.021562,-7.806094,-4.785645,0.000000
+0,1,20573,7.021562,-7.688414,-4.667965,0.000000
+0,1,20578,7.021562,-7.688414,-4.667965,0.000000
+0,1,20583,7.139242,-7.413828,-4.589512,0.000000
+0,1,20588,7.139242,-7.413828,-4.589512,0.000000
+0,1,20593,7.256921,-7.335374,-4.550286,0.000000
+0,1,20598,7.256921,-7.335374,-4.550286,0.000000
+0,1,20603,7.374601,-7.727641,-4.393379,0.000000
+0,1,20608,7.374601,-7.727641,-4.393379,0.000000
+0,1,20613,7.609961,-8.237586,-4.354153,0.000000
+0,1,20618,7.609961,-8.237586,-4.354153,0.000000
+0,1,20623,8.237586,-9.100572,-4.354153,0.000000
+0,1,20628,8.237586,-9.100572,-4.354153,0.000000
+0,1,20633,8.472946,-9.335931,-4.550286,0.000000
+0,1,20638,8.472946,-9.335931,-4.550286,0.000000
+0,1,20643,8.943666,-9.375158,-4.903325,0.000000
+0,1,20648,8.943666,-9.375158,-4.903325,0.000000
+0,1,20653,8.865212,-8.747532,-4.864099,0.000000
+0,1,20658,8.865212,-8.747532,-4.864099,0.000000
+0,1,20663,8.433720,-7.884547,-5.138685,0.000000
+0,1,20668,8.433720,-7.884547,-5.138685,0.000000
+0,1,20673,8.433720,-7.884547,-5.138685,0.000000
+0,1,20678,8.041453,-7.492281,-5.138685,0.000000
+0,1,20683,8.041453,-7.492281,-5.138685,0.000000
+0,1,20688,7.492281,-7.178468,-5.217138,0.000000
+0,1,20693,7.492281,-7.178468,-5.217138,0.000000
+0,1,20698,7.060789,-6.825429,-5.217138,0.000000
+0,1,20703,7.060789,-6.825429,-5.217138,0.000000
+0,1,20708,6.590069,-6.354709,-5.177911,0.000000
+0,1,20713,6.590069,-6.354709,-5.177911,0.000000
+0,1,20718,6.276257,-6.158576,-5.060232,0.000000
+0,1,20723,6.276257,-6.158576,-5.060232,0.000000
+0,1,20728,5.648631,-5.334818,-4.824872,0.000000
+0,1,20733,5.648631,-5.334818,-4.824872,0.000000
+0,1,20738,5.334818,-4.864099,-4.354153,0.000000
+0,1,20743,5.334818,-4.864099,-4.354153,0.000000
+0,1,20748,5.021005,-4.981779,-4.236473,0.000000
+0,1,20753,5.021005,-4.981779,-4.236473,0.000000
+0,1,20758,5.217138,-5.687858,-4.040340,0.000000
+0,1,20763,5.217138,-5.687858,-4.040340,0.000000
+0,1,20768,5.452498,-6.237030,-4.079566,0.000000
+0,1,20773,5.452498,-6.237030,-4.079566,0.000000
+0,1,20778,5.530951,-6.472389,-4.040340,0.000000
+0,1,20783,5.530951,-6.472389,-4.040340,0.000000
+0,1,20788,5.766310,-6.550843,-4.314926,0.000000
+0,1,20793,5.766310,-6.550843,-4.314926,0.000000
+0,1,20798,6.354709,-6.550843,-4.628739,0.000000
+0,1,20803,6.354709,-6.550843,-4.628739,0.000000
+0,1,20808,6.707749,-6.668522,-4.707192,0.000000
+0,1,20813,6.707749,-6.668522,-4.707192,0.000000
+0,1,20818,7.021562,-6.707749,-4.785645,0.000000
+0,1,20823,7.021562,-6.707749,-4.785645,0.000000
+0,1,20828,7.100015,-6.590069,-4.981779,0.000000
+0,1,20833,7.100015,-6.590069,-4.981779,0.000000
+0,1,20838,7.021562,-6.511616,-5.099459,0.000000
+0,1,20843,7.021562,-6.511616,-5.099459,0.000000
+0,1,20848,6.746975,-6.550843,-5.099459,0.000000
+0,1,20853,6.746975,-6.550843,-5.099459,0.000000
+0,1,20858,6.393936,-6.472389,-5.177911,0.000000
+0,1,20863,6.393936,-6.472389,-5.177911,0.000000
+0,1,20868,6.001670,-6.354709,-5.217138,0.000000
+0,1,20873,6.001670,-6.354709,-5.217138,0.000000
+0,1,20878,5.727084,-6.315483,-4.903325,0.000000
+0,1,20883,5.727084,-6.315483,-4.903325,0.000000
+0,1,20888,5.413271,-6.119350,-4.707192,0.000000
+0,1,20893,5.413271,-6.119350,-4.707192,0.000000
+0,1,20898,5.334818,-5.962444,-4.471833,0.000000
+0,1,20903,5.334818,-5.962444,-4.471833,0.000000
+0,1,20908,5.217138,-5.844764,-4.079566,0.000000
+0,1,20913,5.217138,-5.844764,-4.079566,0.000000
+0,1,20918,5.334818,-5.727084,-4.079566,0.000000
+0,1,20923,5.334818,-5.727084,-4.079566,0.000000
+0,1,20928,5.374045,-5.570178,-4.040340,0.000000
+0,1,20933,5.374045,-5.570178,-4.040340,0.000000
+0,1,20938,5.491724,-5.609404,-3.961887,0.000000
+0,1,20943,5.491724,-5.609404,-3.961887,0.000000
+0,1,20948,5.491724,-5.334818,-3.804980,0.000000
+0,1,20953,5.491724,-5.334818,-3.804980,0.000000
+0,1,20958,5.648631,-5.295591,-3.804980,0.000000
+0,1,20963,5.648631,-5.295591,-3.804980,0.000000
+0,1,20968,5.727084,-5.413271,-3.648074,0.000000
+0,1,20973,5.727084,-5.413271,-3.648074,0.000000
+0,1,20978,5.609404,-5.413271,-3.687301,0.000000
+0,1,20983,5.609404,-5.413271,-3.687301,0.000000
+0,1,20988,5.570178,-5.570178,-3.530394,0.000000
+0,1,20993,5.570178,-5.570178,-3.530394,0.000000
+0,1,20998,5.413271,-5.687858,-3.373488,0.000000
+0,1,21003,5.413271,-5.687858,-3.373488,0.000000
+0,1,21008,5.374045,-5.844764,-3.451941,0.000000
+0,1,21013,5.374045,-5.844764,-3.451941,0.000000
+0,1,21018,5.256365,-5.962444,-3.295035,0.000000
+0,1,21023,5.256365,-5.962444,-3.295035,0.000000
+0,1,21028,5.256365,-6.080123,-3.491168,0.000000
+0,1,21033,5.256365,-6.080123,-3.491168,0.000000
+0,1,21038,5.295591,-6.119350,-3.451941,0.000000
+0,1,21043,5.295591,-6.119350,-3.451941,0.000000
+0,1,21048,5.295591,-6.080123,-3.687301,0.000000
+0,1,21053,5.295591,-6.080123,-3.687301,0.000000
+0,1,21058,5.491724,-6.119350,-4.079566,0.000000
+0,1,21063,5.491724,-6.119350,-4.079566,0.000000
+0,1,21068,5.727084,-6.158576,-4.197247,0.000000
+0,1,21073,5.727084,-6.158576,-4.197247,0.000000
+0,1,21078,5.923217,-6.001670,-4.354153,0.000000
+0,1,21083,5.923217,-6.001670,-4.354153,0.000000
+0,1,21088,6.080123,-6.158576,-4.314926,0.000000
+0,1,21093,6.080123,-6.158576,-4.314926,0.000000
+0,1,21098,6.001670,-6.119350,-4.354153,0.000000
+0,1,21103,6.001670,-6.119350,-4.354153,0.000000
+0,1,21108,6.315483,-6.276257,-4.393379,0.000000
+0,1,21113,6.315483,-6.276257,-4.393379,0.000000
+0,1,21118,6.354709,-6.393936,-4.393379,0.000000
+0,1,21123,6.354709,-6.393936,-4.393379,0.000000
+0,1,21128,6.354709,-6.393936,-4.393379,0.000000
+0,1,21133,6.511616,-6.433163,-4.354153,0.000000
+0,1,21138,6.511616,-6.433163,-4.354153,0.000000
+0,1,21143,6.550843,-6.629296,-4.354153,0.000000
+0,1,21148,6.550843,-6.629296,-4.354153,0.000000
+0,1,21153,6.668522,-6.668522,-4.354153,0.000000
+0,1,21158,6.668522,-6.668522,-4.354153,0.000000
+0,1,21163,6.982335,-6.668522,-4.550286,0.000000
+0,1,21168,6.982335,-6.668522,-4.550286,0.000000
+0,1,21173,7.139242,-6.746975,-4.511059,0.000000
+0,1,21178,7.139242,-6.746975,-4.511059,0.000000
+0,1,21183,7.413828,-6.786202,-4.589512,0.000000
+0,1,21188,7.413828,-6.786202,-4.589512,0.000000
+0,1,21193,7.413828,-6.746975,-4.628739,0.000000
+0,1,21198,7.413828,-6.746975,-4.628739,0.000000
+0,1,21203,7.374601,-6.864655,-4.667965,0.000000
+0,1,21208,7.374601,-6.864655,-4.667965,0.000000
+0,1,21213,7.296148,-6.943109,-4.667965,0.000000
+0,1,21218,7.296148,-6.943109,-4.667965,0.000000
+0,1,21223,7.178468,-6.864655,-4.746419,0.000000
+0,1,21228,7.178468,-6.864655,-4.746419,0.000000
+0,1,21233,7.060789,-6.825429,-4.785645,0.000000
+0,1,21238,7.060789,-6.825429,-4.785645,0.000000
+0,1,21243,6.943109,-6.629296,-4.824872,0.000000
+0,1,21248,6.943109,-6.629296,-4.824872,0.000000
+0,1,21253,6.825429,-6.433163,-4.824872,0.000000
+0,1,21258,6.825429,-6.433163,-4.824872,0.000000
+0,1,21263,6.746975,-6.158576,-4.903325,0.000000
+0,1,21268,6.746975,-6.158576,-4.903325,0.000000
+0,1,21273,6.590069,-6.001670,-4.824872,0.000000
+0,1,21278,6.590069,-6.001670,-4.824872,0.000000
+0,1,21283,6.550843,-6.080123,-5.021005,0.000000
+0,1,21288,6.550843,-6.080123,-5.021005,0.000000
+0,1,21293,6.707749,-7.217695,-4.628739,0.000000
+0,1,21298,6.707749,-7.217695,-4.628739,0.000000
+0,1,21303,7.060789,-8.629852,-4.589512,0.000000
+0,1,21308,7.060789,-8.629852,-4.589512,0.000000
+0,1,21313,7.139242,-9.335931,-5.021005,0.000000
+0,1,21318,7.139242,-9.335931,-5.021005,0.000000
+0,1,21323,7.453054,-9.610518,-5.334818,0.000000
+0,1,21328,7.453054,-9.610518,-5.334818,0.000000
+0,1,21333,7.923774,-9.414385,-5.727084,0.000000
+0,1,21338,7.923774,-9.414385,-5.727084,0.000000
+0,1,21343,8.198359,-8.982892,-5.766310,0.000000
+0,1,21348,8.198359,-8.982892,-5.766310,0.000000
+0,1,21353,8.237586,-8.472946,-5.883990,0.000000
+0,1,21358,8.237586,-8.472946,-5.883990,0.000000
+0,1,21363,8.119907,-7.609961,-6.080123,0.000000
+0,1,21368,8.119907,-7.609961,-6.080123,0.000000
+0,1,21373,7.727641,-7.021562,-6.080123,0.000000
+0,1,21378,7.727641,-7.021562,-6.080123,0.000000
+0,1,21383,7.453054,-6.707749,-6.001670,0.000000
+0,1,21388,7.453054,-6.707749,-6.001670,0.000000
+0,1,21393,6.825429,-6.629296,-5.923217,0.000000
+0,1,21398,6.825429,-6.629296,-5.923217,0.000000
+0,1,21403,6.237030,-6.707749,-5.570178,0.000000
+0,1,21408,6.237030,-6.707749,-5.570178,0.000000
+0,1,21413,5.844764,-6.943109,-5.217138,0.000000
+0,1,21418,5.844764,-6.943109,-5.217138,0.000000
+0,1,21423,5.530951,-7.217695,-4.746419,0.000000
+0,1,21428,5.530951,-7.217695,-4.746419,0.000000
+0,1,21433,5.256365,-7.531507,-4.471833,0.000000
+0,1,21438,5.256365,-7.531507,-4.471833,0.000000
+0,1,21443,4.981779,-7.570734,-4.118793,0.000000
+0,1,21448,4.981779,-7.570734,-4.118793,0.000000
+0,1,21453,4.864099,-7.570734,-3.922660,0.000000
+0,1,21458,4.864099,-7.570734,-3.922660,0.000000
+0,1,21463,4.864099,-7.453054,-3.608848,0.000000
+0,1,21468,4.864099,-7.453054,-3.608848,0.000000
+0,1,21473,4.942552,-7.492281,-3.687301,0.000000
+0,1,21478,4.942552,-7.492281,-3.687301,0.000000
+0,1,21483,5.177911,-7.453054,-3.648074,0.000000
+0,1,21488,5.177911,-7.453054,-3.648074,0.000000
+0,1,21493,5.452498,-7.296148,-3.726527,0.000000
+0,1,21498,5.452498,-7.296148,-3.726527,0.000000
+0,1,21503,5.648631,-7.296148,-3.648074,0.000000
+0,1,21508,5.648631,-7.296148,-3.648074,0.000000
+0,1,21513,5.727084,-7.335374,-3.726527,0.000000
+0,1,21518,5.727084,-7.335374,-3.726527,0.000000
+0,1,21523,5.727084,-7.413828,-3.726527,0.000000
+0,1,21528,5.727084,-7.413828,-3.726527,0.000000
+0,1,21533,5.687858,-7.453054,-3.922660,0.000000
+0,1,21538,5.687858,-7.453054,-3.922660,0.000000
+0,1,21543,5.491724,-7.413828,-3.961887,0.000000
+0,1,21548,5.491724,-7.413828,-3.961887,0.000000
+0,1,21553,5.295591,-7.335374,-4.158020,0.000000
+0,1,21558,5.295591,-7.335374,-4.158020,0.000000
+0,1,21563,5.177911,-7.335374,-4.275700,0.000000
+0,1,21568,5.177911,-7.335374,-4.275700,0.000000
+0,1,21573,5.099459,-7.256921,-4.432606,0.000000
+0,1,21578,5.099459,-7.256921,-4.432606,0.000000
+0,1,21583,5.099459,-7.256921,-4.432606,0.000000
+0,1,21588,5.060232,-7.178468,-4.628739,0.000000
+0,1,21593,5.060232,-7.178468,-4.628739,0.000000
+0,1,21598,5.138685,-7.021562,-4.589512,0.000000
+0,1,21603,5.138685,-7.021562,-4.589512,0.000000
+0,1,21608,5.099459,-6.943109,-4.550286,0.000000
+0,1,21613,5.099459,-6.943109,-4.550286,0.000000
+0,1,21618,5.060232,-6.903882,-4.393379,0.000000
+0,1,21623,5.060232,-6.903882,-4.393379,0.000000
+0,1,21628,5.138685,-6.864655,-4.314926,0.000000
+0,1,21633,5.138685,-6.864655,-4.314926,0.000000
+0,1,21638,5.060232,-6.943109,-4.118793,0.000000
+0,1,21643,5.060232,-6.943109,-4.118793,0.000000
+0,1,21648,4.981779,-6.825429,-3.883434,0.000000
+0,1,21653,4.981779,-6.825429,-3.883434,0.000000
+0,1,21658,5.021005,-6.786202,-3.883434,0.000000
+0,1,21663,5.021005,-6.786202,-3.883434,0.000000
+0,1,21668,5.021005,-6.825429,-3.922660,0.000000
+0,1,21673,5.021005,-6.825429,-3.922660,0.000000
+0,1,21678,5.021005,-6.707749,-3.844207,0.000000
+0,1,21683,5.021005,-6.707749,-3.844207,0.000000
+0,1,21688,5.021005,-6.629296,-3.765754,0.000000
+0,1,21693,5.021005,-6.629296,-3.765754,0.000000
+0,1,21698,5.021005,-6.550843,-3.648074,0.000000
+0,1,21703,5.021005,-6.550843,-3.648074,0.000000
+0,1,21708,4.942552,-6.590069,-3.491168,0.000000
+0,1,21713,4.942552,-6.590069,-3.491168,0.000000
+0,1,21718,4.903325,-6.393936,-3.451941,0.000000
+0,1,21723,4.903325,-6.393936,-3.451941,0.000000
+0,1,21728,5.021005,-6.354709,-3.530394,0.000000
+0,1,21733,5.021005,-6.354709,-3.530394,0.000000
+0,1,21738,4.942552,-6.197803,-3.412714,0.000000
+0,1,21743,4.942552,-6.197803,-3.412714,0.000000
+0,1,21748,5.021005,-6.080123,-3.334261,0.000000
+0,1,21753,5.021005,-6.080123,-3.334261,0.000000
+0,1,21758,4.942552,-5.962444,-3.373488,0.000000
+0,1,21763,4.942552,-5.962444,-3.373488,0.000000
+0,1,21768,4.981779,-5.962444,-3.412714,0.000000
+0,1,21773,4.981779,-5.962444,-3.412714,0.000000
+0,1,21778,4.942552,-6.080123,-3.373488,0.000000
+0,1,21783,4.942552,-6.080123,-3.373488,0.000000
+0,1,21788,5.060232,-6.197803,-3.373488,0.000000
+0,1,21793,5.060232,-6.197803,-3.373488,0.000000
+0,1,21798,5.177911,-6.354709,-3.412714,0.000000
+0,1,21803,5.177911,-6.354709,-3.412714,0.000000
+0,1,21808,5.413271,-6.433163,-3.491168,0.000000
+0,1,21813,5.413271,-6.433163,-3.491168,0.000000
+0,1,21818,5.648631,-6.550843,-3.687301,0.000000
+0,1,21823,5.648631,-6.550843,-3.687301,0.000000
+0,1,21828,6.001670,-6.746975,-3.844207,0.000000
+0,1,21833,6.001670,-6.746975,-3.844207,0.000000
+0,1,21838,6.158576,-6.903882,-3.844207,0.000000
+0,1,21843,6.158576,-6.903882,-3.844207,0.000000
+0,1,21848,6.472389,-6.903882,-4.118793,0.000000
+0,1,21853,6.472389,-6.903882,-4.118793,0.000000
+0,1,21858,6.668522,-7.060789,-4.040340,0.000000
+0,1,21863,6.668522,-7.060789,-4.040340,0.000000
+0,1,21868,6.943109,-7.021562,-4.118793,0.000000
+0,1,21873,6.943109,-7.021562,-4.118793,0.000000
+0,1,21878,6.982335,-7.060789,-4.197247,0.000000
+0,1,21883,6.982335,-7.060789,-4.197247,0.000000
+0,1,21888,6.982335,-7.100015,-4.197247,0.000000
+0,1,21893,6.982335,-7.100015,-4.197247,0.000000
+0,1,21898,6.943109,-6.982335,-4.275700,0.000000
+0,1,21903,6.943109,-6.982335,-4.275700,0.000000
+0,1,21908,6.786202,-6.982335,-4.275700,0.000000
+0,1,21913,6.786202,-6.982335,-4.275700,0.000000
+0,1,21918,6.629296,-6.903882,-4.354153,0.000000
+0,1,21923,6.629296,-6.903882,-4.354153,0.000000
+0,1,21928,6.550843,-6.943109,-4.354153,0.000000
+0,1,21933,6.550843,-6.943109,-4.354153,0.000000
+0,1,21938,6.511616,-6.982335,-4.197247,0.000000
+0,1,21943,6.511616,-6.982335,-4.197247,0.000000
+0,1,21948,6.590069,-7.335374,-4.001113,0.000000
+0,1,21953,6.590069,-7.335374,-4.001113,0.000000
+0,1,21958,7.021562,-8.276814,-4.040340,0.000000
+0,1,21963,7.021562,-8.276814,-4.040340,0.000000
+0,1,21968,7.374601,-9.022119,-4.197247,0.000000
+0,1,21973,7.374601,-9.022119,-4.197247,0.000000
+0,1,21978,7.766868,-9.218252,-4.550286,0.000000
+0,1,21983,7.766868,-9.218252,-4.550286,0.000000
+0,1,21988,8.198359,-9.414385,-4.628739,0.000000
+0,1,21993,8.198359,-9.414385,-4.628739,0.000000
+0,1,21998,8.276814,-9.257479,-5.060232,0.000000
+0,1,22003,8.276814,-9.257479,-5.060232,0.000000
+0,1,22008,8.041453,-8.747532,-5.177911,0.000000
+0,1,22013,8.041453,-8.747532,-5.177911,0.000000
+0,1,22018,7.806094,-8.119907,-5.413271,0.000000
+0,1,22023,7.806094,-8.119907,-5.413271,0.000000
+0,1,22028,7.649188,-7.492281,-5.413271,0.000000
+0,1,22033,7.531507,-7.492281,-5.413271,0.000000
+0,1,22038,7.531507,-7.492281,-5.413271,0.000000
+0,1,22043,7.100015,-6.707749,-5.452498,0.000000
+0,1,22048,7.100015,-6.707749,-5.452498,0.000000
+0,1,22053,6.629296,-6.080123,-5.648631,0.000000
+0,1,22058,6.629296,-6.080123,-5.648631,0.000000
+0,1,22063,6.511616,-5.609404,-5.570178,0.000000
+0,1,22068,6.511616,-5.609404,-5.570178,0.000000
+0,1,22073,6.080123,-5.530951,-5.609404,0.000000
+0,1,22078,6.080123,-5.530951,-5.609404,0.000000
+0,1,22083,5.844764,-5.177911,-5.256365,0.000000
+0,1,22088,5.844764,-5.177911,-5.256365,0.000000
+0,1,22093,5.805537,-5.295591,-5.177911,0.000000
+0,1,22098,5.805537,-5.295591,-5.177911,0.000000
+0,1,22103,5.923217,-6.040897,-4.903325,0.000000
+0,1,22108,5.923217,-6.040897,-4.903325,0.000000
+0,1,22113,6.158576,-6.550843,-4.746419,0.000000
+0,1,22118,6.158576,-6.550843,-4.746419,0.000000
+0,1,22123,6.433163,-6.590069,-4.864099,0.000000
+0,1,22128,6.433163,-6.590069,-4.864099,0.000000
+0,1,22133,6.825429,-6.550843,-4.824872,0.000000
+0,1,22138,6.825429,-6.550843,-4.824872,0.000000
+0,1,22143,7.217695,-6.433163,-5.099459,0.000000
+0,1,22148,7.217695,-6.433163,-5.099459,0.000000
+0,1,22153,7.609961,-6.197803,-5.256365,0.000000
+0,1,22158,7.609961,-6.197803,-5.256365,0.000000
+0,1,22163,7.649188,-6.080123,-5.060232,0.000000
+0,1,22168,7.649188,-6.080123,-5.060232,0.000000
+0,1,22173,7.531507,-5.805537,-5.217138,0.000000
+0,1,22178,7.531507,-5.805537,-5.217138,0.000000
+0,1,22183,7.374601,-5.805537,-5.256365,0.000000
+0,1,22188,7.374601,-5.805537,-5.256365,0.000000
+0,1,22193,6.864655,-5.962444,-5.177911,0.000000
+0,1,22198,6.864655,-5.962444,-5.177911,0.000000
+0,1,22203,6.393936,-5.962444,-5.138685,0.000000
+0,1,22208,6.393936,-5.962444,-5.138685,0.000000
+0,1,22213,5.883990,-5.844764,-4.942552,0.000000
+0,1,22218,5.883990,-5.844764,-4.942552,0.000000
+0,1,22223,5.452498,-5.923217,-4.628739,0.000000
+0,1,22228,5.452498,-5.923217,-4.628739,0.000000
+0,1,22233,5.060232,-5.883990,-4.354153,0.000000
+0,1,22238,5.060232,-5.883990,-4.354153,0.000000
+0,1,22243,4.824872,-5.844764,-4.275700,0.000000
+0,1,22248,4.824872,-5.844764,-4.275700,0.000000
+0,1,22253,4.746419,-5.727084,-4.158020,0.000000
+0,1,22258,4.746419,-5.727084,-4.158020,0.000000
+0,1,22263,4.707192,-5.609404,-4.040340,0.000000
+0,1,22268,4.707192,-5.609404,-4.040340,0.000000
+0,1,22273,4.746419,-5.491724,-3.961887,0.000000
+0,1,22278,4.746419,-5.491724,-3.961887,0.000000
+0,1,22283,4.824872,-5.334818,-3.765754,0.000000
+0,1,22288,4.824872,-5.334818,-3.765754,0.000000
+0,1,22293,4.942552,-5.295591,-3.804980,0.000000
+0,1,22298,4.942552,-5.295591,-3.804980,0.000000
+0,1,22303,5.099459,-5.256365,-3.765754,0.000000
+0,1,22308,5.099459,-5.256365,-3.765754,0.000000
+0,1,22313,5.138685,-5.334818,-3.608848,0.000000
+0,1,22318,5.138685,-5.334818,-3.608848,0.000000
+0,1,22323,5.099459,-5.256365,-3.530394,0.000000
+0,1,22328,5.099459,-5.256365,-3.530394,0.000000
+0,1,22333,5.099459,-5.295591,-3.530394,0.000000
+0,1,22338,5.099459,-5.295591,-3.530394,0.000000
+0,1,22343,5.138685,-5.491724,-3.648074,0.000000
+0,1,22348,5.138685,-5.491724,-3.648074,0.000000
+0,1,22353,5.256365,-5.648631,-3.765754,0.000000
+0,1,22358,5.256365,-5.648631,-3.765754,0.000000
+0,1,22363,5.374045,-5.687858,-3.726527,0.000000
+0,1,22368,5.374045,-5.687858,-3.726527,0.000000
+0,1,22373,5.530951,-5.727084,-3.922660,0.000000
+0,1,22378,5.530951,-5.727084,-3.922660,0.000000
+0,1,22383,5.648631,-5.648631,-4.040340,0.000000
+0,1,22388,5.648631,-5.648631,-4.040340,0.000000
+0,1,22393,5.687858,-5.570178,-4.040340,0.000000
+0,1,22398,5.687858,-5.570178,-4.040340,0.000000
+0,1,22403,5.766310,-5.491724,-4.158020,0.000000
+0,1,22408,5.766310,-5.491724,-4.158020,0.000000
+0,1,22413,5.923217,-5.648631,-4.354153,0.000000
+0,1,22418,5.923217,-5.648631,-4.354153,0.000000
+0,1,22423,6.197803,-5.766310,-4.471833,0.000000
+0,1,22428,6.197803,-5.766310,-4.471833,0.000000
+0,1,22433,6.393936,-5.805537,-4.667965,0.000000
+0,1,22438,6.393936,-5.805537,-4.667965,0.000000
+0,1,22443,6.590069,-5.962444,-4.746419,0.000000
+0,1,22448,6.590069,-5.962444,-4.746419,0.000000
+0,1,22453,6.903882,-6.315483,-4.746419,0.000000
+0,1,22458,6.903882,-6.315483,-4.746419,0.000000
+0,1,22463,7.374601,-6.511616,-4.864099,0.000000
+0,1,22468,7.374601,-6.511616,-4.864099,0.000000
+0,1,22473,7.649188,-6.825429,-4.903325,0.000000
+0,1,22478,7.649188,-6.825429,-4.903325,0.000000
+0,1,22483,7.649188,-6.825429,-4.903325,0.000000
+0,1,22488,7.923774,-6.943109,-5.021005,0.000000
+0,1,22493,7.923774,-6.943109,-5.021005,0.000000
+0,1,22498,8.041453,-6.746975,-5.099459,0.000000
+0,1,22503,8.041453,-6.746975,-5.099459,0.000000
+0,1,22508,8.512173,-7.139242,-5.217138,0.000000
+0,1,22513,8.512173,-7.139242,-5.217138,0.000000
+0,1,22518,8.551399,-7.100015,-5.256365,0.000000
+0,1,22523,8.551399,-7.100015,-5.256365,0.000000
+0,1,22528,8.629852,-6.982335,-5.452498,0.000000
+0,1,22533,8.629852,-6.982335,-5.452498,0.000000
+0,1,22538,8.786758,-7.256921,-5.256365,0.000000
+0,1,22543,8.786758,-7.256921,-5.256365,0.000000
+0,1,22548,8.472946,-7.178468,-5.217138,0.000000
+0,1,22553,8.472946,-7.178468,-5.217138,0.000000
+0,1,22558,8.080680,-7.021562,-5.060232,0.000000
+0,1,22563,8.080680,-7.021562,-5.060232,0.000000
+0,1,22568,7.649188,-7.021562,-4.746419,0.000000
+0,1,22573,7.649188,-7.021562,-4.746419,0.000000
+0,1,22578,7.296148,-7.413828,-4.550286,0.000000
+0,1,22583,7.296148,-7.413828,-4.550286,0.000000
+0,1,22588,7.413828,-8.080680,-4.550286,0.000000
+0,1,22593,7.413828,-8.080680,-4.550286,0.000000
+0,1,22598,7.256921,-8.551399,-4.354153,0.000000
+0,1,22603,7.256921,-8.551399,-4.354153,0.000000
+0,1,22608,6.903882,-8.512173,-4.158020,0.000000
+0,1,22613,6.903882,-8.512173,-4.158020,0.000000
+0,1,22618,6.903882,-8.433720,-4.707192,0.000000
+0,1,22623,6.903882,-8.433720,-4.707192,0.000000
+0,1,22628,7.021562,-8.276814,-4.667965,0.000000
+0,1,22633,7.021562,-8.276814,-4.667965,0.000000
+0,1,22638,6.864655,-7.688414,-4.314926,0.000000
+0,1,22643,6.864655,-7.688414,-4.314926,0.000000
+0,1,22648,6.982335,-7.492281,-4.197247,0.000000
+0,1,22653,6.982335,-7.492281,-4.197247,0.000000
+0,1,22658,6.746975,-7.374601,-4.707192,0.000000
+0,1,22663,6.746975,-7.374601,-4.707192,0.000000
+0,1,22668,6.825429,-7.296148,-4.275700,0.000000
+0,1,22673,6.825429,-7.296148,-4.275700,0.000000
+0,1,22678,6.354709,-7.021562,-3.765754,0.000000
+0,1,22683,6.354709,-7.021562,-3.765754,0.000000
+0,1,22688,6.433163,-7.139242,-3.844207,0.000000
+0,1,22693,6.433163,-7.139242,-3.844207,0.000000
+0,1,22698,5.766310,-7.374601,-4.432606,0.000000
+0,1,22703,5.766310,-7.374601,-4.432606,0.000000
+0,1,22708,5.805537,-6.903882,-3.412714,0.000000
+0,1,22713,5.805537,-6.903882,-3.412714,0.000000
+0,1,22718,4.785645,-6.746975,-4.785645,0.000000
+0,1,22723,4.785645,-6.746975,-4.785645,0.000000
+0,1,22728,5.177911,-7.570734,-4.393379,0.000000
+0,1,22733,5.177911,-7.570734,-4.393379,0.000000
+0,1,22738,4.981779,-7.335374,-3.569621,0.000000
+0,1,22743,4.981779,-7.335374,-3.569621,0.000000
+0,1,22748,5.295591,-7.217695,-3.726527,0.000000
+0,1,22753,5.295591,-7.217695,-3.726527,0.000000
+0,1,22758,5.099459,-7.256921,-3.844207,0.000000
+0,1,22763,5.099459,-7.256921,-3.844207,0.000000
+0,1,22768,5.021005,-7.256921,-3.765754,0.000000
+0,1,22773,5.021005,-7.256921,-3.765754,0.000000
+0,1,22778,5.021005,-7.413828,-3.765754,0.000000
+0,1,22783,5.021005,-7.413828,-3.765754,0.000000
+0,1,22788,4.903325,-7.570734,-3.961887,0.000000
+0,1,22793,4.903325,-7.570734,-3.961887,0.000000
+0,1,22798,4.667965,-7.649188,-4.314926,0.000000
+0,1,22803,4.667965,-7.649188,-4.314926,0.000000
+0,1,22808,5.334818,-7.806094,-3.844207,0.000000
+0,1,22813,5.334818,-7.806094,-3.844207,0.000000
+0,1,22818,4.667965,-7.649188,-4.118793,0.000000
+0,1,22823,4.667965,-7.649188,-4.118793,0.000000
+0,1,22828,4.746419,-7.492281,-3.922660,0.000000
+0,1,22833,4.746419,-7.492281,-3.922660,0.000000
+0,1,22838,4.511059,-7.178468,-4.275700,0.000000
+0,1,22843,4.511059,-7.178468,-4.275700,0.000000
+0,1,22848,4.903325,-7.374601,-4.432606,0.000000
+0,1,22853,4.903325,-7.374601,-4.432606,0.000000
+0,1,22858,4.864099,-7.139242,-4.589512,0.000000
+0,1,22863,4.864099,-7.139242,-4.589512,0.000000
+0,1,22868,4.785645,-6.943109,-4.785645,0.000000
+0,1,22873,4.785645,-6.943109,-4.785645,0.000000
+0,1,22878,4.785645,-6.707749,-4.667965,0.000000
+0,1,22883,4.785645,-6.707749,-4.667965,0.000000
+0,1,22888,4.864099,-6.590069,-4.746419,0.000000
+0,1,22893,4.864099,-6.590069,-4.746419,0.000000
+0,1,22898,4.864099,-6.590069,-4.746419,0.000000
+0,1,22903,4.864099,-6.590069,-4.746419,0.000000
+0,1,22908,4.785645,-6.550843,-4.746419,0.000000
+0,1,22913,4.785645,-6.550843,-4.746419,0.000000
+0,1,22918,4.589512,-6.629296,-4.550286,0.000000
+0,1,22923,4.589512,-6.629296,-4.550286,0.000000
+0,1,22928,4.628739,-6.668522,-4.471833,0.000000
+0,1,22933,4.628739,-6.668522,-4.471833,0.000000
+0,1,22938,4.628739,-6.668522,-4.158020,0.000000
+0,1,22943,4.550286,-6.668522,-4.197247,0.000000
+0,1,22948,4.550286,-6.668522,-4.197247,0.000000
+0,1,22953,4.550286,-6.668522,-4.079566,0.000000
+0,1,22958,4.550286,-6.668522,-4.079566,0.000000
+0,1,22963,4.746419,-6.707749,-3.922660,0.000000
+0,1,22968,4.746419,-6.707749,-3.922660,0.000000
+0,1,22973,4.903325,-6.786202,-4.040340,0.000000
+0,1,22978,4.903325,-6.786202,-4.040340,0.000000
+0,1,22983,5.256365,-6.786202,-4.158020,0.000000
+0,1,22988,5.256365,-6.786202,-4.158020,0.000000
+0,1,22993,5.452498,-6.825429,-4.236473,0.000000
+0,1,22998,5.452498,-6.825429,-4.236473,0.000000
+0,1,23003,5.491724,-6.746975,-4.197247,0.000000
+0,1,23013,5.570178,-6.668522,-4.197247,0.000000
+0,1,23018,5.570178,-6.668522,-4.197247,0.000000
+0,1,23023,5.648631,-6.629296,-4.236473,0.000000
+0,1,23028,5.648631,-6.629296,-4.236473,0.000000
+0,1,23033,5.687858,-6.629296,-4.354153,0.000000
+0,1,23038,5.687858,-6.629296,-4.354153,0.000000
+0,1,23043,5.687858,-6.511616,-4.432606,0.000000
+0,1,23048,5.687858,-6.511616,-4.432606,0.000000
+0,1,23053,5.648631,-6.511616,-4.432606,0.000000
+0,1,23058,5.648631,-6.511616,-4.432606,0.000000
+0,1,23063,5.727084,-6.590069,-4.511059,0.000000
+0,1,23068,5.727084,-6.590069,-4.511059,0.000000
+0,1,23073,6.001670,-6.786202,-4.785645,0.000000
+0,1,23078,6.001670,-6.786202,-4.785645,0.000000
+0,1,23083,6.276257,-6.943109,-4.981779,0.000000
+0,1,23088,6.276257,-6.943109,-4.981779,0.000000
+0,1,23093,6.433163,-6.864655,-5.021005,0.000000
+0,1,23098,6.433163,-6.864655,-5.021005,0.000000
+0,1,23103,6.746975,-6.943109,-5.021005,0.000000
+0,1,23108,6.746975,-6.943109,-5.021005,0.000000
+0,1,23113,7.021562,-7.021562,-5.021005,0.000000
+0,1,23118,7.021562,-7.021562,-5.021005,0.000000
+0,1,23123,7.178468,-6.943109,-5.138685,0.000000
+0,1,23128,7.178468,-6.943109,-5.138685,0.000000
+0,1,23133,7.335374,-7.100015,-5.256365,0.000000
+0,1,23138,7.335374,-7.100015,-5.256365,0.000000
+0,1,23143,7.217695,-7.021562,-5.334818,0.000000
+0,1,23148,7.217695,-7.021562,-5.334818,0.000000
+0,1,23153,7.021562,-7.060789,-5.374045,0.000000
+0,1,23158,7.021562,-7.060789,-5.374045,0.000000
+0,1,23163,6.786202,-7.100015,-5.491724,0.000000
+0,1,23168,6.786202,-7.100015,-5.491724,0.000000
+0,1,23173,6.472389,-7.256921,-5.609404,0.000000
+0,1,23178,6.472389,-7.256921,-5.609404,0.000000
+0,1,23183,6.040897,-7.413828,-5.452498,0.000000
+0,1,23188,6.040897,-7.413828,-5.452498,0.000000
+0,1,23193,6.001670,-8.002227,-5.374045,0.000000
+0,1,23198,6.001670,-8.002227,-5.374045,0.000000
+0,1,23203,6.393936,-8.982892,-5.177911,0.000000
+0,1,23208,6.393936,-8.982892,-5.177911,0.000000
+0,1,23213,6.707749,-9.688971,-5.256365,0.000000
+0,1,23218,6.707749,-9.688971,-5.256365,0.000000
+0,1,23223,7.021562,-9.806650,-5.334818,0.000000
+0,1,23228,7.021562,-9.806650,-5.334818,0.000000
+0,1,23233,7.256921,-9.728197,-5.374045,0.000000
+0,1,23238,7.256921,-9.728197,-5.374045,0.000000
+0,1,23243,7.139242,-9.492838,-5.334818,0.000000
+0,1,23248,7.139242,-9.492838,-5.334818,0.000000
+0,1,23253,6.746975,-8.865212,-5.334818,0.000000
+0,1,23258,6.746975,-8.865212,-5.334818,0.000000
+0,1,23263,6.276257,-8.316040,-5.334818,0.000000
+0,1,23268,6.276257,-8.316040,-5.334818,0.000000
+0,1,23273,5.962444,-7.766868,-5.334818,0.000000
+0,1,23278,5.962444,-7.766868,-5.334818,0.000000
+0,1,23283,5.609404,-7.021562,-5.217138,0.000000
+0,1,23288,5.609404,-7.021562,-5.217138,0.000000
+0,1,23293,5.413271,-6.354709,-4.903325,0.000000
+0,1,23298,5.413271,-6.354709,-4.903325,0.000000
+0,1,23303,5.256365,-5.844764,-4.824872,0.000000
+0,1,23308,5.256365,-5.844764,-4.824872,0.000000
+0,1,23313,5.177911,-5.727084,-4.314926,0.000000
+0,1,23318,5.177911,-5.727084,-4.314926,0.000000
+0,1,23323,5.138685,-5.766310,-4.001113,0.000000
+0,1,23328,5.138685,-5.766310,-4.001113,0.000000
+0,1,23333,5.295591,-5.962444,-3.883434,0.000000
+0,1,23338,5.295591,-5.962444,-3.883434,0.000000
+0,1,23343,5.491724,-6.119350,-3.726527,0.000000
+0,1,23348,5.491724,-6.119350,-3.726527,0.000000
+0,1,23353,5.844764,-6.197803,-3.804980,0.000000
+0,1,23358,5.844764,-6.197803,-3.804980,0.000000
+0,1,23363,6.158576,-6.354709,-3.648074,0.000000
+0,1,23368,6.158576,-6.354709,-3.648074,0.000000
+0,1,23373,6.433163,-6.393936,-3.648074,0.000000
+0,1,23378,6.433163,-6.393936,-3.648074,0.000000
+0,1,23383,6.786202,-6.472389,-3.608848,0.000000
+0,1,23388,6.786202,-6.472389,-3.608848,0.000000
+0,1,23393,6.786202,-6.472389,-3.608848,0.000000
+0,1,23398,7.100015,-6.315483,-3.412714,0.000000
+0,1,23403,7.100015,-6.315483,-3.412714,0.000000
+0,1,23408,7.413828,-6.237030,-3.569621,0.000000
+0,1,23413,7.413828,-6.237030,-3.569621,0.000000
+0,1,23418,7.413828,-6.080123,-3.608848,0.000000
+0,1,23423,7.413828,-6.080123,-3.608848,0.000000
+0,1,23428,7.335374,-6.001670,-3.648074,0.000000
+0,1,23433,7.335374,-6.001670,-3.648074,0.000000
+0,1,23438,7.256921,-5.962444,-3.765754,0.000000
+0,1,23443,7.256921,-5.962444,-3.765754,0.000000
+0,1,23448,6.903882,-5.962444,-3.804980,0.000000
+0,1,23453,6.903882,-5.962444,-3.804980,0.000000
+0,1,23458,6.550843,-5.923217,-3.765754,0.000000
+0,1,23463,6.550843,-5.923217,-3.765754,0.000000
+0,1,23468,6.158576,-5.844764,-3.608848,0.000000
+0,1,23473,6.158576,-5.844764,-3.608848,0.000000
+0,1,23478,5.844764,-5.805537,-3.530394,0.000000
+0,1,23483,5.844764,-5.805537,-3.530394,0.000000
+0,1,23488,5.570178,-5.883990,-3.451941,0.000000
+0,1,23493,5.570178,-5.883990,-3.451941,0.000000
+0,1,23498,5.256365,-5.805537,-3.295035,0.000000
+0,1,23503,5.256365,-5.805537,-3.295035,0.000000
+0,1,23508,5.177911,-5.766310,-3.255808,0.000000
+0,1,23513,5.177911,-5.766310,-3.255808,0.000000
+0,1,23518,5.138685,-5.766310,-3.138128,0.000000
+0,1,23523,5.138685,-5.766310,-3.138128,0.000000
+0,1,23528,5.021005,-5.687858,-3.216581,0.000000
+0,1,23533,5.021005,-5.687858,-3.216581,0.000000
+0,1,23538,5.021005,-5.727084,-3.138128,0.000000
+0,1,23543,5.021005,-5.727084,-3.138128,0.000000
+0,1,23548,5.099459,-5.648631,-3.295035,0.000000
+0,1,23553,5.099459,-5.648631,-3.295035,0.000000
+0,1,23558,5.060232,-5.923217,-3.098902,0.000000
+0,1,23563,5.060232,-5.923217,-3.098902,0.000000
+0,1,23568,5.177911,-5.687858,-3.295035,0.000000
+0,1,23573,5.177911,-5.687858,-3.295035,0.000000
+0,1,23578,5.099459,-5.766310,-3.098902,0.000000
+0,1,23583,5.099459,-5.766310,-3.098902,0.000000
+0,1,23588,5.060232,-5.805537,-3.138128,0.000000
+0,1,23593,5.060232,-5.805537,-3.138128,0.000000
+0,1,23598,5.099459,-5.805537,-3.255808,0.000000
+0,1,23603,5.099459,-5.805537,-3.255808,0.000000
+0,1,23608,5.217138,-5.844764,-3.412714,0.000000
+0,1,23613,5.217138,-5.844764,-3.412714,0.000000
+0,1,23618,5.334818,-5.648631,-3.569621,0.000000
+0,1,23623,5.334818,-5.648631,-3.569621,0.000000
+0,1,23628,5.334818,-5.530951,-3.726527,0.000000
+0,1,23633,5.334818,-5.530951,-3.726527,0.000000
+0,1,23638,5.452498,-5.374045,-4.040340,0.000000
+0,1,23643,5.452498,-5.374045,-4.040340,0.000000
+0,1,23648,5.609404,-5.374045,-4.197247,0.000000
+0,1,23653,5.609404,-5.374045,-4.197247,0.000000
+0,1,23658,5.844764,-5.413271,-4.158020,0.000000
+0,1,23663,5.844764,-5.413271,-4.158020,0.000000
+0,1,23668,6.119350,-5.374045,-4.432606,0.000000
+0,1,23673,6.119350,-5.374045,-4.432606,0.000000
+0,1,23678,6.237030,-5.452498,-4.589512,0.000000
+0,1,23683,6.237030,-5.452498,-4.589512,0.000000
+0,1,23688,6.629296,-5.570178,-4.511059,0.000000
+0,1,23693,6.629296,-5.570178,-4.511059,0.000000
+0,1,23698,6.864655,-5.609404,-4.589512,0.000000
+0,1,23703,6.864655,-5.609404,-4.589512,0.000000
+0,1,23708,7.100015,-5.687858,-4.589512,0.000000
+0,1,23713,7.100015,-5.687858,-4.589512,0.000000
+0,1,23718,7.296148,-5.766310,-4.707192,0.000000
+0,1,23723,7.296148,-5.766310,-4.707192,0.000000
+0,1,23728,7.531507,-5.883990,-4.667965,0.000000
+0,1,23733,7.531507,-5.883990,-4.667965,0.000000
+0,1,23738,8.159133,-5.099459,-4.079566,0.000000
+0,1,23743,8.159133,-5.099459,-4.079566,0.000000
+0,1,23748,7.923774,-5.844764,-4.942552,0.000000
+0,1,23753,7.923774,-5.844764,-4.942552,0.000000
+0,1,23758,8.394493,-5.962444,-5.138685,0.000000
+0,1,23763,8.394493,-5.962444,-5.138685,0.000000
+0,1,23768,8.276814,-5.883990,-5.256365,0.000000
+0,1,23773,8.276814,-5.883990,-5.256365,0.000000
+0,1,23778,8.276814,-5.883990,-5.374045,0.000000
+0,1,23783,8.276814,-5.883990,-5.374045,0.000000
+0,1,23788,8.119907,-5.766310,-5.687858,0.000000
+0,1,23793,8.119907,-5.766310,-5.687858,0.000000
+0,1,23798,7.884547,-5.844764,-5.844764,0.000000
+0,1,23803,7.884547,-5.844764,-5.844764,0.000000
+0,1,23808,7.766868,-5.883990,-5.805537,0.000000
+0,1,23813,7.766868,-5.883990,-5.805537,0.000000
+0,1,23818,7.570734,-6.354709,-5.727084,0.000000
+0,1,23823,7.570734,-6.354709,-5.727084,0.000000
+0,1,23828,7.649188,-7.531507,-5.530951,0.000000
+0,1,23833,7.649188,-7.531507,-5.530951,0.000000
+0,1,23838,7.649188,-7.531507,-5.687858,0.000000
+0,1,23843,7.649188,-8.237586,-5.727084,0.000000
+0,1,23848,7.649188,-8.237586,-5.727084,0.000000
+0,1,23853,7.531507,-8.080680,-5.687858,0.000000
+0,1,23858,7.531507,-8.080680,-5.687858,0.000000
+0,1,23863,7.531507,-8.237586,-5.452498,0.000000
+0,1,23868,7.531507,-8.237586,-5.452498,0.000000
+0,1,23873,7.609961,-8.119907,-6.315483,0.000000
+0,1,23878,7.609961,-8.119907,-6.315483,0.000000
+0,1,23883,8.002227,-8.080680,-6.197803,0.000000
+0,1,23888,8.002227,-8.080680,-6.197803,0.000000
+0,1,23893,8.080680,-7.727641,-6.511616,0.000000
+0,1,23898,8.080680,-7.727641,-6.511616,0.000000
+0,1,23903,7.923774,-7.570734,-6.315483,0.000000
+0,1,23908,7.923774,-7.570734,-6.315483,0.000000
+0,1,23913,7.531507,-6.982335,-6.550843,0.000000
+0,1,23918,7.531507,-6.982335,-6.550843,0.000000
+0,1,23923,7.453054,-6.864655,-6.746975,0.000000
+0,1,23928,7.453054,-6.864655,-6.746975,0.000000
+0,1,23933,7.256921,-6.590069,-6.707749,0.000000
+0,1,23938,7.256921,-6.590069,-6.707749,0.000000
+0,1,23943,6.707749,-6.276257,-6.393936,0.000000
+0,1,23948,6.707749,-6.276257,-6.393936,0.000000
+0,1,23953,6.237030,-6.080123,-5.962444,0.000000
+0,1,23958,6.237030,-6.080123,-5.962444,0.000000
+0,1,23963,5.844764,-6.354709,-5.491724,0.000000
+0,1,23968,5.844764,-6.354709,-5.491724,0.000000
+0,1,23973,5.530951,-6.511616,-5.138685,0.000000
+0,1,23978,5.530951,-6.511616,-5.138685,0.000000
+0,1,23983,5.217138,-6.590069,-4.746419,0.000000
+0,1,23988,5.217138,-6.590069,-4.746419,0.000000
+0,1,23993,4.942552,-6.668522,-4.511059,0.000000
+0,1,23998,4.942552,-6.668522,-4.511059,0.000000
+0,1,24003,4.707192,-6.668522,-4.471833,0.000000
+0,1,24008,4.707192,-6.668522,-4.471833,0.000000
+0,1,24013,4.667965,-6.746975,-4.354153,0.000000
+0,1,24018,4.667965,-6.746975,-4.354153,0.000000
+0,1,24023,4.707192,-6.786202,-4.236473,0.000000
+0,1,24028,4.707192,-6.786202,-4.236473,0.000000
+0,1,24033,4.746419,-6.629296,-4.275700,0.000000
+0,1,24038,4.746419,-6.629296,-4.275700,0.000000
+0,1,24043,4.824872,-6.590069,-4.275700,0.000000
+0,1,24048,4.824872,-6.590069,-4.275700,0.000000
+0,1,24053,4.824872,-6.590069,-4.275700,0.000000
+0,1,24058,4.824872,-6.590069,-4.275700,0.000000
+0,1,24063,4.903325,-6.590069,-4.354153,0.000000
+0,1,24068,4.903325,-6.590069,-4.354153,0.000000
+0,1,24073,4.903325,-6.511616,-4.550286,0.000000
+0,1,24078,4.903325,-6.511616,-4.550286,0.000000
+0,1,24083,5.021005,-6.433163,-4.746419,0.000000
+0,1,24088,5.021005,-6.433163,-4.746419,0.000000
+0,1,24093,5.099459,-6.354709,-4.864099,0.000000
+0,1,24098,5.099459,-6.354709,-4.864099,0.000000
+0,1,24103,5.177911,-6.197803,-5.021005,0.000000
+0,1,24108,5.177911,-6.197803,-5.021005,0.000000
+0,1,24113,5.099459,-6.158576,-5.099459,0.000000
+0,1,24118,5.099459,-6.158576,-5.099459,0.000000
+0,1,24123,5.060232,-6.119350,-5.099459,0.000000
+0,1,24128,5.060232,-6.119350,-5.099459,0.000000
+0,1,24133,5.217138,-6.080123,-5.138685,0.000000
+0,1,24138,5.217138,-6.080123,-5.138685,0.000000
+0,1,24143,5.256365,-6.040897,-4.981779,0.000000
+0,1,24148,5.256365,-6.040897,-4.981779,0.000000
+0,1,24153,5.374045,-6.080123,-4.942552,0.000000
+0,1,24158,5.374045,-6.080123,-4.942552,0.000000
+0,1,24163,5.491724,-6.080123,-4.864099,0.000000
+0,1,24168,5.491724,-6.080123,-4.864099,0.000000
+0,1,24173,5.570178,-6.197803,-4.707192,0.000000
+0,1,24178,5.570178,-6.197803,-4.707192,0.000000
+0,1,24183,5.530951,-6.158576,-4.511059,0.000000
+0,1,24188,5.530951,-6.158576,-4.511059,0.000000
+0,1,24193,5.452498,-6.237030,-4.275700,0.000000
+0,1,24198,5.452498,-6.237030,-4.275700,0.000000
+0,1,24203,5.727084,-6.315483,-4.314926,0.000000
+0,1,24208,5.727084,-6.315483,-4.314926,0.000000
+0,1,24213,5.805537,-6.393936,-4.275700,0.000000
+0,1,24218,5.805537,-6.393936,-4.275700,0.000000
+0,1,24223,5.883990,-6.511616,-4.236473,0.000000
+0,1,24228,5.883990,-6.511616,-4.236473,0.000000
+0,1,24233,5.923217,-6.511616,-4.158020,0.000000
+0,1,24238,5.923217,-6.511616,-4.158020,0.000000
+0,1,24243,5.805537,-6.354709,-4.079566,0.000000
+0,1,24248,5.805537,-6.354709,-4.079566,0.000000
+0,1,24253,5.805537,-6.433163,-4.001113,0.000000
+0,1,24258,5.805537,-6.433163,-4.001113,0.000000
+0,1,24263,5.844764,-6.433163,-3.765754,0.000000
+0,1,24268,5.844764,-6.433163,-3.765754,0.000000
+0,1,24273,5.844764,-6.472389,-3.648074,0.000000
+0,1,24278,5.844764,-6.472389,-3.648074,0.000000
+0,1,24283,5.727084,-6.433163,-3.569621,0.000000
+0,1,24288,5.727084,-6.433163,-3.569621,0.000000
+0,1,24293,5.727084,-6.433163,-3.569621,0.000000
+0,1,24298,5.727084,-6.393936,-3.412714,0.000000
+0,1,24303,5.727084,-6.393936,-3.412714,0.000000
+0,1,24308,5.648631,-6.354709,-3.412714,0.000000
+0,1,24313,5.648631,-6.354709,-3.412714,0.000000
+0,1,24318,5.609404,-6.393936,-3.373488,0.000000
+0,1,24323,5.609404,-6.393936,-3.373488,0.000000
+0,1,24328,5.530951,-6.472389,-3.412714,0.000000
+0,1,24333,5.530951,-6.472389,-3.412714,0.000000
+0,1,24338,5.609404,-6.511616,-3.451941,0.000000
+0,1,24343,5.609404,-6.511616,-3.451941,0.000000
+0,1,24348,5.727084,-6.550843,-3.451941,0.000000
+0,1,24353,5.727084,-6.550843,-3.451941,0.000000
+0,1,24358,5.766310,-6.511616,-3.491168,0.000000
+0,1,24363,5.766310,-6.511616,-3.491168,0.000000
+0,1,24368,5.844764,-6.590069,-3.491168,0.000000
+0,1,24373,5.844764,-6.590069,-3.491168,0.000000
+0,1,24378,5.844764,-6.668522,-3.451941,0.000000
+0,1,24383,5.844764,-6.668522,-3.451941,0.000000
+0,1,24388,5.962444,-6.707749,-3.569621,0.000000
+0,1,24393,5.962444,-6.707749,-3.569621,0.000000
+0,1,24398,6.001670,-6.903882,-3.451941,0.000000
+0,1,24403,6.001670,-6.903882,-3.451941,0.000000
+0,1,24408,6.276257,-6.864655,-3.569621,0.000000
+0,1,24413,6.276257,-6.864655,-3.569621,0.000000
+0,1,24418,6.315483,-7.060789,-3.451941,0.000000
+0,1,24423,6.315483,-7.060789,-3.451941,0.000000
+0,1,24428,6.511616,-7.100015,-3.687301,0.000000
+0,1,24433,6.511616,-7.100015,-3.687301,0.000000
+0,1,24438,6.433163,-7.100015,-3.804980,0.000000
+0,1,24443,6.433163,-7.100015,-3.804980,0.000000
+0,1,24448,6.629296,-7.413828,-3.765754,0.000000
+0,1,24453,6.629296,-7.413828,-3.765754,0.000000
+0,1,24458,6.707749,-7.492281,-3.961887,0.000000
+0,1,24463,6.707749,-7.492281,-3.961887,0.000000
+0,1,24468,6.786202,-7.413828,-4.001113,0.000000
+0,1,24473,6.786202,-7.413828,-4.001113,0.000000
+0,1,24478,6.825429,-7.453054,-4.040340,0.000000
+0,1,24483,6.825429,-7.453054,-4.040340,0.000000
+0,1,24488,6.825429,-7.413828,-4.079566,0.000000
+0,1,24493,6.825429,-7.413828,-4.079566,0.000000
+0,1,24498,6.786202,-7.453054,-4.079566,0.000000
+0,1,24503,6.786202,-7.453054,-4.079566,0.000000
+0,1,24508,6.707749,-7.570734,-4.079566,0.000000
+0,1,24513,6.707749,-7.570734,-4.079566,0.000000
+0,1,24518,6.943109,-8.316040,-4.040340,0.000000
+0,1,24523,6.943109,-8.316040,-4.040340,0.000000
+0,1,24528,6.668522,-8.786758,-4.589512,0.000000
+0,1,24533,6.668522,-8.786758,-4.589512,0.000000
+0,1,24538,7.453054,-9.375158,-4.707192,0.000000
+0,1,24543,7.453054,-9.375158,-4.707192,0.000000
+0,1,24548,8.080680,-9.688971,-4.942552,0.000000
+0,1,24553,8.080680,-9.688971,-4.942552,0.000000
+0,1,24558,8.394493,-9.767424,-5.138685,0.000000
+0,1,24563,8.394493,-9.767424,-5.138685,0.000000
+0,1,24568,8.472946,-8.943666,-5.138685,0.000000
+0,1,24573,8.472946,-8.943666,-5.138685,0.000000
+0,1,24578,8.002227,-7.963000,-5.256365,0.000000
+0,1,24583,8.002227,-7.963000,-5.256365,0.000000
+0,1,24588,7.845320,-7.413828,-5.177911,0.000000
+0,1,24593,7.845320,-7.413828,-5.177911,0.000000
+0,1,24598,7.884547,-7.178468,-5.295591,0.000000
+0,1,24603,7.884547,-7.178468,-5.295591,0.000000
+0,1,24608,7.845320,-7.021562,-5.491724,0.000000
+0,1,24613,7.845320,-7.021562,-5.491724,0.000000
+0,1,24618,7.492281,-6.472389,-5.334818,0.000000
+0,1,24623,7.492281,-6.472389,-5.334818,0.000000
+0,1,24628,7.217695,-6.119350,-5.256365,0.000000
+0,1,24633,7.217695,-6.119350,-5.256365,0.000000
+0,1,24638,6.943109,-5.609404,-5.217138,0.000000
+0,1,24643,6.943109,-5.609404,-5.217138,0.000000
+0,1,24648,6.707749,-5.099459,-4.746419,0.000000
+0,1,24653,6.707749,-5.099459,-4.746419,0.000000
+0,1,24658,6.629296,-5.138685,-4.785645,0.000000
+0,1,24663,6.629296,-5.138685,-4.785645,0.000000
+0,1,24668,6.707749,-5.570178,-4.667965,0.000000
+0,1,24673,6.707749,-5.570178,-4.667965,0.000000
+0,1,24678,6.668522,-5.883990,-4.707192,0.000000
+0,1,24683,6.668522,-5.883990,-4.707192,0.000000
+0,1,24688,6.550843,-6.315483,-4.942552,0.000000
+0,1,24693,6.550843,-6.315483,-4.942552,0.000000
+0,1,24698,6.707749,-6.590069,-5.060232,0.000000
+0,1,24703,6.707749,-6.590069,-5.060232,0.000000
+0,1,24708,6.707749,-6.590069,-5.374045,0.000000
+0,1,24713,6.707749,-6.590069,-5.374045,0.000000
+0,1,24718,6.864655,-6.707749,-5.491724,0.000000
+0,1,24723,6.864655,-6.707749,-5.491724,0.000000
+0,1,24728,7.060789,-6.707749,-5.530951,0.000000
+0,1,24733,7.060789,-6.707749,-5.530951,0.000000
+0,1,24738,7.060789,-6.707749,-5.530951,0.000000
+0,1,24743,7.100015,-6.550843,-5.452498,0.000000
+0,1,24748,7.100015,-6.550843,-5.452498,0.000000
+0,1,24753,7.845320,-6.590069,-5.570178,0.000000
+0,1,24758,7.845320,-6.590069,-5.570178,0.000000
+0,1,24763,7.374601,-6.001670,-5.727084,0.000000
+0,1,24768,7.374601,-6.001670,-5.727084,0.000000
+0,1,24773,7.296148,-6.119350,-5.570178,0.000000
+0,1,24778,7.296148,-6.119350,-5.570178,0.000000
+0,1,24783,6.943109,-5.883990,-5.217138,0.000000
+0,1,24788,6.943109,-5.883990,-5.217138,0.000000
+0,1,24793,6.472389,-5.923217,-4.864099,0.000000
+0,1,24798,6.472389,-5.923217,-4.864099,0.000000
+0,1,24803,6.315483,-5.727084,-4.707192,0.000000
+0,1,24808,6.315483,-5.727084,-4.707192,0.000000
+0,1,24813,6.080123,-5.648631,-4.550286,0.000000
+0,1,24818,6.080123,-5.648631,-4.550286,0.000000
+0,1,24823,5.883990,-5.530951,-4.118793,0.000000
+0,1,24828,5.883990,-5.530951,-4.118793,0.000000
+0,1,24833,5.883990,-5.374045,-4.275700,0.000000
+0,1,24838,5.883990,-5.374045,-4.275700,0.000000
+0,1,24843,5.648631,-5.374045,-3.687301,0.000000
+0,1,24848,5.648631,-5.374045,-3.687301,0.000000
+0,1,24853,5.452498,-5.374045,-3.608848,0.000000
+0,1,24858,5.452498,-5.374045,-3.608848,0.000000
+0,1,24863,5.491724,-5.060232,-3.334261,0.000000
+0,1,24868,5.491724,-5.060232,-3.334261,0.000000
+0,1,24873,5.530951,-5.138685,-3.412714,0.000000
+0,1,24878,5.530951,-5.138685,-3.412714,0.000000
+0,1,24883,5.452498,-5.138685,-3.216581,0.000000
+0,1,24888,5.452498,-5.138685,-3.216581,0.000000
+0,1,24893,5.413271,-5.138685,-3.373488,0.000000
+0,1,24898,5.413271,-5.138685,-3.373488,0.000000
+0,1,24903,5.295591,-5.256365,-3.255808,0.000000
+0,1,24908,5.295591,-5.256365,-3.255808,0.000000
+0,1,24913,5.334818,-5.295591,-3.334261,0.000000
+0,1,24918,5.334818,-5.295591,-3.334261,0.000000
+0,1,24923,5.413271,-5.374045,-3.177355,0.000000
+0,1,24928,5.413271,-5.374045,-3.177355,0.000000
+0,1,24933,5.491724,-5.334818,-2.902768,0.000000
+0,1,24938,5.491724,-5.334818,-2.902768,0.000000
+0,1,24943,5.530951,-5.413271,-3.059675,0.000000
+0,1,24948,5.530951,-5.413271,-3.059675,0.000000
+0,1,24953,5.570178,-5.883990,-3.059675,0.000000
+0,1,24958,5.570178,-5.883990,-3.059675,0.000000
+0,1,24963,5.570178,-5.491724,-3.334261,0.000000
+0,1,24968,5.570178,-5.491724,-3.334261,0.000000
+0,1,24973,5.334818,-5.648631,-3.726527,0.000000
+0,1,24978,5.334818,-5.648631,-3.726527,0.000000
+0,1,24983,5.609404,-5.609404,-3.608848,0.000000
+0,1,24988,5.609404,-5.609404,-3.608848,0.000000
+0,1,24993,5.570178,-5.413271,-3.961887,0.000000
+0,1,24998,5.570178,-5.413271,-3.961887,0.000000
+0,1,25003,5.648631,-5.452498,-4.236473,0.000000
+0,1,25008,5.648631,-5.452498,-4.236473,0.000000
+0,1,25013,5.962444,-5.530951,-4.197247,0.000000
+0,1,25018,5.962444,-5.530951,-4.197247,0.000000
+0,1,25023,5.844764,-5.374045,-4.393379,0.000000
+0,1,25028,5.844764,-5.374045,-4.393379,0.000000
+0,1,25033,6.001670,-5.334818,-4.471833,0.000000
+0,1,25038,6.001670,-5.334818,-4.471833,0.000000
+0,1,25043,6.158576,-5.256365,-4.314926,0.000000
+0,1,25048,6.158576,-5.256365,-4.314926,0.000000
+0,1,25053,6.354709,-5.295591,-4.158020,0.000000
+0,1,25058,6.354709,-5.295591,-4.158020,0.000000
+0,1,25063,6.590069,-5.491724,-4.354153,0.000000
+0,1,25068,6.590069,-5.491724,-4.354153,0.000000
+0,1,25073,6.433163,-5.374045,-4.158020,0.000000
+0,1,25078,6.433163,-5.374045,-4.158020,0.000000
+0,1,25083,6.903882,-5.413271,-4.040340,0.000000
+0,1,25088,6.903882,-5.413271,-4.040340,0.000000
+0,1,25093,7.217695,-6.040897,-4.550286,0.000000
+0,1,25098,7.217695,-6.040897,-4.550286,0.000000
+0,1,25103,7.649188,-6.197803,-4.550286,0.000000
+0,1,25108,7.649188,-6.197803,-4.550286,0.000000
+0,1,25113,7.492281,-5.962444,-4.707192,0.000000
+0,1,25118,7.492281,-5.962444,-4.707192,0.000000
+0,1,25123,7.963000,-6.197803,-4.589512,0.000000
+0,1,25128,7.963000,-6.197803,-4.589512,0.000000
+0,1,25133,7.923774,-6.119350,-4.824872,0.000000
+0,1,25138,7.923774,-6.119350,-4.824872,0.000000
+0,1,25143,7.884547,-6.433163,-4.864099,0.000000
+0,1,25148,7.884547,-6.433163,-4.864099,0.000000
+0,1,25153,7.884547,-6.472389,-5.021005,0.000000
+0,1,25158,7.884547,-6.472389,-5.021005,0.000000
+0,1,25163,7.845320,-6.550843,-5.217138,0.000000
+0,1,25168,7.845320,-6.550843,-5.217138,0.000000
+0,1,25173,7.727641,-6.590069,-5.374045,0.000000
+0,1,25178,7.727641,-6.590069,-5.374045,0.000000
+0,1,25183,7.570734,-6.550843,-5.413271,0.000000
+0,1,25188,7.531507,-6.550843,-5.413271,0.000000
+0,1,25193,7.531507,-6.550843,-5.413271,0.000000
+0,1,25198,7.453054,-6.393936,-5.491724,0.000000
+0,1,25203,7.453054,-6.393936,-5.491724,0.000000
+0,1,25208,7.374601,-6.433163,-5.609404,0.000000
+0,1,25213,7.374601,-6.433163,-5.609404,0.000000
+0,1,25218,7.335374,-6.707749,-5.687858,0.000000
+0,1,25223,7.335374,-6.707749,-5.687858,0.000000
+0,1,25228,7.413828,-7.688414,-5.452498,0.000000
+0,1,25233,7.413828,-7.688414,-5.452498,0.000000
+0,1,25238,7.531507,-8.551399,-5.530951,0.000000
+0,1,25243,7.531507,-8.551399,-5.530951,0.000000
+0,1,25248,7.609961,-8.786758,-5.648631,0.000000
+0,1,25253,7.609961,-8.786758,-5.648631,0.000000
+0,1,25258,7.963000,-8.825986,-5.766310,0.000000
+0,1,25263,7.963000,-8.825986,-5.766310,0.000000
+0,1,25268,8.276814,-8.316040,-5.883990,0.000000
+0,1,25273,8.276814,-8.316040,-5.883990,0.000000
+0,1,25278,8.943666,-8.237586,-5.805537,0.000000
+0,1,25283,8.943666,-8.237586,-5.805537,0.000000
+0,1,25288,8.904439,-7.688414,-5.491724,0.000000
+0,1,25293,8.904439,-7.688414,-5.491724,0.000000
+0,1,25298,8.747532,-7.060789,-5.609404,0.000000
+0,1,25303,8.747532,-7.060789,-5.609404,0.000000
+0,1,25308,8.433720,-6.433163,-4.707192,0.000000
+0,1,25313,8.433720,-6.433163,-4.707192,0.000000
+0,1,25318,8.119907,-6.276257,-4.471833,0.000000
+0,1,25323,8.119907,-6.276257,-4.471833,0.000000
+0,1,25328,7.963000,-6.903882,-4.981779,0.000000
+0,1,25333,7.963000,-6.903882,-4.981779,0.000000
+0,1,25338,7.178468,-6.354709,-4.589512,0.000000
+0,1,25343,7.178468,-6.354709,-4.589512,0.000000
+0,1,25348,5.923217,-6.472389,-5.177911,0.000000
+0,1,25353,5.923217,-6.472389,-5.177911,0.000000
+0,1,25358,6.315483,-6.746975,-4.393379,0.000000
+0,1,25363,6.315483,-6.746975,-4.393379,0.000000
+0,1,25368,5.805537,-7.217695,-4.550286,0.000000
+0,1,25373,5.805537,-7.217695,-4.550286,0.000000
+0,1,25378,5.530951,-6.903882,-4.354153,0.000000
+0,1,25383,5.530951,-6.903882,-4.354153,0.000000
+0,1,25388,5.217138,-7.060789,-3.961887,0.000000
+0,1,25393,5.217138,-7.060789,-3.961887,0.000000
+0,1,25398,5.217138,-7.178468,-3.961887,0.000000
+0,1,25403,5.217138,-7.178468,-3.961887,0.000000
+0,1,25408,5.217138,-7.453054,-3.961887,0.000000
+0,1,25413,5.217138,-7.453054,-3.961887,0.000000
+0,1,25418,5.295591,-7.609961,-3.765754,0.000000
+0,1,25423,5.295591,-7.609961,-3.765754,0.000000
+0,1,25428,5.374045,-7.531507,-3.765754,0.000000
+0,1,25433,5.374045,-7.531507,-3.765754,0.000000
+0,1,25438,5.413271,-7.492281,-3.648074,0.000000
+0,1,25443,5.413271,-7.492281,-3.648074,0.000000
+0,1,25448,5.609404,-7.570734,-3.530394,0.000000
+0,1,25453,5.609404,-7.570734,-3.530394,0.000000
+0,1,25458,5.648631,-7.492281,-3.412714,0.000000
+0,1,25463,5.648631,-7.492281,-3.412714,0.000000
+0,1,25468,5.648631,-7.413828,-3.451941,0.000000
+0,1,25473,5.648631,-7.413828,-3.451941,0.000000
+0,1,25478,5.648631,-7.256921,-3.373488,0.000000
+0,1,25483,5.648631,-7.256921,-3.373488,0.000000
+0,1,25488,5.648631,-7.178468,-3.373488,0.000000
+0,1,25493,5.648631,-7.178468,-3.373488,0.000000
+0,1,25498,5.609404,-7.060789,-3.569621,0.000000
+0,1,25503,5.609404,-7.060789,-3.569621,0.000000
+0,1,25508,5.805537,-6.982335,-3.844207,0.000000
+0,1,25513,5.805537,-6.982335,-3.844207,0.000000
+0,1,25518,5.648631,-6.825429,-3.961887,0.000000
+0,1,25523,5.648631,-6.825429,-3.961887,0.000000
+0,1,25528,5.452498,-6.707749,-4.197247,0.000000
+0,1,25533,5.452498,-6.707749,-4.197247,0.000000
+0,1,25538,5.491724,-6.590069,-4.197247,0.000000
+0,1,25543,5.491724,-6.590069,-4.197247,0.000000
+0,1,25548,5.413271,-6.550843,-4.197247,0.000000
+0,1,25553,5.413271,-6.550843,-4.197247,0.000000
+0,1,25558,5.413271,-6.550843,-4.197247,0.000000
+0,1,25563,5.413271,-6.550843,-4.197247,0.000000
+0,1,25568,5.295591,-6.511616,-4.079566,0.000000
+0,1,25573,5.295591,-6.511616,-4.079566,0.000000
+0,1,25578,5.256365,-6.550843,-3.922660,0.000000
+0,1,25583,5.256365,-6.550843,-3.922660,0.000000
+0,1,25588,5.334818,-6.393936,-3.883434,0.000000
+0,1,25593,5.334818,-6.393936,-3.883434,0.000000
+0,1,25598,5.295591,-6.511616,-3.687301,0.000000
+0,1,25603,5.295591,-6.511616,-3.687301,0.000000
+0,1,25608,5.138685,-6.511616,-3.491168,0.000000
+0,1,25613,5.138685,-6.511616,-3.491168,0.000000
+0,1,25618,5.099459,-6.511616,-3.451941,0.000000
+0,1,25623,5.099459,-6.511616,-3.451941,0.000000
+0,1,25628,5.099459,-6.472389,-3.373488,0.000000
+0,1,25633,5.099459,-6.472389,-3.373488,0.000000
+0,1,25638,5.099459,-6.472389,-3.255808,0.000000
+0,1,25643,5.099459,-6.550843,-3.255808,0.000000
+0,1,25648,5.099459,-6.550843,-3.255808,0.000000
+0,1,25653,5.099459,-6.511616,-3.373488,0.000000
+0,1,25658,5.099459,-6.511616,-3.373488,0.000000
+0,1,25663,5.099459,-6.393936,-3.334261,0.000000
+0,1,25668,5.099459,-6.393936,-3.334261,0.000000
+0,1,25673,5.177911,-6.197803,-3.334261,0.000000
+0,1,25678,5.177911,-6.197803,-3.334261,0.000000
+0,1,25683,5.138685,-6.276257,-3.255808,0.000000
+0,1,25688,5.138685,-6.276257,-3.255808,0.000000
+0,1,25693,5.138685,-6.080123,-3.138128,0.000000
+0,1,25698,5.138685,-6.080123,-3.138128,0.000000
+0,1,25703,5.138685,-6.040897,-3.255808,0.000000
+0,1,25708,5.138685,-6.040897,-3.255808,0.000000
+0,1,25713,5.217138,-6.040897,-3.177355,0.000000
+0,1,25718,5.217138,-6.040897,-3.177355,0.000000
+0,1,25723,5.099459,-6.040897,-3.020448,0.000000
+0,1,25728,5.099459,-6.040897,-3.020448,0.000000
+0,1,25733,5.060232,-6.237030,-2.941995,0.000000
+0,1,25738,5.060232,-6.237030,-2.941995,0.000000
+0,1,25743,5.217138,-6.393936,-2.981222,0.000000
+0,1,25748,5.217138,-6.393936,-2.981222,0.000000
+0,1,25753,5.413271,-6.511616,-3.098902,0.000000
+0,1,25758,5.413271,-6.511616,-3.098902,0.000000
+0,1,25763,5.570178,-6.590069,-3.059675,0.000000
+0,1,25768,5.570178,-6.590069,-3.059675,0.000000
+0,1,25773,5.648631,-6.746975,-3.138128,0.000000
+0,1,25778,5.648631,-6.746975,-3.138128,0.000000
+0,1,25783,5.923217,-6.746975,-3.412714,0.000000
+0,1,25788,5.923217,-6.746975,-3.412714,0.000000
+0,1,25793,6.158576,-6.903882,-3.608848,0.000000
+0,1,25798,6.158576,-6.903882,-3.608848,0.000000
+0,1,25803,6.433163,-7.060789,-3.765754,0.000000
+0,1,25808,6.433163,-7.060789,-3.765754,0.000000
+0,1,25813,6.746975,-7.100015,-3.883434,0.000000
+0,1,25818,6.746975,-7.100015,-3.883434,0.000000
+0,1,25823,6.903882,-7.178468,-4.118793,0.000000
+0,1,25828,6.903882,-7.178468,-4.118793,0.000000
+0,1,25833,7.217695,-7.335374,-4.314926,0.000000
+0,1,25838,7.217695,-7.335374,-4.314926,0.000000
+0,1,25843,7.296148,-7.335374,-4.511059,0.000000
+0,1,25848,7.296148,-7.335374,-4.511059,0.000000
+0,1,25853,7.374601,-7.374601,-4.589512,0.000000
+0,1,25858,7.374601,-7.374601,-4.589512,0.000000
+0,1,25863,7.256921,-7.256921,-4.746419,0.000000
+0,1,25868,7.256921,-7.256921,-4.746419,0.000000
+0,1,25873,7.021562,-7.178468,-4.707192,0.000000
+0,1,25878,7.021562,-7.178468,-4.707192,0.000000
+0,1,25883,6.707749,-7.139242,-4.628739,0.000000
+0,1,25888,6.707749,-7.139242,-4.628739,0.000000
+0,1,25893,6.511616,-7.178468,-4.589512,0.000000
+0,1,25898,6.511616,-7.178468,-4.589512,0.000000
+0,1,25903,6.354709,-6.982335,-4.589512,0.000000
+0,1,25908,6.354709,-6.982335,-4.589512,0.000000
+0,1,25913,6.393936,-6.668522,-4.393379,0.000000
+0,1,25918,6.393936,-6.668522,-4.393379,0.000000
+0,1,25923,6.629296,-6.511616,-4.393379,0.000000
+0,1,25928,6.629296,-6.511616,-4.393379,0.000000
+0,1,25933,6.864655,-6.786202,-4.197247,0.000000
+0,1,25938,6.864655,-6.786202,-4.197247,0.000000
+0,1,25943,7.531507,-7.845320,-4.040340,0.000000
+0,1,25948,7.531507,-7.845320,-4.040340,0.000000
+0,1,25953,7.178468,-7.845320,-3.765754,0.000000
+0,1,25958,7.178468,-7.845320,-3.765754,0.000000
+0,1,25963,8.316040,-8.629852,-4.746419,0.000000
+0,1,25968,8.316040,-8.629852,-4.746419,0.000000
+0,1,25973,9.767424,-9.728197,-4.550286,0.000000
+0,1,25978,9.767424,-9.728197,-4.550286,0.000000
+0,1,25983,9.806650,-9.649744,-5.295591,0.000000
+0,1,25988,9.806650,-9.649744,-5.295591,0.000000
+0,1,25993,10.042010,-8.865212,-5.413271,0.000000
+0,1,25998,10.042010,-8.865212,-5.413271,0.000000
+0,1,26003,9.139798,-7.570734,-5.727084,0.000000
+0,1,26008,9.139798,-7.570734,-5.727084,0.000000
+0,1,26013,8.433720,-6.668522,-5.687858,0.000000
+0,1,26018,8.433720,-6.668522,-5.687858,0.000000
+0,1,26023,8.041453,-6.040897,-6.119350,0.000000
+0,1,26028,8.041453,-6.040897,-6.119350,0.000000
+0,1,26033,7.766868,-5.962444,-6.119350,0.000000
+0,1,26038,7.766868,-5.962444,-6.119350,0.000000
+0,1,26043,7.060789,-5.374045,-6.040897,0.000000
+0,1,26048,7.060789,-5.374045,-6.040897,0.000000
+0,1,26053,6.237030,-4.785645,-5.609404,0.000000
+0,1,26058,6.237030,-4.785645,-5.609404,0.000000
+0,1,26063,5.452498,-4.746419,-5.138685,0.000000
+0,1,26068,5.452498,-4.746419,-5.138685,0.000000
+0,1,26073,5.138685,-5.177911,-4.981779,0.000000
+0,1,26078,5.138685,-5.177911,-4.981779,0.000000
+0,1,26083,5.452498,-6.158576,-4.746419,0.000000
+0,1,26088,5.452498,-6.158576,-4.746419,0.000000
+0,1,26093,5.452498,-6.158576,-4.746419,0.000000
+0,1,26098,5.491724,-6.943109,-4.550286,0.000000
+0,1,26103,5.491724,-6.943109,-4.550286,0.000000
+0,1,26108,5.648631,-7.060789,-4.550286,0.000000
+0,1,26113,5.648631,-7.060789,-4.550286,0.000000
+0,1,26118,6.001670,-6.707749,-4.667965,0.000000
+0,1,26123,6.001670,-6.707749,-4.667965,0.000000
+0,1,26128,6.629296,-6.433163,-4.667965,0.000000
+0,1,26133,6.629296,-6.433163,-4.667965,0.000000
+0,1,26138,7.217695,-6.001670,-4.824872,0.000000
+0,1,26143,7.217695,-6.001670,-4.824872,0.000000
+0,1,26148,7.923774,-6.001670,-4.903325,0.000000
+0,1,26153,7.923774,-6.001670,-4.903325,0.000000
+0,1,26158,8.159133,-5.805537,-4.550286,0.000000
+0,1,26163,8.159133,-5.805537,-4.550286,0.000000
+0,1,26168,8.080680,-5.648631,-4.667965,0.000000
+0,1,26173,8.080680,-5.648631,-4.667965,0.000000
+0,1,26178,7.570734,-5.452498,-4.864099,0.000000
+0,1,26183,7.570734,-5.452498,-4.864099,0.000000
+0,1,26188,6.943109,-5.727084,-4.824872,0.000000
+0,1,26193,6.943109,-5.727084,-4.824872,0.000000
+0,1,26198,6.629296,-5.727084,-4.746419,0.000000
+0,1,26203,6.629296,-5.727084,-4.746419,0.000000
+0,1,26208,5.923217,-5.962444,-4.667965,0.000000
+0,1,26213,5.923217,-5.962444,-4.667965,0.000000
+0,1,26218,5.491724,-5.805537,-4.511059,0.000000
+0,1,26223,5.491724,-5.805537,-4.511059,0.000000
+0,1,26228,5.217138,-5.844764,-4.118793,0.000000
+0,1,26233,5.217138,-5.844764,-4.118793,0.000000
+0,1,26238,5.060232,-5.727084,-3.922660,0.000000
+0,1,26243,5.060232,-5.727084,-3.922660,0.000000
+0,1,26248,4.981779,-5.766310,-3.922660,0.000000
+0,1,26253,4.981779,-5.766310,-3.922660,0.000000
+0,1,26258,4.981779,-5.452498,-3.922660,0.000000
+0,1,26263,4.981779,-5.452498,-3.922660,0.000000
+0,1,26268,5.021005,-5.374045,-3.530394,0.000000
+0,1,26273,5.021005,-5.374045,-3.530394,0.000000
+0,1,26278,5.099459,-5.217138,-3.765754,0.000000
+0,1,26283,5.099459,-5.217138,-3.765754,0.000000
+0,1,26288,5.217138,-5.334818,-3.687301,0.000000
+0,1,26293,5.217138,-5.334818,-3.687301,0.000000
+0,1,26298,5.256365,-5.256365,-3.569621,0.000000
+0,1,26303,5.256365,-5.256365,-3.569621,0.000000
+0,1,26308,5.374045,-5.295591,-3.569621,0.000000
+0,1,26313,5.374045,-5.295591,-3.569621,0.000000
+0,1,26318,5.256365,-5.452498,-3.530394,0.000000
+0,1,26323,5.256365,-5.452498,-3.530394,0.000000
+0,1,26328,5.374045,-5.687858,-3.530394,0.000000
+0,1,26333,5.374045,-5.687858,-3.530394,0.000000
+0,1,26338,5.452498,-5.687858,-3.530394,0.000000
+0,1,26343,5.452498,-5.687858,-3.530394,0.000000
+0,1,26348,5.609404,-5.766310,-3.530394,0.000000
+0,1,26353,5.609404,-5.766310,-3.530394,0.000000
+0,1,26358,5.727084,-5.727084,-3.608848,0.000000
+0,1,26363,5.727084,-5.727084,-3.608848,0.000000
+0,1,26368,5.883990,-5.413271,-3.687301,0.000000
+0,1,26373,5.883990,-5.413271,-3.687301,0.000000
+0,1,26378,5.766310,-5.491724,-3.883434,0.000000
+0,1,26383,5.766310,-5.491724,-3.883434,0.000000
+0,1,26388,5.844764,-5.609404,-3.844207,0.000000
+0,1,26393,5.844764,-5.609404,-3.844207,0.000000
+0,1,26398,5.805537,-5.687858,-4.079566,0.000000
+0,1,26403,5.805537,-5.687858,-4.079566,0.000000
+0,1,26408,5.687858,-5.609404,-4.197247,0.000000
+0,1,26413,5.687858,-5.609404,-4.197247,0.000000
+0,1,26418,5.727084,-5.648631,-4.354153,0.000000
+0,1,26423,5.727084,-5.648631,-4.354153,0.000000
+0,1,26433,5.883990,-5.687858,-4.471833,0.000000
+0,1,26438,5.962444,-5.805537,-4.118793,0.000000
+0,1,26443,5.962444,-5.805537,-4.118793,0.000000
+0,1,26448,6.276257,-5.923217,-4.236473,0.000000
+0,1,26453,6.276257,-5.923217,-4.236473,0.000000
+0,1,26458,6.629296,-6.237030,-4.118793,0.000000
+0,1,26463,6.629296,-6.237030,-4.118793,0.000000
+0,1,26468,6.903882,-6.433163,-4.197247,0.000000
+0,1,26473,6.903882,-6.433163,-4.197247,0.000000
+0,1,26478,7.256921,-6.629296,-4.158020,0.000000
+0,1,26483,7.256921,-6.629296,-4.158020,0.000000
+0,1,26488,7.570734,-6.511616,-4.550286,0.000000
+0,1,26493,7.570734,-6.511616,-4.550286,0.000000
+0,1,26498,8.002227,-6.550843,-4.589512,0.000000
+0,1,26503,8.002227,-6.550843,-4.589512,0.000000
+0,1,26508,8.394493,-6.393936,-4.707192,0.000000
+0,1,26513,8.394493,-6.393936,-4.707192,0.000000
+0,1,26518,8.355267,-6.276257,-4.824872,0.000000
+0,1,26523,8.355267,-6.276257,-4.824872,0.000000
+0,1,26528,8.198359,-6.433163,-4.707192,0.000000
+0,1,26533,8.198359,-6.433163,-4.707192,0.000000
+0,1,26538,8.198359,-6.433163,-5.021005,0.000000
+0,1,26543,8.159133,-6.668522,-4.981779,0.000000
+0,1,26548,8.159133,-6.668522,-4.981779,0.000000
+0,1,26553,8.080680,-7.060789,-5.177911,0.000000
+0,1,26558,8.080680,-7.060789,-5.177911,0.000000
+0,1,26563,8.041453,-7.570734,-5.256365,0.000000
+0,1,26568,8.041453,-7.570734,-5.256365,0.000000
+0,1,26573,7.963000,-7.963000,-5.452498,0.000000
+0,1,26578,7.963000,-7.963000,-5.452498,0.000000
+0,1,26583,7.923774,-8.237586,-5.452498,0.000000
+0,1,26588,7.923774,-8.237586,-5.452498,0.000000
+0,1,26593,7.963000,-8.394493,-5.413271,0.000000
+0,1,26598,7.963000,-8.394493,-5.413271,0.000000
+0,1,26603,7.845320,-8.276814,-5.374045,0.000000
+0,1,26608,7.845320,-8.276814,-5.374045,0.000000
+0,1,26613,7.806094,-7.963000,-5.491724,0.000000
+0,1,26618,7.806094,-7.963000,-5.491724,0.000000
+0,1,26623,7.845320,-7.727641,-5.491724,0.000000
+0,1,26628,7.845320,-7.727641,-5.491724,0.000000
+0,1,26633,7.531507,-7.374601,-5.217138,0.000000
+0,1,26638,7.531507,-7.374601,-5.217138,0.000000
+0,1,26643,7.374601,-6.982335,-5.021005,0.000000
+0,1,26648,7.374601,-6.982335,-5.021005,0.000000
+0,1,26653,7.178468,-6.864655,-4.903325,0.000000
+0,1,26658,7.178468,-6.864655,-4.903325,0.000000
+0,1,26663,6.943109,-6.629296,-4.707192,0.000000
+0,1,26668,6.943109,-6.629296,-4.707192,0.000000
+0,1,26673,6.472389,-6.511616,-4.824872,0.000000
+0,1,26678,6.472389,-6.511616,-4.824872,0.000000
+0,1,26683,6.276257,-6.276257,-4.471833,0.000000
+0,1,26688,6.276257,-6.276257,-4.471833,0.000000
+0,1,26693,6.001670,-6.354709,-4.354153,0.000000
+0,1,26698,6.001670,-6.354709,-4.354153,0.000000
+0,1,26703,5.687858,-6.197803,-4.236473,0.000000
+0,1,26708,5.687858,-6.197803,-4.236473,0.000000
+0,1,26713,5.491724,-6.158576,-4.079566,0.000000
+0,1,26718,5.491724,-6.158576,-4.079566,0.000000
+0,1,26723,5.217138,-6.237030,-3.883434,0.000000
+0,1,26728,5.217138,-6.237030,-3.883434,0.000000
+0,1,26733,5.334818,-6.629296,-3.648074,0.000000
+0,1,26738,5.334818,-6.629296,-3.648074,0.000000
+0,1,26743,5.570178,-6.982335,-3.765754,0.000000
+0,1,26748,5.570178,-6.982335,-3.765754,0.000000
+0,1,26753,5.727084,-7.021562,-3.687301,0.000000
+0,1,26758,5.727084,-7.021562,-3.687301,0.000000
+0,1,26763,5.962444,-7.374601,-3.569621,0.000000
+0,1,26768,5.962444,-7.374601,-3.569621,0.000000
+0,1,26773,6.197803,-7.492281,-3.726527,0.000000
+0,1,26778,6.197803,-7.492281,-3.726527,0.000000
+0,1,26783,6.786202,-7.531507,-3.804980,0.000000
+0,1,26788,6.786202,-7.531507,-3.804980,0.000000
+0,1,26793,6.982335,-7.570734,-3.883434,0.000000
+0,1,26798,6.982335,-7.570734,-3.883434,0.000000
+0,1,26803,7.060789,-7.570734,-4.079566,0.000000
+0,1,26808,7.060789,-7.570734,-4.079566,0.000000
+0,1,26813,7.217695,-7.492281,-4.314926,0.000000
+0,1,26818,7.217695,-7.492281,-4.314926,0.000000
+0,1,26823,7.100015,-7.963000,-6.237030,0.000000
+0,1,26828,7.100015,-7.963000,-6.237030,0.000000
+0,1,26833,6.786202,-7.217695,-4.746419,0.000000
+0,1,26838,6.786202,-7.217695,-4.746419,0.000000
+0,1,26843,6.746975,-7.570734,-4.667965,0.000000
+0,1,26848,6.746975,-7.570734,-4.667965,0.000000
+0,1,26853,6.393936,-7.963000,-5.099459,0.000000
+0,1,26858,6.393936,-7.963000,-5.099459,0.000000
+0,1,26863,5.805537,-7.570734,-5.217138,0.000000
+0,1,26868,5.805537,-7.570734,-5.217138,0.000000
+0,1,26873,5.491724,-7.256921,-4.864099,0.000000
+0,1,26878,5.491724,-7.256921,-4.864099,0.000000
+0,1,26883,5.570178,-7.256921,-4.746419,0.000000
+0,1,26888,5.570178,-7.256921,-4.746419,0.000000
+0,1,26893,5.648631,-7.256921,-4.707192,0.000000
+0,1,26898,5.648631,-7.256921,-4.707192,0.000000
+0,1,26903,5.609404,-7.178468,-4.550286,0.000000
+0,1,26908,5.609404,-7.178468,-4.550286,0.000000
+0,1,26913,5.687858,-6.903882,-4.354153,0.000000
+0,1,26918,5.687858,-6.903882,-4.354153,0.000000
+0,1,26923,5.648631,-6.550843,-4.079566,0.000000
+0,1,26928,5.648631,-6.550843,-4.079566,0.000000
+0,1,26933,5.766310,-6.472389,-3.922660,0.000000
+0,1,26938,5.766310,-6.472389,-3.922660,0.000000
+0,1,26943,5.766310,-6.433163,-3.648074,0.000000
+0,1,26948,5.766310,-6.433163,-3.648074,0.000000
+0,1,26953,5.727084,-6.393936,-3.491168,0.000000
+0,1,26958,5.727084,-6.393936,-3.491168,0.000000
+0,1,26963,5.570178,-6.276257,-3.451941,0.000000
+0,1,26968,5.570178,-6.276257,-3.451941,0.000000
+0,1,26973,5.530951,-6.119350,-3.255808,0.000000
+0,1,26978,5.530951,-6.119350,-3.255808,0.000000
+0,1,26983,5.530951,-6.197803,-3.216581,0.000000
+0,1,26988,5.530951,-6.197803,-3.216581,0.000000
+0,1,26993,5.530951,-6.197803,-3.216581,0.000000
+0,1,26998,5.530951,-6.197803,-3.059675,0.000000
+0,1,27003,5.530951,-6.197803,-3.059675,0.000000
+0,1,27008,5.491724,-6.197803,-3.020448,0.000000
+0,1,27013,5.491724,-6.197803,-3.020448,0.000000
+0,1,27018,5.491724,-5.923217,-2.981222,0.000000
+0,1,27023,5.491724,-5.923217,-2.981222,0.000000
+0,1,27028,5.374045,-5.923217,-2.981222,0.000000
+0,1,27033,5.374045,-5.923217,-2.981222,0.000000
+0,1,27038,5.295591,-5.923217,-3.098902,0.000000
+0,1,27043,5.295591,-5.923217,-3.098902,0.000000
+0,1,27048,5.177911,-5.844764,-3.098902,0.000000
+0,1,27053,5.177911,-5.844764,-3.098902,0.000000
+0,1,27058,5.138685,-5.962444,-2.902768,0.000000
+0,1,27063,5.138685,-5.962444,-2.902768,0.000000
+0,1,27068,5.217138,-6.001670,-2.981222,0.000000
+0,1,27073,5.217138,-6.001670,-2.981222,0.000000
+0,1,27078,5.138685,-6.158576,-2.902768,0.000000
+0,1,27083,5.138685,-6.158576,-2.902768,0.000000
+0,1,27088,5.217138,-6.393936,-2.941995,0.000000
+0,1,27093,5.217138,-6.393936,-2.941995,0.000000
+0,1,27098,5.413271,-6.590069,-3.138128,0.000000
+0,1,27103,5.413271,-6.590069,-3.138128,0.000000
+0,1,27108,5.727084,-6.786202,-3.255808,0.000000
+0,1,27113,5.727084,-6.786202,-3.255808,0.000000
+0,1,27118,6.001670,-6.943109,-3.334261,0.000000
+0,1,27123,6.001670,-6.943109,-3.334261,0.000000
+0,1,27128,6.197803,-6.943109,-3.491168,0.000000
+0,1,27133,6.197803,-6.943109,-3.491168,0.000000
+0,1,27138,6.393936,-6.903882,-3.648074,0.000000
+0,1,27143,6.393936,-6.903882,-3.648074,0.000000
+0,1,27148,6.433163,-7.021562,-3.726527,0.000000
+0,1,27153,6.433163,-7.021562,-3.726527,0.000000
+0,1,27158,6.433163,-7.021562,-3.765754,0.000000
+0,1,27163,6.433163,-7.021562,-3.765754,0.000000
+0,1,27168,6.433163,-6.982335,-3.844207,0.000000
+0,1,27173,6.433163,-6.982335,-3.844207,0.000000
+0,1,27178,6.237030,-7.100015,-4.040340,0.000000
+0,1,27183,6.237030,-7.100015,-4.040340,0.000000
+0,1,27188,6.040897,-7.296148,-4.079566,0.000000
+0,1,27193,6.040897,-7.296148,-4.079566,0.000000
+0,1,27198,5.844764,-7.492281,-3.922660,0.000000
+0,1,27203,5.844764,-7.492281,-3.922660,0.000000
+0,1,27208,5.687858,-7.727641,-4.079566,0.000000
+0,1,27213,5.687858,-7.727641,-4.079566,0.000000
+0,1,27218,5.727084,-8.159133,-3.883434,0.000000
+0,1,27223,5.727084,-8.159133,-3.883434,0.000000
+0,1,27228,6.040897,-8.904439,-3.804980,0.000000
+0,1,27233,6.040897,-8.904439,-3.804980,0.000000
+0,1,27238,6.590069,-9.453611,-3.765754,0.000000
+0,1,27243,6.590069,-9.453611,-3.765754,0.000000
+0,1,27248,6.472389,-9.257479,-3.687301,0.000000
+0,1,27253,6.472389,-9.257479,-3.687301,0.000000
+0,1,27258,6.668522,-8.943666,-4.393379,0.000000
+0,1,27263,6.668522,-8.943666,-4.393379,0.000000
+0,1,27268,7.649188,-9.688971,-4.511059,0.000000
+0,1,27273,7.649188,-9.688971,-4.511059,0.000000
+0,1,27278,7.374601,-9.218252,-4.628739,0.000000
+0,1,27283,7.374601,-9.218252,-4.628739,0.000000
+0,1,27288,6.746975,-8.198359,-4.667965,0.000000
+0,1,27293,6.746975,-8.198359,-4.667965,0.000000
+0,1,27298,6.433163,-8.002227,-4.785645,0.000000
+0,1,27303,6.433163,-8.002227,-4.785645,0.000000
+0,1,27308,6.707749,-8.041453,-5.021005,0.000000
+0,1,27313,6.707749,-8.041453,-5.021005,0.000000
+0,1,27318,6.825429,-8.080680,-5.021005,0.000000
+0,1,27323,6.825429,-8.080680,-5.021005,0.000000
+0,1,27328,6.786202,-7.845320,-5.021005,0.000000
+0,1,27333,6.786202,-7.845320,-5.021005,0.000000
+0,1,27338,6.786202,-7.453054,-4.864099,0.000000
+0,1,27343,6.786202,-7.453054,-4.864099,0.000000
+0,1,27348,7.021562,-7.100015,-4.942552,0.000000
+0,1,27353,7.021562,-7.100015,-4.942552,0.000000
+0,1,27358,7.100015,-6.668522,-4.707192,0.000000
+0,1,27363,7.100015,-6.668522,-4.707192,0.000000
+0,1,27368,7.178468,-6.158576,-4.785645,0.000000
+0,1,27373,7.178468,-6.158576,-4.785645,0.000000
+0,1,27378,7.217695,-5.766310,-4.824872,0.000000
+0,1,27383,7.217695,-5.766310,-4.824872,0.000000
+0,1,27388,7.217695,-5.334818,-5.060232,0.000000
+0,1,27393,7.217695,-5.334818,-5.060232,0.000000
+0,1,27398,7.217695,-5.060232,-5.256365,0.000000
+0,1,27403,7.217695,-5.060232,-5.256365,0.000000
+0,1,27408,7.217695,-4.942552,-5.256365,0.000000
+0,1,27413,7.217695,-4.942552,-5.256365,0.000000
+0,1,27418,6.825429,-5.021005,-5.021005,0.000000
+0,1,27423,6.825429,-5.021005,-5.021005,0.000000
+0,1,27428,6.550843,-5.099459,-4.864099,0.000000
+0,1,27433,6.550843,-5.099459,-4.864099,0.000000
+0,1,27438,6.158576,-5.491724,-4.628739,0.000000
+0,1,27443,6.158576,-5.491724,-4.628739,0.000000
+0,1,27448,6.158576,-5.491724,-4.628739,0.000000
+0,1,27453,5.962444,-5.805537,-4.550286,0.000000
+0,1,27458,5.962444,-5.805537,-4.550286,0.000000
+0,1,27463,5.687858,-6.276257,-4.511059,0.000000
+0,1,27468,5.687858,-6.276257,-4.511059,0.000000
+0,1,27473,5.648631,-6.590069,-4.471833,0.000000
+0,1,27478,5.648631,-6.590069,-4.471833,0.000000
+0,1,27483,5.570178,-6.746975,-4.471833,0.000000
+0,1,27488,5.570178,-6.746975,-4.471833,0.000000
+0,1,27493,5.805537,-7.060789,-4.393379,0.000000
+0,1,27498,5.805537,-7.060789,-4.393379,0.000000
+0,1,27503,6.080123,-6.982335,-4.471833,0.000000
+0,1,27508,6.080123,-6.982335,-4.471833,0.000000
+0,1,27513,6.433163,-6.786202,-4.471833,0.000000
+0,1,27518,6.433163,-6.786202,-4.471833,0.000000
+0,1,27523,6.786202,-6.550843,-4.471833,0.000000
+0,1,27528,6.786202,-6.550843,-4.471833,0.000000
+0,1,27533,6.982335,-6.158576,-4.589512,0.000000
+0,1,27538,6.982335,-6.158576,-4.589512,0.000000
+0,1,27543,7.060789,-5.883990,-4.628739,0.000000
+0,1,27548,7.060789,-5.883990,-4.628739,0.000000
+0,1,27553,6.943109,-5.570178,-4.550286,0.000000
+0,1,27558,6.943109,-5.570178,-4.550286,0.000000
+0,1,27563,7.100015,-5.609404,-4.079566,0.000000
+0,1,27568,7.100015,-5.609404,-4.079566,0.000000
+0,1,27573,6.472389,-5.256365,-4.471833,0.000000
+0,1,27578,6.472389,-5.256365,-4.471833,0.000000
+0,1,27583,6.629296,-5.295591,-4.158020,0.000000
+0,1,27588,6.629296,-5.295591,-4.158020,0.000000
+0,1,27593,6.315483,-5.177911,-4.158020,0.000000
+0,1,27598,6.315483,-5.177911,-4.158020,0.000000
+0,1,27603,6.276257,-5.256365,-3.883434,0.000000
+0,1,27608,6.276257,-5.256365,-3.883434,0.000000
+0,1,27613,6.315483,-5.256365,-3.569621,0.000000
+0,1,27618,6.315483,-5.256365,-3.569621,0.000000
+0,1,27623,6.119350,-5.138685,-3.451941,0.000000
+0,1,27628,6.119350,-5.138685,-3.451941,0.000000
+0,1,27633,6.158576,-5.099459,-3.569621,0.000000
+0,1,27638,6.158576,-5.099459,-3.569621,0.000000
+0,1,27643,6.433163,-5.177911,-3.530394,0.000000
+0,1,27648,6.433163,-5.177911,-3.530394,0.000000
+0,1,27653,6.393936,-5.138685,-3.530394,0.000000
+0,1,27658,6.393936,-5.138685,-3.530394,0.000000
+0,1,27663,6.237030,-5.021005,-3.177355,0.000000
+0,1,27668,6.237030,-5.021005,-3.177355,0.000000
+0,1,27673,6.472389,-5.099459,-3.020448,0.000000
+0,1,27678,6.472389,-5.099459,-3.020448,0.000000
+0,1,27683,6.472389,-5.334818,-3.216581,0.000000
+0,1,27688,6.472389,-5.334818,-3.216581,0.000000
+0,1,27693,6.472389,-5.452498,-3.491168,0.000000
+0,1,27698,6.472389,-5.452498,-3.491168,0.000000
+0,1,27703,6.472389,-5.530951,-3.412714,0.000000
+0,1,27708,6.472389,-5.530951,-3.412714,0.000000
+0,1,27713,6.550843,-5.687858,-3.608848,0.000000
+0,1,27718,6.550843,-5.687858,-3.608848,0.000000
+0,1,27723,6.629296,-5.805537,-3.804980,0.000000
+0,1,27728,6.629296,-5.805537,-3.804980,0.000000
+0,1,27733,6.550843,-5.883990,-3.922660,0.000000
+0,1,27738,6.550843,-5.883990,-3.922660,0.000000
+0,1,27743,6.433163,-5.844764,-4.040340,0.000000
+0,1,27748,6.433163,-5.844764,-4.040340,0.000000
+0,1,27753,6.433163,-5.805537,-4.158020,0.000000
+0,1,27758,6.433163,-5.805537,-4.158020,0.000000
+0,1,27763,6.393936,-5.766310,-4.354153,0.000000
+0,1,27768,6.393936,-5.766310,-4.354153,0.000000
+0,1,27773,6.550843,-5.687858,-4.314926,0.000000
+0,1,27778,6.550843,-5.687858,-4.314926,0.000000
+0,1,27783,6.668522,-5.570178,-4.236473,0.000000
+0,1,27788,6.668522,-5.570178,-4.236473,0.000000
+0,1,27793,6.511616,-5.491724,-4.197247,0.000000
+0,1,27798,6.511616,-5.491724,-4.197247,0.000000
+0,1,27803,6.590069,-5.334818,-4.079566,0.000000
+0,1,27808,6.590069,-5.334818,-4.079566,0.000000
+0,1,27813,6.707749,-5.295591,-4.001113,0.000000
+0,1,27818,6.707749,-5.295591,-4.001113,0.000000
+0,1,27823,6.707749,-5.413271,-4.079566,0.000000
+0,1,27828,6.707749,-5.413271,-4.079566,0.000000
+0,1,27833,6.864655,-5.374045,-4.079566,0.000000
+0,1,27838,6.864655,-5.374045,-4.079566,0.000000
+0,1,27843,6.982335,-5.374045,-4.118793,0.000000
+0,1,27848,6.982335,-5.374045,-4.118793,0.000000
+0,1,27853,7.139242,-5.413271,-4.040340,0.000000
+0,1,27858,7.139242,-5.413271,-4.040340,0.000000
+0,1,27863,7.335374,-5.609404,-4.079566,0.000000
+0,1,27868,7.335374,-5.609404,-4.079566,0.000000
+0,1,27873,7.609961,-5.648631,-4.236473,0.000000
+0,1,27878,7.609961,-5.648631,-4.236473,0.000000
+0,1,27883,7.727641,-5.687858,-4.471833,0.000000
+0,1,27888,7.727641,-5.687858,-4.471833,0.000000
+0,1,27893,7.727641,-5.687858,-4.471833,0.000000
+0,1,27898,7.806094,-5.727084,-4.471833,0.000000
+0,1,27903,7.806094,-5.727084,-4.471833,0.000000
+0,1,27908,7.884547,-5.923217,-4.550286,0.000000
+0,1,27913,7.884547,-5.923217,-4.550286,0.000000
+0,1,27918,8.080680,-6.080123,-4.667965,0.000000
+0,1,27923,8.080680,-6.080123,-4.667965,0.000000
+0,1,27928,8.119907,-6.433163,-4.785645,0.000000
+0,1,27933,8.119907,-6.433163,-4.785645,0.000000
+0,1,27938,8.119907,-6.668522,-4.785645,0.000000
+0,1,27943,8.119907,-6.668522,-4.785645,0.000000
+0,1,27948,8.080680,-6.825429,-4.864099,0.000000
+0,1,27953,8.080680,-6.825429,-4.864099,0.000000
+0,1,27958,8.237586,-7.139242,-4.981779,0.000000
+0,1,27963,8.237586,-7.139242,-4.981779,0.000000
+0,1,27968,8.276814,-7.453054,-4.981779,0.000000
+0,1,27973,8.276814,-7.453054,-4.981779,0.000000
+0,1,27978,8.629852,-8.080680,-4.942552,0.000000
+0,1,27983,8.629852,-8.080680,-4.942552,0.000000
+0,1,27988,9.061345,-8.865212,-4.942552,0.000000
+0,1,27993,9.061345,-8.865212,-4.942552,0.000000
+0,1,27998,9.257479,-9.179025,-4.903325,0.000000
+0,1,28003,9.257479,-9.179025,-4.903325,0.000000
+0,1,28008,9.532064,-8.002227,-5.060232,0.000000
+0,1,28013,9.532064,-8.002227,-5.060232,0.000000
+0,1,28018,9.571291,-7.923774,-5.530951,0.000000
+0,1,28023,9.571291,-7.923774,-5.530951,0.000000
+0,1,28028,9.061345,-6.668522,-5.021005,0.000000
+0,1,28033,9.061345,-6.668522,-5.021005,0.000000
+0,1,28038,8.198359,-5.177911,-4.824872,0.000000
+0,1,28043,8.198359,-5.177911,-4.824872,0.000000
+0,1,28048,7.453054,-5.021005,-4.432606,0.000000
+0,1,28053,7.453054,-5.021005,-4.432606,0.000000
+0,1,28058,6.943109,-5.138685,-4.393379,0.000000
+0,1,28063,6.943109,-5.138685,-4.393379,0.000000
+0,1,28068,6.550843,-5.491724,-4.550286,0.000000
+0,1,28073,6.550843,-5.491724,-4.550286,0.000000
+0,1,28078,6.040897,-5.570178,-4.236473,0.000000
+0,1,28083,6.040897,-5.570178,-4.236473,0.000000
+0,1,28088,5.687858,-6.197803,-4.118793,0.000000
+0,1,28093,5.687858,-6.197803,-4.118793,0.000000
+0,1,28098,5.727084,-6.943109,-3.765754,0.000000
+0,1,28103,5.727084,-6.943109,-3.765754,0.000000
+0,1,28108,5.844764,-7.100015,-3.648074,0.000000
+0,1,28113,5.844764,-7.100015,-3.648074,0.000000
+0,1,28118,6.119350,-7.178468,-3.608848,0.000000
+0,1,28123,6.119350,-7.178468,-3.608848,0.000000
+0,1,28128,6.550843,-7.413828,-3.569621,0.000000
+0,1,28133,6.550843,-7.413828,-3.569621,0.000000
+0,1,28138,7.021562,-7.453054,-3.491168,0.000000
+0,1,28143,7.021562,-7.453054,-3.491168,0.000000
+0,1,28148,7.492281,-7.296148,-3.569621,0.000000
+0,1,28153,7.492281,-7.296148,-3.569621,0.000000
+0,1,28158,7.845320,-7.217695,-3.765754,0.000000
+0,1,28163,7.845320,-7.217695,-3.765754,0.000000
+0,1,28168,7.923774,-7.139242,-4.001113,0.000000
+0,1,28173,7.923774,-7.139242,-4.001113,0.000000
+0,1,28178,7.845320,-7.178468,-4.118793,0.000000
+0,1,28183,7.845320,-7.178468,-4.118793,0.000000
+0,1,28188,7.609961,-7.374601,-4.079566,0.000000
+0,1,28193,7.609961,-7.374601,-4.079566,0.000000
+0,1,28198,7.374601,-7.570734,-4.158020,0.000000
+0,1,28203,7.374601,-7.570734,-4.158020,0.000000
+0,1,28208,6.943109,-7.766868,-4.079566,0.000000
+0,1,28213,6.943109,-7.766868,-4.079566,0.000000
+0,1,28218,6.707749,-7.845320,-4.118793,0.000000
+0,1,28223,6.707749,-7.845320,-4.118793,0.000000
+0,1,28228,6.315483,-7.884547,-4.001113,0.000000
+0,1,28233,6.315483,-7.884547,-4.001113,0.000000
+0,1,28238,6.001670,-7.570734,-3.844207,0.000000
+0,1,28243,6.001670,-7.570734,-3.844207,0.000000
+0,1,28248,5.727084,-7.413828,-3.844207,0.000000
+0,1,28253,5.727084,-7.413828,-3.844207,0.000000
+0,1,28258,5.570178,-7.060789,-3.765754,0.000000
+0,1,28263,5.570178,-7.060789,-3.765754,0.000000
+0,1,28268,5.452498,-6.943109,-3.569621,0.000000
+0,1,28273,5.452498,-6.943109,-3.569621,0.000000
+0,1,28278,5.295591,-6.864655,-3.451941,0.000000
+0,1,28283,5.295591,-6.864655,-3.451941,0.000000
+0,1,28288,5.256365,-7.021562,-3.373488,0.000000
+0,1,28293,5.256365,-7.021562,-3.373488,0.000000
+0,1,28298,5.413271,-6.943109,-3.334261,0.000000
+0,1,28303,5.413271,-6.943109,-3.334261,0.000000
+0,1,28308,5.295591,-6.982335,-3.098902,0.000000
+0,1,28313,5.295591,-6.982335,-3.098902,0.000000
+0,1,28318,5.256365,-6.982335,-2.941995,0.000000
+0,1,28323,5.256365,-6.982335,-2.941995,0.000000
+0,1,28328,5.099459,-7.060789,-2.745862,0.000000
+0,1,28333,5.099459,-7.060789,-2.745862,0.000000
+0,1,28338,5.099459,-7.021562,-2.706636,0.000000
+0,1,28343,5.099459,-7.021562,-2.706636,0.000000
+0,1,28348,5.099459,-7.021562,-2.706636,0.000000
+0,1,28353,5.099459,-7.178468,-2.588956,0.000000
+0,1,28358,5.099459,-7.178468,-2.588956,0.000000
+0,1,28363,5.374045,-7.100015,-2.588956,0.000000
+0,1,28368,5.374045,-7.100015,-2.588956,0.000000
+0,1,28373,5.530951,-6.943109,-2.745862,0.000000
+0,1,28378,5.530951,-6.943109,-2.745862,0.000000
+0,1,28383,5.648631,-6.825429,-2.863542,0.000000
+0,1,28388,5.648631,-6.825429,-2.863542,0.000000
+0,1,28393,5.687858,-6.825429,-3.138128,0.000000
+0,1,28398,5.687858,-6.825429,-3.138128,0.000000
+0,1,28403,5.648631,-6.786202,-3.373488,0.000000
+0,1,28408,5.648631,-6.786202,-3.373488,0.000000
+0,1,28413,5.648631,-6.903882,-3.687301,0.000000
+0,1,28418,5.648631,-6.903882,-3.687301,0.000000
+0,1,28423,5.570178,-6.982335,-3.922660,0.000000
+0,1,28428,5.570178,-6.982335,-3.922660,0.000000
+0,1,28433,5.530951,-7.060789,-4.158020,0.000000
+0,1,28438,5.530951,-7.060789,-4.158020,0.000000
+0,1,28443,5.452498,-7.178468,-4.314926,0.000000
+0,1,28448,5.452498,-7.178468,-4.314926,0.000000
+0,1,28453,5.295591,-7.374601,-4.432606,0.000000
+0,1,28458,5.295591,-7.374601,-4.432606,0.000000
+0,1,28463,5.334818,-7.335374,-4.707192,0.000000
+0,1,28468,5.334818,-7.335374,-4.707192,0.000000
+0,1,28473,5.138685,-7.492281,-4.746419,0.000000
+0,1,28478,5.138685,-7.492281,-4.746419,0.000000
+0,1,28483,5.491724,-8.159133,-4.942552,0.000000
+0,1,28488,5.491724,-8.159133,-4.942552,0.000000
+0,1,28493,4.903325,-7.100015,-4.981779,0.000000
+0,1,28498,4.903325,-7.100015,-4.981779,0.000000
+0,1,28503,5.217138,-7.688414,-5.609404,0.000000
+0,1,28508,5.217138,-7.688414,-5.609404,0.000000
+0,1,28513,5.099459,-7.021562,-5.295591,0.000000
+0,1,28518,5.099459,-7.021562,-5.295591,0.000000
+0,1,28523,5.217138,-7.060789,-5.609404,0.000000
+0,1,28528,5.217138,-7.060789,-5.609404,0.000000
+0,1,28533,5.217138,-6.825429,-4.942552,0.000000
+0,1,28538,5.217138,-6.825429,-4.942552,0.000000
+0,1,28543,5.021005,-6.472389,-5.256365,0.000000
+0,1,28548,5.021005,-6.472389,-5.256365,0.000000
+0,1,28553,5.374045,-7.100015,-5.138685,0.000000
+0,1,28558,5.374045,-7.100015,-5.138685,0.000000
+0,1,28563,5.295591,-7.060789,-5.021005,0.000000
+0,1,28568,5.295591,-7.060789,-5.021005,0.000000
+0,1,28573,5.295591,-6.943109,-5.021005,0.000000
+0,1,28578,5.295591,-6.943109,-5.021005,0.000000
+0,1,28583,5.452498,-6.903882,-4.981779,0.000000
+0,1,28588,5.452498,-6.903882,-4.981779,0.000000
+0,1,28593,5.609404,-6.903882,-5.060232,0.000000
+0,1,28598,5.609404,-6.903882,-5.060232,0.000000
+0,1,28603,5.805537,-6.746975,-5.060232,0.000000
+0,1,28608,5.805537,-6.746975,-5.060232,0.000000
+0,1,28613,5.962444,-6.746975,-5.099459,0.000000
+0,1,28618,5.962444,-6.746975,-5.099459,0.000000
+0,1,28623,6.119350,-6.707749,-5.177911,0.000000
+0,1,28628,6.119350,-6.707749,-5.177911,0.000000
+0,1,28633,6.276257,-6.472389,-5.217138,0.000000
+0,1,28638,6.276257,-6.472389,-5.217138,0.000000
+0,1,28643,6.315483,-6.550843,-5.256365,0.000000
+0,1,28648,6.315483,-6.550843,-5.256365,0.000000
+0,1,28653,6.315483,-6.472389,-5.138685,0.000000
+0,1,28658,6.315483,-6.472389,-5.138685,0.000000
+0,1,28663,6.354709,-6.511616,-5.021005,0.000000
+0,1,28668,6.354709,-6.511616,-5.021005,0.000000
+0,1,28673,6.315483,-6.668522,-4.942552,0.000000
+0,1,28678,6.315483,-6.668522,-4.942552,0.000000
+0,1,28683,6.197803,-6.786202,-4.903325,0.000000
+0,1,28688,6.197803,-6.786202,-4.903325,0.000000
+0,1,28693,6.158576,-6.786202,-4.824872,0.000000
+0,1,28698,6.158576,-6.786202,-4.824872,0.000000
+0,1,28703,6.040897,-6.786202,-4.824872,0.000000
+0,1,28708,6.040897,-6.786202,-4.824872,0.000000
+0,1,28713,6.158576,-6.903882,-4.864099,0.000000
+0,1,28718,6.158576,-6.903882,-4.864099,0.000000
+0,1,28723,6.197803,-6.943109,-4.903325,0.000000
+0,1,28728,6.197803,-6.943109,-4.903325,0.000000
+0,1,28733,6.080123,-7.100015,-4.942552,0.000000
+0,1,28738,6.080123,-7.100015,-4.942552,0.000000
+0,1,28743,6.158576,-7.413828,-5.021005,0.000000
+0,1,28748,6.158576,-7.413828,-5.021005,0.000000
+0,1,28753,6.197803,-7.413828,-5.099459,0.000000
+0,1,28758,6.197803,-7.413828,-5.099459,0.000000
+0,1,28763,6.119350,-7.727641,-5.021005,0.000000
+0,1,28768,6.119350,-7.727641,-5.021005,0.000000
+0,1,28773,6.080123,-7.923774,-5.021005,0.000000
+0,1,28778,6.080123,-7.923774,-5.021005,0.000000
+0,1,28783,6.119350,-8.159133,-5.060232,0.000000
+0,1,28788,6.119350,-8.159133,-5.060232,0.000000
+0,1,28793,6.119350,-8.159133,-4.903325,0.000000
+0,1,28798,6.237030,-8.943666,-4.942552,0.000000
+0,1,28803,6.237030,-8.943666,-4.942552,0.000000
+0,1,28808,6.550843,-10.042010,-4.981779,0.000000
+0,1,28813,6.550843,-10.042010,-4.981779,0.000000
+0,1,28818,7.021562,-10.669636,-5.138685,0.000000
+0,1,28823,7.021562,-10.669636,-5.138685,0.000000
+0,1,28828,7.100015,-10.316596,-5.452498,0.000000
+0,1,28833,7.100015,-10.316596,-5.452498,0.000000
+0,1,28838,7.060789,-9.885103,-5.570178,0.000000
+0,1,28843,7.060789,-9.885103,-5.570178,0.000000
+0,1,28848,6.668522,-9.022119,-5.805537,0.000000
+0,1,28853,6.668522,-9.022119,-5.805537,0.000000
+0,1,28858,6.393936,-8.002227,-5.923217,0.000000
+0,1,28863,6.393936,-8.002227,-5.923217,0.000000
+0,1,28868,5.530951,-7.335374,-6.354709,0.000000
+0,1,28873,5.530951,-7.335374,-6.354709,0.000000
+0,1,28878,5.452498,-6.786202,-5.687858,0.000000
+0,1,28883,5.452498,-6.786202,-5.687858,0.000000
+0,1,28888,4.746419,-6.237030,-5.962444,0.000000
+0,1,28893,4.746419,-6.237030,-5.962444,0.000000
+0,1,28898,4.903325,-6.119350,-5.844764,0.000000
+0,1,28903,4.903325,-6.119350,-5.844764,0.000000
+0,1,28908,4.550286,-5.805537,-5.334818,0.000000
+0,1,28913,4.550286,-5.805537,-5.334818,0.000000
+0,1,28918,4.707192,-5.727084,-4.942552,0.000000
+0,1,28923,4.707192,-5.727084,-4.942552,0.000000
+0,1,28928,5.021005,-6.197803,-4.550286,0.000000
+0,1,28933,5.021005,-6.197803,-4.550286,0.000000
+0,1,28938,5.334818,-6.315483,-4.236473,0.000000
+0,1,28943,5.334818,-6.315483,-4.236473,0.000000
+0,1,28948,5.727084,-6.197803,-4.079566,0.000000
+0,1,28953,5.727084,-6.197803,-4.079566,0.000000
+0,1,28958,6.197803,-6.158576,-4.001113,0.000000
+0,1,28963,6.197803,-6.158576,-4.001113,0.000000
+0,1,28968,6.629296,-6.080123,-4.040340,0.000000
+0,1,28973,6.629296,-6.080123,-4.040340,0.000000
+0,1,28978,6.943109,-6.158576,-4.158020,0.000000
+0,1,28983,6.943109,-6.158576,-4.158020,0.000000
+0,1,28988,7.256921,-6.197803,-4.275700,0.000000
+0,1,28993,7.256921,-6.197803,-4.275700,0.000000
+0,1,28998,7.217695,-6.158576,-4.314926,0.000000
+0,1,29003,7.217695,-6.158576,-4.314926,0.000000
+0,1,29008,6.943109,-6.276257,-4.275700,0.000000
+0,1,29013,6.943109,-6.276257,-4.275700,0.000000
+0,1,29018,6.550843,-6.433163,-4.393379,0.000000
+0,1,29023,6.550843,-6.433163,-4.393379,0.000000
+0,1,29028,6.158576,-6.433163,-4.550286,0.000000
+0,1,29033,6.158576,-6.433163,-4.550286,0.000000
+0,1,29038,5.805537,-6.668522,-4.707192,0.000000
+0,1,29043,5.805537,-6.668522,-4.707192,0.000000
+0,1,29048,5.530951,-6.746975,-4.746419,0.000000
+0,1,29053,5.530951,-6.746975,-4.746419,0.000000
+0,1,29058,5.334818,-6.786202,-4.824872,0.000000
+0,1,29063,5.334818,-6.786202,-4.824872,0.000000
+0,1,29068,5.217138,-6.786202,-4.707192,0.000000
+0,1,29073,5.217138,-6.786202,-4.707192,0.000000
+0,1,29078,5.021005,-6.707749,-4.667965,0.000000
+0,1,29083,5.021005,-6.707749,-4.667965,0.000000
+0,1,29088,4.903325,-6.511616,-4.707192,0.000000
+0,1,29093,4.903325,-6.511616,-4.707192,0.000000
+0,1,29098,4.903325,-6.433163,-4.628739,0.000000
+0,1,29103,4.903325,-6.433163,-4.628739,0.000000
+0,1,29108,4.942552,-6.237030,-4.707192,0.000000
+0,1,29113,4.942552,-6.237030,-4.707192,0.000000
+0,1,29118,5.060232,-6.040897,-4.550286,0.000000
+0,1,29123,5.060232,-6.040897,-4.550286,0.000000
+0,1,29128,5.217138,-6.001670,-4.275700,0.000000
+0,1,29132,5.217138,-6.001670,-4.275700,0.000000
+0,1,29137,5.217138,-5.844764,-4.118793,0.000000
+0,1,29142,5.217138,-5.844764,-4.118793,0.000000
+0,1,29147,5.217138,-5.727084,-4.040340,0.000000
+0,1,29152,5.217138,-5.727084,-4.040340,0.000000
+0,1,29157,5.099459,-5.727084,-3.844207,0.000000
+0,1,29162,5.099459,-5.727084,-3.844207,0.000000
+0,1,29167,5.021005,-5.609404,-3.922660,0.000000
+0,1,29172,5.021005,-5.609404,-3.922660,0.000000
+0,1,29177,5.021005,-5.609404,-3.765754,0.000000
+0,1,29182,5.021005,-5.609404,-3.765754,0.000000
+0,1,29187,5.021005,-5.570178,-3.804980,0.000000
+0,1,29192,5.021005,-5.570178,-3.804980,0.000000
+0,1,29197,5.021005,-5.295591,-3.804980,0.000000
+0,1,29202,5.021005,-5.295591,-3.804980,0.000000
+0,1,29207,5.099459,-5.217138,-3.687301,0.000000
+0,1,29212,5.099459,-5.217138,-3.687301,0.000000
+0,1,29217,5.256365,-5.177911,-3.648074,0.000000
+0,1,29222,5.256365,-5.177911,-3.648074,0.000000
+0,1,29227,5.374045,-5.138685,-3.804980,0.000000
+0,1,29232,5.374045,-5.138685,-3.804980,0.000000
+0,1,29237,5.530951,-5.060232,-3.804980,0.000000
+0,1,29242,5.570178,-5.060232,-3.804980,0.000000
+0,1,29247,5.570178,-5.060232,-3.804980,0.000000
+0,1,29252,5.648631,-4.981779,-3.844207,0.000000
+0,1,29257,5.648631,-4.981779,-3.844207,0.000000
+0,1,29262,6.040897,-4.981779,-4.040340,0.000000
+0,1,29267,6.040897,-4.981779,-4.040340,0.000000
+0,1,29272,6.158576,-4.942552,-4.118793,0.000000
+0,1,29277,6.158576,-4.942552,-4.118793,0.000000
+0,1,29282,6.472389,-4.824872,-4.236473,0.000000
+0,1,29287,6.472389,-4.824872,-4.236473,0.000000
+0,1,29292,6.707749,-4.667965,-4.354153,0.000000
+0,1,29297,6.707749,-4.667965,-4.354153,0.000000
+0,1,29302,7.021562,-4.707192,-4.393379,0.000000
+0,1,29307,7.021562,-4.707192,-4.393379,0.000000
+0,1,29312,7.256921,-4.511059,-4.511059,0.000000
+0,1,29317,7.256921,-4.511059,-4.511059,0.000000
+0,1,29322,7.609961,-4.471833,-4.628739,0.000000
+0,1,29327,7.609961,-4.471833,-4.628739,0.000000
+0,1,29332,8.041453,-4.275700,-4.628739,0.000000
+0,1,29337,8.041453,-4.275700,-4.628739,0.000000
+0,1,29342,8.433720,-4.236473,-4.746419,0.000000
+0,1,29347,8.433720,-4.236473,-4.746419,0.000000
+0,1,29352,8.786758,-4.079566,-4.785645,0.000000
+0,1,29357,8.786758,-4.079566,-4.785645,0.000000
+0,1,29362,9.022119,-4.079566,-4.864099,0.000000
+0,1,29367,9.022119,-4.079566,-4.864099,0.000000
+0,1,29372,9.296705,-4.118793,-4.942552,0.000000
+0,1,29377,9.296705,-4.118793,-4.942552,0.000000
+0,1,29382,9.296705,-4.158020,-4.981779,0.000000
+0,1,29387,9.296705,-4.158020,-4.981779,0.000000
+0,1,29392,9.296705,-4.275700,-5.177911,0.000000
+0,1,29397,9.296705,-4.275700,-5.177911,0.000000
+0,1,29402,9.414385,-4.197247,-5.374045,0.000000
+0,1,29407,9.414385,-4.197247,-5.374045,0.000000
+0,1,29412,9.218252,-4.432606,-5.295591,0.000000
+0,1,29417,9.218252,-4.432606,-5.295591,0.000000
+0,1,29422,9.022119,-4.785645,-5.138685,0.000000
+0,1,29427,9.022119,-4.785645,-5.138685,0.000000
+0,1,29432,9.022119,-5.687858,-5.099459,0.000000
+0,1,29437,9.022119,-5.687858,-5.099459,0.000000
+0,1,29442,8.551399,-6.354709,-5.021005,0.000000
+0,1,29447,8.551399,-6.354709,-5.021005,0.000000
+0,1,29452,9.335931,-7.335374,-5.060232,0.000000
+0,1,29457,9.335931,-7.335374,-5.060232,0.000000
+0,1,29462,10.277370,-7.806094,-5.766310,0.000000
+0,1,29467,10.277370,-7.806094,-5.766310,0.000000
+0,1,29472,10.708862,-8.629852,-5.962444,0.000000
+0,1,29477,10.708862,-8.629852,-5.962444,0.000000
+0,1,29482,11.218808,-8.982892,-5.844764,0.000000
+0,1,29487,11.218808,-8.982892,-5.844764,0.000000
+0,1,29492,10.551956,-8.119907,-5.648631,0.000000
+0,1,29497,10.551956,-8.119907,-5.648631,0.000000
+0,1,29502,9.885103,-7.139242,-5.570178,0.000000
+0,1,29507,9.885103,-7.139242,-5.570178,0.000000
+0,1,29512,9.806650,-7.139242,-5.530951,0.000000
+0,1,29517,9.806650,-7.139242,-5.530951,0.000000
+0,1,29522,9.571291,-7.413828,-5.609404,0.000000
+0,1,29527,9.571291,-7.413828,-5.609404,0.000000
+0,1,29532,9.335931,-7.688414,-5.609404,0.000000
+0,1,29537,9.335931,-7.688414,-5.609404,0.000000
+0,1,29542,8.786758,-7.688414,-5.570178,0.000000
+0,1,29547,8.786758,-7.688414,-5.570178,0.000000
+0,1,29552,8.159133,-7.727641,-5.374045,0.000000
+0,1,29557,8.159133,-7.727641,-5.374045,0.000000
+0,1,29562,7.766868,-7.531507,-5.334818,0.000000
+0,1,29567,7.766868,-7.531507,-5.334818,0.000000
+0,1,29572,7.139242,-7.178468,-4.981779,0.000000
+0,1,29577,7.139242,-7.178468,-4.981779,0.000000
+0,1,29582,6.668522,-6.746975,-4.785645,0.000000
+0,1,29587,6.668522,-6.746975,-4.785645,0.000000
+0,1,29592,6.276257,-6.590069,-4.550286,0.000000
+0,1,29597,6.276257,-6.590069,-4.550286,0.000000
+0,1,29602,5.962444,-6.237030,-4.393379,0.000000
+0,1,29607,5.962444,-6.237030,-4.393379,0.000000
+0,1,29612,5.648631,-6.119350,-4.118793,0.000000
+0,1,29617,5.648631,-6.119350,-4.118793,0.000000
+0,1,29622,5.570178,-6.158576,-3.844207,0.000000
+0,1,29627,5.570178,-6.158576,-3.844207,0.000000
+0,1,29632,5.766310,-6.590069,-3.608848,0.000000
+0,1,29637,5.766310,-6.590069,-3.608848,0.000000
+0,1,29642,5.727084,-6.786202,-3.295035,0.000000
+0,1,29647,5.727084,-6.786202,-3.295035,0.000000
+0,1,29652,5.727084,-7.100015,-3.098902,0.000000
+0,1,29657,5.727084,-7.100015,-3.098902,0.000000
+0,1,29662,5.883990,-7.296148,-2.785089,0.000000
+0,1,29667,5.883990,-7.296148,-2.785089,0.000000
+0,1,29672,5.923217,-7.531507,-2.745862,0.000000
+0,1,29677,5.923217,-7.531507,-2.745862,0.000000
+0,1,29682,6.158576,-7.727641,-2.667409,0.000000
+0,1,29687,6.158576,-7.727641,-2.667409,0.000000
+0,1,29692,6.393936,-7.570734,-2.824315,0.000000
+0,1,29697,6.393936,-7.570734,-2.824315,0.000000
+0,1,29702,6.393936,-7.570734,-2.824315,0.000000
+0,1,29707,6.511616,-7.296148,-2.863542,0.000000
+0,1,29712,6.511616,-7.296148,-2.863542,0.000000
+0,1,29717,6.433163,-6.903882,-3.059675,0.000000
+0,1,29722,6.433163,-6.903882,-3.059675,0.000000
+0,1,29727,6.433163,-6.707749,-3.334261,0.000000
+0,1,29732,6.433163,-6.707749,-3.334261,0.000000
+0,1,29737,6.276257,-6.511616,-3.569621,0.000000
+0,1,29742,6.276257,-6.511616,-3.569621,0.000000
+0,1,29747,6.080123,-6.472389,-3.844207,0.000000
+0,1,29752,6.080123,-6.472389,-3.844207,0.000000
+0,1,29757,5.766310,-6.393936,-3.961887,0.000000
+0,1,29762,5.766310,-6.393936,-3.961887,0.000000
+0,1,29767,5.295591,-6.354709,-3.961887,0.000000
+0,1,29772,5.295591,-6.354709,-3.961887,0.000000
+0,1,29777,4.942552,-6.550843,-4.001113,0.000000
+0,1,29782,4.942552,-6.550843,-4.001113,0.000000
+0,1,29787,4.628739,-6.786202,-3.922660,0.000000
+0,1,29792,4.628739,-6.786202,-3.922660,0.000000
+0,1,29797,4.236473,-6.825429,-3.883434,0.000000
+0,1,29802,4.236473,-6.825429,-3.883434,0.000000
+0,1,29807,3.922660,-6.825429,-3.844207,0.000000
+0,1,29812,3.922660,-6.825429,-3.844207,0.000000
+0,1,29817,3.687301,-6.825429,-3.765754,0.000000
+0,1,29822,3.687301,-6.825429,-3.765754,0.000000
+0,1,29827,3.687301,-6.746975,-3.648074,0.000000
+0,1,29832,3.687301,-6.746975,-3.648074,0.000000
+0,1,29837,4.040340,-6.472389,-3.687301,0.000000
+0,1,29847,4.197247,-6.276257,-3.530394,0.000000
+0,1,29852,4.197247,-6.276257,-3.530394,0.000000
+0,1,29857,4.471833,-6.158576,-3.412714,0.000000
+0,1,29862,4.471833,-6.158576,-3.412714,0.000000
+0,1,29867,4.589512,-6.001670,-3.334261,0.000000
+0,1,29872,4.589512,-6.001670,-3.334261,0.000000
+0,1,29877,4.746419,-6.001670,-3.373488,0.000000
+0,1,29882,4.746419,-6.001670,-3.373488,0.000000
+0,1,29887,4.864099,-5.883990,-3.216581,0.000000
+0,1,29892,4.864099,-5.883990,-3.216581,0.000000
+0,1,29897,4.981779,-5.766310,-3.020448,0.000000
+0,1,29902,4.981779,-5.766310,-3.020448,0.000000
+0,1,29907,5.177911,-5.883990,-3.295035,0.000000
+0,1,29912,5.177911,-5.883990,-3.295035,0.000000
+0,1,29917,5.177911,-5.883990,-3.608848,0.000000
+0,1,29922,5.177911,-5.883990,-3.608848,0.000000
+0,1,29927,5.805537,-6.001670,-2.941995,0.000000
+0,1,29932,5.805537,-6.001670,-2.941995,0.000000
+0,1,29937,5.687858,-5.844764,-3.726527,0.000000
+0,1,29942,5.687858,-5.844764,-3.726527,0.000000
+0,1,29947,6.080123,-6.197803,-3.255808,0.000000
+0,1,29952,6.080123,-6.197803,-3.255808,0.000000
+0,1,29957,5.962444,-6.040897,-3.608848,0.000000
+0,1,29962,5.962444,-6.040897,-3.608848,0.000000
+0,1,29967,6.276257,-6.197803,-3.491168,0.000000
+0,1,29972,6.276257,-6.197803,-3.491168,0.000000
+0,1,29977,6.276257,-6.158576,-3.883434,0.000000
+0,1,29982,6.276257,-6.158576,-3.883434,0.000000
+0,1,29987,6.550843,-6.590069,-3.491168,0.000000
+0,1,29992,6.550843,-6.590069,-3.491168,0.000000
+0,1,29997,6.903882,-6.040897,-3.569621,0.000000
+0,1,30002,6.903882,-6.040897,-3.569621,0.000000
+0,1,30007,7.021562,-6.433163,-3.765754,0.000000
+0,1,30012,7.021562,-6.433163,-3.765754,0.000000
+0,1,30017,7.178468,-6.511616,-4.197247,0.000000
+0,1,30022,7.178468,-6.511616,-4.197247,0.000000
+0,1,30027,7.570734,-6.590069,-3.922660,0.000000
+0,1,30032,7.570734,-6.590069,-3.922660,0.000000
+0,1,30037,7.688414,-6.864655,-4.471833,0.000000
+0,1,30042,7.688414,-6.864655,-4.471833,0.000000
+0,1,30047,8.119907,-6.903882,-4.667965,0.000000
+0,1,30052,8.119907,-6.903882,-4.667965,0.000000
+0,1,30057,8.198359,-7.060789,-4.589512,0.000000
+0,1,30062,8.198359,-7.060789,-4.589512,0.000000
+0,1,30067,8.080680,-6.903882,-4.824872,0.000000
+0,1,30072,8.080680,-6.903882,-4.824872,0.000000
+0,1,30077,8.002227,-7.021562,-4.903325,0.000000
+0,1,30082,8.002227,-7.021562,-4.903325,0.000000
+0,1,30087,8.002227,-7.139242,-4.942552,0.000000
+0,1,30092,8.002227,-7.139242,-4.942552,0.000000
+0,1,30097,7.727641,-7.296148,-4.981779,0.000000
+0,1,30102,7.727641,-7.296148,-4.981779,0.000000
+0,1,30107,7.531507,-7.100015,-4.981779,0.000000
+0,1,30112,7.531507,-7.100015,-4.981779,0.000000
+0,1,30117,7.296148,-6.943109,-4.864099,0.000000
+0,1,30122,7.296148,-6.943109,-4.864099,0.000000
+0,1,30127,7.100015,-6.668522,-4.667965,0.000000
+0,1,30132,7.100015,-6.668522,-4.667965,0.000000
+0,1,30137,7.060789,-6.393936,-4.314926,0.000000
+0,1,30142,7.060789,-6.393936,-4.314926,0.000000
+0,1,30147,7.217695,-6.864655,-3.961887,0.000000
+0,1,30152,7.217695,-6.864655,-3.961887,0.000000
+0,1,30157,7.217695,-6.864655,-3.961887,0.000000
+0,1,30162,7.766868,-7.100015,-2.824315,0.000000
+0,1,30167,7.766868,-7.100015,-2.824315,0.000000
+0,1,30172,7.727641,-7.335374,-4.001113,0.000000
+0,1,30177,7.727641,-7.335374,-4.001113,0.000000
+0,1,30182,8.629852,-8.590626,-4.236473,0.000000
+0,1,30187,8.629852,-8.590626,-4.236473,0.000000
+0,1,30192,9.257479,-9.179025,-4.432606,0.000000
+0,1,30197,9.257479,-9.179025,-4.432606,0.000000
+0,1,30202,9.492838,-9.179025,-4.785645,0.000000
+0,1,30207,9.492838,-9.179025,-4.785645,0.000000
+0,1,30212,9.296705,-8.119907,-4.942552,0.000000
+0,1,30217,9.296705,-8.119907,-4.942552,0.000000
+0,1,30222,8.472946,-6.825429,-5.177911,0.000000
+0,1,30227,8.472946,-6.825429,-5.177911,0.000000
+0,1,30232,8.316040,-5.962444,-5.295591,0.000000
+0,1,30237,8.316040,-5.962444,-5.295591,0.000000
+0,1,30242,8.080680,-5.570178,-5.374045,0.000000
+0,1,30247,8.080680,-5.570178,-5.374045,0.000000
+0,1,30252,8.002227,-5.177911,-5.491724,0.000000
+0,1,30257,8.002227,-5.177911,-5.491724,0.000000
+0,1,30262,7.963000,-4.903325,-5.256365,0.000000
+0,1,30267,7.963000,-4.903325,-5.256365,0.000000
+0,1,30272,7.453054,-4.511059,-5.217138,0.000000
+0,1,30277,7.453054,-4.511059,-5.217138,0.000000
+0,1,30282,7.100015,-4.393379,-4.903325,0.000000
+0,1,30287,7.100015,-4.393379,-4.903325,0.000000
+0,1,30292,6.943109,-4.785645,-5.177911,0.000000
+0,1,30297,6.943109,-4.785645,-5.177911,0.000000
+0,1,30302,7.256921,-5.570178,-5.256365,0.000000
+0,1,30307,7.256921,-5.570178,-5.256365,0.000000
+0,1,30312,7.374601,-6.001670,-5.530951,0.000000
+0,1,30317,7.374601,-6.001670,-5.530951,0.000000
+0,1,30322,7.374601,-5.923217,-5.570178,0.000000
+0,1,30327,7.374601,-5.923217,-5.570178,0.000000
+0,1,30332,7.374601,-5.766310,-5.844764,0.000000
+0,1,30337,7.374601,-5.766310,-5.844764,0.000000
+0,1,30342,7.688414,-5.609404,-5.923217,0.000000
+0,1,30347,7.688414,-5.609404,-5.923217,0.000000
+0,1,30352,7.884547,-5.374045,-5.766310,0.000000
+0,1,30357,7.884547,-5.374045,-5.766310,0.000000
+0,1,30362,7.963000,-5.177911,-5.687858,0.000000
+0,1,30367,7.963000,-5.177911,-5.687858,0.000000
+0,1,30372,8.002227,-5.021005,-5.491724,0.000000
+0,1,30377,8.002227,-5.021005,-5.491724,0.000000
+0,1,30382,7.766868,-4.824872,-5.334818,0.000000
+0,1,30387,7.766868,-4.824872,-5.334818,0.000000
+0,1,30392,7.374601,-4.903325,-5.138685,0.000000
+0,1,30397,7.374601,-4.903325,-5.138685,0.000000
+0,1,30402,6.864655,-4.981779,-4.942552,0.000000
+0,1,30407,6.864655,-4.981779,-4.942552,0.000000
+0,1,30412,6.393936,-4.942552,-4.746419,0.000000
+0,1,30417,6.393936,-4.942552,-4.746419,0.000000
+0,1,30422,5.883990,-4.981779,-4.354153,0.000000
+0,1,30427,5.883990,-4.981779,-4.354153,0.000000
+0,1,30432,5.687858,-5.021005,-4.275700,0.000000
+0,1,30437,5.687858,-5.021005,-4.275700,0.000000
+0,1,30442,5.374045,-5.021005,-4.118793,0.000000
+0,1,30447,5.374045,-5.021005,-4.118793,0.000000
+0,1,30452,5.256365,-5.021005,-3.883434,0.000000
+0,1,30457,5.256365,-5.021005,-3.883434,0.000000
+0,1,30462,5.138685,-4.942552,-3.804980,0.000000
+0,1,30467,5.138685,-4.942552,-3.804980,0.000000
+0,1,30472,5.138685,-4.864099,-3.726527,0.000000
+0,1,30477,5.138685,-4.864099,-3.726527,0.000000
+0,1,30482,5.177911,-4.903325,-3.608848,0.000000
+0,1,30487,5.177911,-4.903325,-3.608848,0.000000
+0,1,30492,5.334818,-4.981779,-3.648074,0.000000
+0,1,30497,5.334818,-4.981779,-3.648074,0.000000
+0,1,30502,5.374045,-4.903325,-3.648074,0.000000
+0,1,30507,5.374045,-4.903325,-3.648074,0.000000
+0,1,30512,5.609404,-4.942552,-3.569621,0.000000
+0,1,30517,5.609404,-4.942552,-3.569621,0.000000
+0,1,30522,5.570178,-4.981779,-3.569621,0.000000
+0,1,30527,5.570178,-4.981779,-3.569621,0.000000
+0,1,30532,5.648631,-5.021005,-3.491168,0.000000
+0,1,30537,5.648631,-5.021005,-3.491168,0.000000
+0,1,30542,5.766310,-5.021005,-3.373488,0.000000
+0,1,30547,5.766310,-5.021005,-3.373488,0.000000
+0,1,30552,6.001670,-5.099459,-3.608848,0.000000
+0,1,30557,6.001670,-5.099459,-3.608848,0.000000
+0,1,30562,6.276257,-5.138685,-3.883434,0.000000
+0,1,30567,6.276257,-5.138685,-3.883434,0.000000
+0,1,30572,6.590069,-5.021005,-3.922660,0.000000
+0,1,30577,6.590069,-5.021005,-3.922660,0.000000
+0,1,30582,6.864655,-5.021005,-4.118793,0.000000
+0,1,30587,6.864655,-5.021005,-4.118793,0.000000
+0,1,30592,7.100015,-4.824872,-4.354153,0.000000
+0,1,30597,7.100015,-4.824872,-4.354153,0.000000
+0,1,30602,7.100015,-4.824872,-4.511059,0.000000
+0,1,30607,7.217695,-4.981779,-4.511059,0.000000
+0,1,30612,7.217695,-4.981779,-4.511059,0.000000
+0,1,30617,7.296148,-5.021005,-4.628739,0.000000
+0,1,30622,7.296148,-5.021005,-4.628739,0.000000
+0,1,30627,7.453054,-5.021005,-4.746419,0.000000
+0,1,30632,7.453054,-5.021005,-4.746419,0.000000
+0,1,30637,7.492281,-5.021005,-4.785645,0.000000
+0,1,30642,7.492281,-5.021005,-4.785645,0.000000
+0,1,30647,7.453054,-5.099459,-4.785645,0.000000
+0,1,30652,7.453054,-5.099459,-4.785645,0.000000
+0,1,30657,7.413828,-5.413271,-4.667965,0.000000
+0,1,30662,7.413828,-5.413271,-4.667965,0.000000
+0,1,30667,7.453054,-5.570178,-4.667965,0.000000
+0,1,30672,7.453054,-5.570178,-4.667965,0.000000
+0,1,30677,7.531507,-5.805537,-4.667965,0.000000
+0,1,30682,7.531507,-5.805537,-4.667965,0.000000
+0,1,30687,7.609961,-5.923217,-4.746419,0.000000
+0,1,30692,7.609961,-5.923217,-4.746419,0.000000
+0,1,30697,7.806094,-5.962444,-4.550286,0.000000
+0,1,30702,7.806094,-5.962444,-4.550286,0.000000
+0,1,30707,7.923774,-6.040897,-4.511059,0.000000
+0,1,30712,7.923774,-6.040897,-4.511059,0.000000
+0,1,30717,8.041453,-5.962444,-4.471833,0.000000
+0,1,30722,8.041453,-5.962444,-4.471833,0.000000
+0,1,30727,8.080680,-6.040897,-4.432606,0.000000
+0,1,30732,8.080680,-6.040897,-4.432606,0.000000
+0,1,30737,8.198359,-6.276257,-4.550286,0.000000
+0,1,30742,8.198359,-6.276257,-4.550286,0.000000
+0,1,30747,8.355267,-6.354709,-4.589512,0.000000
+0,1,30752,8.355267,-6.354709,-4.589512,0.000000
+0,1,30757,8.590626,-6.315483,-4.667965,0.000000
+0,1,30762,8.590626,-6.315483,-4.667965,0.000000
+0,1,30767,8.590626,-6.080123,-4.707192,0.000000
+0,1,30772,8.590626,-6.080123,-4.707192,0.000000
+0,1,30777,8.512173,-5.805537,-4.707192,0.000000
+0,1,30782,8.512173,-5.805537,-4.707192,0.000000
+0,1,30787,8.237586,-5.687858,-4.432606,0.000000
+0,1,30792,8.237586,-5.687858,-4.432606,0.000000
+0,1,30797,8.041453,-5.530951,-4.393379,0.000000
+0,1,30802,8.041453,-5.530951,-4.393379,0.000000
+0,1,30807,7.884547,-5.805537,-4.354153,0.000000
+0,1,30812,7.884547,-5.805537,-4.354153,0.000000
+0,1,30817,8.119907,-6.903882,-4.197247,0.000000
+0,1,30822,8.119907,-6.903882,-4.197247,0.000000
+0,1,30827,8.119907,-7.609961,-4.236473,0.000000
+0,1,30832,8.119907,-7.609961,-4.236473,0.000000
+0,1,30837,8.119907,-7.531507,-4.589512,0.000000
+0,1,30842,8.119907,-7.531507,-4.589512,0.000000
+0,1,30847,8.002227,-7.256921,-4.628739,0.000000
+0,1,30852,8.002227,-7.256921,-4.628739,0.000000
+0,1,30857,8.041453,-7.139242,-4.667965,0.000000
+0,1,30862,8.041453,-7.139242,-4.667965,0.000000
+0,1,30867,8.198359,-7.021562,-4.628739,0.000000
+0,1,30872,8.198359,-7.021562,-4.628739,0.000000
+0,1,30877,8.276814,-6.786202,-4.707192,0.000000
+0,1,30882,8.276814,-6.786202,-4.707192,0.000000
+0,1,30887,8.433720,-6.629296,-4.864099,0.000000
+0,1,30892,8.433720,-6.629296,-4.864099,0.000000
+0,1,30897,8.472946,-6.354709,-4.942552,0.000000
+0,1,30902,8.472946,-6.354709,-4.942552,0.000000
+0,1,30907,8.394493,-6.040897,-5.217138,0.000000
+0,1,30912,8.394493,-6.040897,-5.217138,0.000000
+0,1,30917,8.198359,-5.923217,-5.138685,0.000000
+0,1,30922,8.198359,-5.923217,-5.138685,0.000000
+0,1,30927,7.845320,-5.727084,-5.060232,0.000000
+0,1,30932,7.845320,-5.727084,-5.060232,0.000000
+0,1,30937,7.453054,-5.766310,-4.824872,0.000000
+0,1,30942,7.453054,-5.766310,-4.824872,0.000000
+0,1,30947,7.100015,-5.844764,-4.667965,0.000000
+0,1,30952,7.100015,-5.844764,-4.667965,0.000000
+0,1,30957,6.982335,-5.923217,-4.589512,0.000000
+0,1,30962,6.982335,-5.923217,-4.589512,0.000000
+0,1,30967,6.864655,-6.040897,-4.354153,0.000000
+0,1,30972,6.864655,-6.040897,-4.354153,0.000000
+0,1,30977,6.668522,-5.923217,-4.197247,0.000000
+0,1,30982,6.668522,-5.923217,-4.197247,0.000000
+0,1,30987,6.511616,-6.119350,-4.001113,0.000000
+0,1,30992,6.511616,-6.119350,-4.001113,0.000000
+0,1,30997,6.472389,-6.197803,-4.001113,0.000000
+0,1,31002,6.472389,-6.197803,-4.001113,0.000000
+0,1,31007,6.433163,-6.393936,-3.883434,0.000000
+0,1,31012,6.433163,-6.393936,-3.883434,0.000000
+0,1,31017,6.315483,-6.511616,-3.765754,0.000000
+0,1,31022,6.315483,-6.511616,-3.765754,0.000000
+0,1,31027,6.276257,-6.668522,-3.765754,0.000000
+0,1,31032,6.276257,-6.668522,-3.765754,0.000000
+0,1,31037,6.237030,-6.864655,-3.687301,0.000000
+0,1,31042,6.237030,-6.864655,-3.687301,0.000000
+0,1,31047,6.197803,-6.943109,-3.569621,0.000000
+0,1,31052,6.197803,-6.943109,-3.569621,0.000000
+0,1,31057,6.197803,-6.943109,-3.569621,0.000000
+0,1,31062,6.158576,-6.982335,-3.569621,0.000000
+0,1,31067,6.158576,-6.982335,-3.569621,0.000000
+0,1,31072,6.080123,-6.903882,-3.608848,0.000000
+0,1,31077,6.080123,-6.903882,-3.608848,0.000000
+0,1,31082,6.158576,-6.825429,-3.961887,0.000000
+0,1,31087,6.158576,-6.825429,-3.961887,0.000000
+0,1,31092,6.393936,-6.668522,-3.922660,0.000000
+0,1,31097,6.393936,-6.668522,-3.922660,0.000000
+0,1,31102,6.354709,-6.433163,-4.236473,0.000000
+0,1,31107,6.354709,-6.433163,-4.236473,0.000000
+0,1,31112,6.197803,-6.197803,-4.236473,0.000000
+0,1,31117,6.197803,-6.197803,-4.236473,0.000000
+0,1,31122,6.197803,-6.158576,-4.197247,0.000000
+0,1,31127,6.197803,-6.158576,-4.197247,0.000000
+0,1,31132,6.080123,-6.040897,-4.236473,0.000000
+0,1,31137,6.080123,-6.040897,-4.236473,0.000000
+0,1,31142,6.040897,-6.119350,-4.236473,0.000000
+0,1,31147,6.040897,-6.119350,-4.236473,0.000000
+0,1,31152,5.883990,-5.923217,-4.236473,0.000000
+0,1,31157,5.883990,-5.923217,-4.236473,0.000000
+0,1,31162,5.766310,-6.001670,-3.961887,0.000000
+0,1,31167,5.766310,-6.001670,-3.961887,0.000000
+0,1,31172,5.727084,-5.923217,-3.883434,0.000000
+0,1,31177,5.727084,-5.923217,-3.883434,0.000000
+0,1,31182,5.766310,-5.883990,-3.804980,0.000000
+0,1,31187,5.766310,-5.883990,-3.804980,0.000000
+0,1,31192,5.766310,-5.883990,-3.608848,0.000000
+0,1,31197,5.766310,-5.883990,-3.608848,0.000000
+0,1,31202,5.687858,-5.883990,-3.491168,0.000000
+0,1,31207,5.687858,-5.883990,-3.491168,0.000000
+0,1,31212,5.687858,-5.805537,-3.373488,0.000000
+0,1,31217,5.687858,-5.805537,-3.373488,0.000000
+0,1,31222,5.687858,-5.687858,-3.373488,0.000000
+0,1,31227,5.687858,-5.687858,-3.373488,0.000000
+0,1,31232,5.687858,-5.609404,-3.334261,0.000000
+0,1,31237,5.687858,-5.609404,-3.334261,0.000000
+0,1,31242,5.687858,-5.609404,-3.177355,0.000000
+0,1,31247,5.687858,-5.609404,-3.177355,0.000000
+0,1,31252,5.648631,-5.609404,-3.138128,0.000000
+0,1,31257,5.648631,-5.609404,-3.138128,0.000000
+0,1,31262,5.570178,-5.570178,-3.216581,0.000000
+0,1,31267,5.570178,-5.570178,-3.216581,0.000000
+0,1,31272,5.570178,-5.570178,-3.098902,0.000000
+0,1,31277,5.570178,-5.570178,-3.098902,0.000000
+0,1,31282,5.530951,-5.609404,-2.981222,0.000000
+0,1,31287,5.530951,-5.609404,-2.981222,0.000000
+0,1,31292,5.530951,-5.609404,-2.902768,0.000000
+0,1,31297,5.530951,-5.609404,-2.902768,0.000000
+0,1,31302,5.687858,-5.805537,-2.902768,0.000000
+0,1,31307,5.687858,-5.805537,-2.902768,0.000000
+0,1,31312,5.962444,-5.962444,-2.941995,0.000000
+0,1,31317,5.962444,-5.962444,-2.941995,0.000000
+0,1,31322,6.119350,-6.119350,-2.981222,0.000000
+0,1,31327,6.119350,-6.119350,-2.981222,0.000000
+0,1,31332,6.433163,-6.197803,-2.941995,0.000000
+0,1,31337,6.433163,-6.197803,-2.941995,0.000000
+0,1,31342,6.707749,-6.276257,-3.059675,0.000000
+0,1,31347,6.707749,-6.276257,-3.059675,0.000000
+0,1,31352,7.060789,-6.472389,-3.255808,0.000000
+0,1,31357,7.060789,-6.472389,-3.255808,0.000000
+0,1,31362,7.335374,-6.590069,-3.255808,0.000000
+0,1,31367,7.335374,-6.590069,-3.255808,0.000000
+0,1,31372,7.531507,-6.393936,-3.334261,0.000000
+0,1,31377,7.531507,-6.393936,-3.334261,0.000000
+0,1,31382,7.609961,-6.629296,-3.648074,0.000000
+0,1,31387,7.609961,-6.629296,-3.648074,0.000000
+0,1,31392,7.570734,-6.707749,-3.883434,0.000000
+0,1,31397,7.570734,-6.707749,-3.883434,0.000000
+0,1,31402,7.374601,-6.707749,-3.883434,0.000000
+0,1,31407,7.374601,-6.707749,-3.883434,0.000000
+0,1,31412,7.296148,-7.100015,-4.079566,0.000000
+0,1,31417,7.296148,-7.100015,-4.079566,0.000000
+0,1,31422,7.256921,-7.492281,-4.079566,0.000000
+0,1,31427,7.256921,-7.492281,-4.079566,0.000000
+0,1,31432,7.413828,-7.884547,-4.197247,0.000000
+0,1,31437,7.413828,-7.884547,-4.197247,0.000000
+0,1,31442,7.570734,-8.119907,-4.393379,0.000000
+0,1,31447,7.570734,-8.119907,-4.393379,0.000000
+0,1,31452,7.766868,-8.433720,-4.589512,0.000000
+0,1,31457,7.766868,-8.433720,-4.589512,0.000000
+0,1,31462,7.649188,-8.472946,-4.746419,0.000000
+0,1,31467,7.649188,-8.472946,-4.746419,0.000000
+0,1,31472,7.688414,-8.159133,-4.746419,0.000000
+0,1,31477,7.688414,-8.159133,-4.746419,0.000000
+0,1,31482,7.727641,-7.570734,-4.903325,0.000000
+0,1,31487,7.727641,-7.570734,-4.903325,0.000000
+0,1,31492,7.649188,-6.943109,-4.903325,0.000000
+0,1,31497,7.649188,-6.943109,-4.903325,0.000000
+0,1,31502,7.806094,-6.276257,-4.981779,0.000000
+0,1,31507,7.688414,-6.276257,-4.981779,0.000000
+0,1,31512,7.688414,-6.276257,-4.981779,0.000000
+0,1,31517,7.766868,-5.530951,-5.177911,0.000000
+0,1,31522,7.766868,-5.530951,-5.177911,0.000000
+0,1,31527,7.766868,-4.864099,-5.060232,0.000000
+0,1,31532,7.766868,-4.864099,-5.060232,0.000000
+0,1,31537,7.766868,-4.275700,-4.981779,0.000000
+0,1,31542,7.766868,-4.275700,-4.981779,0.000000
+0,1,31547,7.727641,-3.844207,-4.785645,0.000000
+0,1,31552,7.727641,-3.844207,-4.785645,0.000000
+0,1,31557,7.766868,-3.648074,-4.628739,0.000000
+0,1,31562,7.766868,-3.648074,-4.628739,0.000000
+0,1,31567,7.806094,-3.648074,-4.746419,0.000000
+0,1,31572,7.806094,-3.648074,-4.746419,0.000000
+0,1,31577,7.806094,-3.804980,-4.707192,0.000000
+0,1,31582,7.806094,-3.804980,-4.707192,0.000000
+0,1,31587,7.963000,-4.118793,-4.707192,0.000000
+0,1,31592,7.963000,-4.118793,-4.707192,0.000000
+0,1,31597,7.923774,-4.393379,-4.864099,0.000000
+0,1,31602,7.923774,-4.393379,-4.864099,0.000000
+0,1,31607,7.963000,-4.550286,-4.981779,0.000000
+0,1,31612,7.963000,-4.550286,-4.981779,0.000000
+0,1,31617,8.355267,-4.824872,-5.256365,0.000000
+0,1,31622,8.355267,-4.824872,-5.256365,0.000000
+0,1,31627,8.708306,-4.864099,-5.374045,0.000000
+0,1,31632,8.708306,-4.864099,-5.374045,0.000000
+0,1,31637,9.061345,-4.746419,-5.491724,0.000000
+0,1,31642,9.061345,-4.746419,-5.491724,0.000000
+0,1,31647,9.296705,-4.667965,-5.452498,0.000000
+0,1,31652,9.296705,-4.667965,-5.452498,0.000000
+0,1,31657,9.179025,-4.628739,-5.530951,0.000000
+0,1,31662,9.179025,-4.628739,-5.530951,0.000000
+0,1,31667,9.139798,-4.589512,-5.687858,0.000000
+0,1,31672,9.139798,-4.589512,-5.687858,0.000000
+0,1,31677,8.943666,-4.667965,-5.570178,0.000000
+0,1,31682,8.943666,-4.667965,-5.570178,0.000000
+0,1,31687,8.669080,-4.707192,-5.452498,0.000000
+0,1,31692,8.669080,-4.707192,-5.452498,0.000000
+0,1,31697,8.551399,-4.864099,-5.217138,0.000000
+0,1,31702,8.551399,-4.864099,-5.217138,0.000000
+0,1,31707,7.845320,-4.785645,-5.138685,0.000000
+0,1,31712,7.845320,-4.785645,-5.138685,0.000000
+0,1,31717,7.492281,-4.785645,-4.903325,0.000000
+0,1,31722,7.492281,-4.785645,-4.903325,0.000000
+0,1,31727,6.943109,-4.824872,-4.785645,0.000000
+0,1,31732,6.943109,-4.824872,-4.785645,0.000000
+0,1,31737,6.668522,-5.021005,-4.667965,0.000000
+0,1,31742,6.668522,-5.021005,-4.667965,0.000000
+0,1,31747,6.354709,-4.785645,-4.432606,0.000000
+0,1,31752,6.354709,-4.785645,-4.432606,0.000000
+0,1,31757,6.197803,-4.746419,-4.393379,0.000000
+0,1,31762,6.197803,-4.746419,-4.393379,0.000000
+0,1,31767,6.197803,-4.824872,-4.118793,0.000000
+0,1,31772,6.197803,-4.824872,-4.118793,0.000000
+0,1,31777,6.197803,-4.903325,-3.765754,0.000000
+0,1,31782,6.197803,-4.903325,-3.765754,0.000000
+0,1,31787,6.197803,-4.864099,-3.765754,0.000000
+0,1,31792,6.197803,-4.864099,-3.765754,0.000000
+0,1,31797,6.237030,-5.060232,-3.608848,0.000000
+0,1,31802,6.237030,-5.060232,-3.608848,0.000000
+0,1,31807,6.197803,-5.138685,-3.569621,0.000000
+0,1,31812,6.197803,-5.138685,-3.569621,0.000000
+0,1,31817,6.158576,-5.295591,-3.451941,0.000000
+0,1,31822,6.158576,-5.295591,-3.451941,0.000000
+0,1,31827,6.237030,-5.452498,-3.334261,0.000000
+0,1,31832,6.237030,-5.452498,-3.334261,0.000000
+0,1,31837,6.354709,-5.491724,-3.530394,0.000000
+0,1,31842,6.354709,-5.491724,-3.530394,0.000000
+0,1,31847,6.550843,-5.452498,-3.726527,0.000000
+0,1,31852,6.550843,-5.452498,-3.726527,0.000000
+0,1,31857,6.707749,-5.452498,-3.844207,0.000000
+0,1,31862,6.707749,-5.452498,-3.844207,0.000000
+0,1,31867,6.825429,-5.452498,-3.765754,0.000000
+0,1,31872,6.825429,-5.452498,-3.765754,0.000000
+0,1,31877,7.021562,-5.334818,-3.922660,0.000000
+0,1,31882,7.021562,-5.334818,-3.922660,0.000000
+0,1,31887,7.021562,-5.256365,-4.040340,0.000000
+0,1,31892,7.021562,-5.256365,-4.040340,0.000000
+0,1,31897,7.060789,-5.256365,-4.079566,0.000000
+0,1,31902,7.060789,-5.256365,-4.079566,0.000000
+0,1,31907,7.139242,-5.334818,-4.197247,0.000000
+0,1,31912,7.139242,-5.334818,-4.197247,0.000000
+0,1,31917,7.100015,-5.374045,-4.432606,0.000000
+0,1,31922,7.100015,-5.374045,-4.432606,0.000000
+0,1,31927,7.296148,-5.334818,-4.354153,0.000000
+0,1,31932,7.296148,-5.334818,-4.354153,0.000000
+0,1,31937,7.335374,-5.413271,-4.393379,0.000000
+0,1,31942,7.335374,-5.413271,-4.393379,0.000000
+0,1,31947,7.453054,-5.413271,-4.314926,0.000000
+0,1,31952,7.453054,-5.413271,-4.314926,0.000000
+0,1,31957,7.453054,-5.413271,-4.314926,0.000000
+0,1,31962,7.609961,-5.295591,-4.236473,0.000000
+0,1,31967,7.609961,-5.295591,-4.236473,0.000000
+0,1,31972,7.923774,-5.334818,-4.197247,0.000000
+0,1,31977,7.923774,-5.334818,-4.197247,0.000000
+0,1,31982,8.119907,-5.413271,-4.236473,0.000000
+0,1,31987,8.119907,-5.413271,-4.236473,0.000000
+0,1,31992,8.433720,-5.334818,-4.432606,0.000000
+0,1,31997,8.433720,-5.334818,-4.432606,0.000000
+0,1,32002,8.786758,-5.530951,-4.471833,0.000000
+0,1,32007,8.786758,-5.530951,-4.471833,0.000000
+0,1,32012,8.982892,-5.491724,-4.511059,0.000000
+0,1,32017,8.982892,-5.491724,-4.511059,0.000000
+0,1,32022,9.100572,-5.452498,-4.589512,0.000000
+0,1,32027,9.100572,-5.452498,-4.589512,0.000000
+0,1,32032,9.061345,-5.530951,-4.550286,0.000000
+0,1,32037,9.061345,-5.530951,-4.550286,0.000000
+0,1,32042,8.904439,-5.609404,-4.354153,0.000000
+0,1,32047,8.904439,-5.609404,-4.354153,0.000000
+0,1,32052,8.943666,-5.687858,-4.432606,0.000000
+0,1,32057,8.943666,-5.687858,-4.432606,0.000000
+0,1,32062,8.825986,-5.883990,-4.275700,0.000000
+0,1,32067,8.825986,-5.883990,-4.275700,0.000000
+0,1,32072,8.747532,-6.040897,-4.236473,0.000000
+0,1,32077,8.747532,-6.040897,-4.236473,0.000000
+0,1,32082,8.669080,-6.825429,-3.922660,0.000000
+0,1,32087,8.669080,-6.825429,-3.922660,0.000000
+0,1,32092,8.747532,-7.570734,-3.726527,0.000000
+0,1,32097,8.747532,-7.570734,-3.726527,0.000000
+0,1,32102,8.669080,-7.923774,-3.961887,0.000000
+0,1,32107,8.669080,-7.923774,-3.961887,0.000000
+0,1,32112,8.747532,-8.159133,-4.236473,0.000000
+0,1,32117,8.747532,-8.159133,-4.236473,0.000000
+0,1,32122,9.335931,-8.237586,-3.648074,0.000000
+0,1,32127,9.335931,-8.237586,-3.648074,0.000000
+0,1,32132,9.139798,-7.453054,-4.393379,0.000000
+0,1,32137,9.139798,-7.453054,-4.393379,0.000000
+0,1,32142,9.453611,-7.374601,-3.373488,0.000000
+0,1,32147,9.453611,-7.374601,-3.373488,0.000000
+0,1,32152,9.296705,-6.315483,-3.412714,0.000000
+0,1,32157,9.296705,-6.315483,-3.412714,0.000000
+0,1,32162,8.982892,-5.648631,-3.373488,0.000000
+0,1,32167,8.982892,-5.648631,-3.373488,0.000000
+0,1,32172,8.825986,-5.844764,-3.648074,0.000000
+0,1,32177,8.825986,-5.844764,-3.648074,0.000000
+0,1,32182,8.590626,-6.276257,-3.569621,0.000000
+0,1,32187,8.590626,-6.276257,-3.569621,0.000000
+0,1,32192,8.237586,-6.393936,-3.922660,0.000000
+0,1,32197,8.237586,-6.393936,-3.922660,0.000000
+0,1,32202,7.806094,-6.668522,-3.844207,0.000000
+0,1,32207,7.806094,-6.668522,-3.844207,0.000000
+0,1,32212,7.531507,-6.943109,-3.883434,0.000000
+0,1,32217,7.531507,-6.943109,-3.883434,0.000000
+0,1,32222,7.178468,-6.943109,-3.922660,0.000000
+0,1,32227,7.178468,-6.943109,-3.922660,0.000000
+0,1,32232,6.864655,-6.550843,-3.687301,0.000000
+0,1,32237,6.864655,-6.550843,-3.687301,0.000000
+0,1,32242,6.629296,-5.962444,-3.451941,0.000000
+0,1,32247,6.629296,-5.962444,-3.451941,0.000000
+0,1,32252,6.590069,-5.334818,-3.216581,0.000000
+0,1,32257,6.590069,-5.334818,-3.216581,0.000000
+0,1,32262,6.590069,-4.864099,-3.020448,0.000000
+0,1,32267,6.590069,-4.864099,-3.020448,0.000000
+0,1,32272,6.590069,-4.707192,-3.059675,0.000000
+0,1,32277,6.590069,-4.707192,-3.059675,0.000000
+0,1,32282,6.433163,-4.511059,-2.902768,0.000000
+0,1,32287,6.433163,-4.511059,-2.902768,0.000000
+0,1,32292,6.158576,-4.589512,-2.941995,0.000000
+0,1,32297,6.158576,-4.589512,-2.941995,0.000000
+0,1,32302,5.883990,-4.746419,-2.706636,0.000000
+0,1,32307,5.883990,-4.746419,-2.706636,0.000000
+0,1,32312,5.923217,-4.824872,-2.824315,0.000000
+0,1,32317,5.923217,-4.824872,-2.824315,0.000000
+0,1,32322,5.805537,-4.981779,-2.824315,0.000000
+0,1,32327,5.805537,-4.981779,-2.824315,0.000000
+0,1,32332,5.609404,-5.060232,-2.863542,0.000000
+0,1,32337,5.609404,-5.060232,-2.863542,0.000000
+0,1,32342,5.530951,-5.217138,-2.941995,0.000000
+0,1,32347,5.530951,-5.217138,-2.941995,0.000000
+0,1,32352,5.413271,-5.452498,-3.020448,0.000000
+0,1,32357,5.413271,-5.452498,-3.020448,0.000000
+0,1,32362,5.609404,-5.648631,-3.255808,0.000000
+0,1,32367,5.609404,-5.648631,-3.255808,0.000000
+0,1,32372,5.766310,-5.844764,-3.648074,0.000000
+0,1,32377,5.766310,-5.844764,-3.648074,0.000000
+0,1,32382,5.766310,-5.962444,-3.844207,0.000000
+0,1,32387,5.766310,-5.962444,-3.844207,0.000000
+0,1,32392,5.727084,-5.962444,-4.079566,0.000000
+0,1,32397,5.727084,-5.962444,-4.079566,0.000000
+0,1,32402,5.727084,-6.001670,-4.314926,0.000000
+0,1,32407,5.727084,-6.001670,-4.314926,0.000000
+0,1,32412,5.727084,-6.001670,-4.471833,0.000000
+0,1,32417,5.648631,-5.962444,-4.550286,0.000000
+0,1,32422,5.648631,-5.962444,-4.550286,0.000000
+0,1,32427,5.648631,-6.001670,-4.903325,0.000000
+0,1,32432,5.648631,-6.001670,-4.903325,0.000000
+0,1,32437,5.570178,-6.119350,-5.099459,0.000000
+0,1,32442,5.570178,-6.119350,-5.099459,0.000000
+0,1,32447,5.530951,-6.040897,-5.374045,0.000000
+0,1,32452,5.530951,-6.040897,-5.374045,0.000000
+0,1,32457,5.374045,-6.237030,-5.413271,0.000000
+0,1,32462,5.374045,-6.237030,-5.413271,0.000000
+0,1,32467,5.256365,-6.197803,-5.374045,0.000000
+0,1,32472,5.256365,-6.197803,-5.374045,0.000000
+0,1,32477,5.060232,-6.276257,-5.491724,0.000000
+0,1,32482,5.060232,-6.276257,-5.491724,0.000000
+0,1,32487,5.099459,-6.393936,-5.256365,0.000000
+0,1,32492,5.099459,-6.393936,-5.256365,0.000000
+0,1,32497,5.099459,-6.315483,-5.217138,0.000000
+0,1,32502,5.099459,-6.315483,-5.217138,0.000000
+0,1,32507,5.295591,-6.276257,-5.021005,0.000000
+0,1,32512,5.295591,-6.276257,-5.021005,0.000000
+0,1,32517,5.452498,-6.237030,-4.824872,0.000000
+0,1,32522,5.452498,-6.237030,-4.824872,0.000000
+0,1,32527,5.727084,-6.119350,-4.746419,0.000000
+0,1,32532,5.727084,-6.119350,-4.746419,0.000000
+0,1,32537,5.805537,-6.001670,-4.667965,0.000000
+0,1,32542,5.805537,-6.001670,-4.667965,0.000000
+0,1,32547,5.962444,-5.923217,-4.667965,0.000000
+0,1,32552,5.962444,-5.923217,-4.667965,0.000000
+0,1,32557,6.001670,-5.923217,-4.471833,0.000000
+0,1,32562,6.001670,-5.923217,-4.471833,0.000000
+0,1,32567,6.080123,-5.883990,-4.550286,0.000000
+0,1,32572,6.080123,-5.883990,-4.550286,0.000000
+0,1,32577,6.040897,-5.844764,-4.511059,0.000000
+0,1,32582,6.040897,-5.844764,-4.511059,0.000000
+0,1,32587,6.001670,-5.883990,-4.471833,0.000000
+0,1,32592,6.001670,-5.883990,-4.471833,0.000000
+0,1,32597,6.080123,-5.844764,-4.511059,0.000000
+0,1,32602,6.080123,-5.844764,-4.511059,0.000000
+0,1,32607,6.119350,-6.001670,-4.471833,0.000000
+0,1,32612,6.119350,-6.001670,-4.471833,0.000000
+0,1,32617,6.237030,-6.040897,-4.628739,0.000000
+0,1,32622,6.237030,-6.040897,-4.628739,0.000000
+0,1,32627,6.315483,-6.315483,-4.589512,0.000000
+0,1,32632,6.315483,-6.315483,-4.589512,0.000000
+0,1,32637,6.315483,-6.629296,-4.432606,0.000000
+0,1,32642,6.315483,-6.629296,-4.432606,0.000000
+0,1,32647,6.354709,-6.746975,-4.589512,0.000000
+0,1,32652,6.354709,-6.746975,-4.589512,0.000000
+0,1,32657,6.629296,-6.864655,-4.511059,0.000000
+0,1,32662,6.629296,-6.864655,-4.511059,0.000000
+0,1,32667,6.746975,-7.021562,-4.471833,0.000000
+0,1,32672,6.746975,-7.021562,-4.471833,0.000000
+0,1,32677,7.021562,-7.021562,-4.511059,0.000000
+0,1,32682,7.021562,-7.021562,-4.511059,0.000000
+0,1,32687,7.296148,-7.021562,-4.667965,0.000000
+0,1,32692,7.296148,-7.021562,-4.667965,0.000000
+0,1,32697,7.413828,-6.903882,-4.707192,0.000000
+0,1,32702,7.413828,-6.903882,-4.707192,0.000000
+0,1,32707,7.492281,-6.903882,-4.785645,0.000000
+0,1,32712,7.492281,-6.903882,-4.785645,0.000000
+0,1,32717,7.492281,-6.943109,-5.021005,0.000000
+0,1,32722,7.492281,-6.943109,-5.021005,0.000000
+0,1,32727,7.531507,-6.825429,-5.177911,0.000000
+0,1,32732,7.531507,-6.825429,-5.177911,0.000000
+0,1,32737,7.256921,-6.864655,-5.217138,0.000000
+0,1,32742,7.256921,-6.864655,-5.217138,0.000000
+0,1,32747,7.021562,-6.864655,-5.177911,0.000000
+0,1,32752,7.021562,-6.864655,-5.177911,0.000000
+0,1,32757,6.707749,-6.864655,-5.060232,0.000000
+0,1,32762,6.707749,-6.864655,-5.060232,0.000000
+0,1,32767,6.707749,-7.335374,-4.942552,0.000000
+0,1,32772,6.707749,-7.335374,-4.942552,0.000000
+0,1,32777,6.982335,-8.080680,-4.746419,0.000000
+0,1,32782,6.982335,-8.080680,-4.746419,0.000000
+0,1,32787,7.296148,-8.512173,-4.746419,0.000000
+0,1,32792,7.296148,-8.512173,-4.746419,0.000000
+0,1,32797,7.374601,-8.629852,-4.785645,0.000000
+0,1,32802,7.374601,-8.629852,-4.785645,0.000000
+0,1,32807,7.609961,-8.904439,-4.785645,0.000000
+0,1,32812,7.609961,-8.904439,-4.785645,0.000000
+0,1,32817,7.531507,-8.472946,-5.177911,0.000000
+0,1,32822,7.531507,-8.472946,-5.177911,0.000000
+0,1,32827,7.492281,-8.198359,-5.374045,0.000000
+0,1,32832,7.492281,-8.198359,-5.374045,0.000000
+0,1,32837,7.256921,-7.531507,-5.570178,0.000000
+0,1,32842,7.256921,-7.531507,-5.570178,0.000000
+0,1,32847,7.060789,-6.943109,-5.570178,0.000000
+0,1,32852,7.060789,-6.943109,-5.570178,0.000000
+0,1,32857,7.060789,-6.158576,-5.923217,0.000000
+0,1,32862,6.825429,-6.197803,-5.923217,0.000000
+0,1,32867,6.825429,-6.197803,-5.923217,0.000000
+0,1,32872,6.825429,-5.452498,-6.040897,0.000000
+0,1,32877,6.825429,-5.452498,-6.040897,0.000000
+0,1,32882,6.864655,-4.981779,-6.119350,0.000000
+0,1,32887,6.864655,-4.981779,-6.119350,0.000000
+0,1,32892,6.943109,-5.099459,-6.158576,0.000000
+0,1,32897,6.943109,-5.099459,-6.158576,0.000000
+0,1,32902,7.217695,-5.452498,-5.727084,0.000000
+0,1,32907,7.217695,-5.452498,-5.727084,0.000000
+0,1,32912,7.374601,-5.727084,-5.727084,0.000000
+0,1,32917,7.374601,-5.727084,-5.727084,0.000000
+0,1,32922,7.609961,-5.923217,-5.570178,0.000000
+0,1,32927,7.609961,-5.923217,-5.570178,0.000000
+0,1,32932,7.727641,-5.962444,-5.374045,0.000000
+0,1,32937,7.727641,-5.962444,-5.374045,0.000000
+0,1,32942,7.963000,-5.923217,-5.727084,0.000000
+0,1,32947,7.963000,-5.923217,-5.727084,0.000000
+0,1,32952,8.629852,-5.648631,-5.687858,0.000000
+0,1,32957,8.629852,-5.648631,-5.687858,0.000000
+0,1,32962,8.904439,-5.295591,-6.197803,0.000000
+0,1,32967,8.904439,-5.295591,-6.197803,0.000000
+0,1,32972,9.414385,-5.138685,-5.530951,0.000000
+0,1,32977,9.414385,-5.138685,-5.530951,0.000000
+0,1,32982,9.257479,-4.589512,-5.491724,0.000000
+0,1,32987,9.257479,-4.589512,-5.491724,0.000000
+0,1,32992,8.786758,-4.746419,-5.099459,0.000000
+0,1,32997,8.786758,-4.746419,-5.099459,0.000000
+0,1,33002,8.394493,-4.667965,-4.707192,0.000000
+0,1,33007,8.394493,-4.667965,-4.707192,0.000000
+0,1,33012,7.806094,-4.746419,-4.628739,0.000000
+0,1,33017,7.806094,-4.746419,-4.628739,0.000000
+0,1,33022,7.296148,-4.903325,-4.393379,0.000000
+0,1,33027,7.296148,-4.903325,-4.393379,0.000000
+0,1,33032,6.668522,-4.942552,-4.275700,0.000000
+0,1,33037,6.668522,-4.942552,-4.275700,0.000000
+0,1,33042,6.237030,-4.942552,-4.197247,0.000000
+0,1,33047,6.237030,-4.942552,-4.197247,0.000000
+0,1,33052,6.001670,-5.060232,-3.961887,0.000000
+0,1,33057,6.001670,-5.060232,-3.961887,0.000000
+0,1,33062,5.883990,-4.864099,-3.804980,0.000000
+0,1,33067,5.883990,-4.864099,-3.804980,0.000000
+0,1,33072,5.570178,-4.785645,-3.569621,0.000000
+0,1,33077,5.570178,-4.785645,-3.569621,0.000000
+0,1,33082,5.648631,-4.824872,-3.255808,0.000000
+0,1,33087,5.648631,-4.824872,-3.255808,0.000000
+0,1,33092,5.648631,-4.746419,-2.981222,0.000000
+0,1,33097,5.648631,-4.746419,-2.981222,0.000000
+0,1,33102,5.727084,-4.667965,-2.785089,0.000000
+0,1,33107,5.727084,-4.667965,-2.785089,0.000000
+0,1,33112,5.883990,-4.667965,-2.588956,0.000000
+0,1,33117,5.883990,-4.667965,-2.588956,0.000000
+0,1,33122,5.923217,-4.511059,-2.471276,0.000000
+0,1,33127,5.923217,-4.511059,-2.471276,0.000000
+0,1,33132,5.648631,-4.589512,-2.275143,0.000000
+0,1,33137,5.648631,-4.589512,-2.275143,0.000000
+0,1,33142,5.687858,-4.667965,-2.353596,0.000000
+0,1,33147,5.687858,-4.667965,-2.353596,0.000000
+0,1,33152,5.766310,-4.707192,-2.353596,0.000000
+0,1,33157,5.766310,-4.707192,-2.353596,0.000000
+0,1,33162,5.805537,-4.864099,-2.314370,0.000000
+0,1,33167,5.805537,-4.864099,-2.314370,0.000000
+0,1,33172,5.883990,-4.864099,-2.471276,0.000000
+0,1,33177,5.883990,-4.864099,-2.471276,0.000000
+0,1,33182,6.119350,-4.903325,-2.549729,0.000000
+0,1,33187,6.119350,-4.903325,-2.549729,0.000000
+0,1,33192,6.433163,-4.981779,-2.902768,0.000000
+0,1,33197,6.433163,-4.981779,-2.902768,0.000000
+0,1,33202,6.629296,-5.060232,-3.098902,0.000000
+0,1,33207,6.629296,-5.060232,-3.098902,0.000000
+0,1,33212,6.707749,-5.138685,-3.373488,0.000000
+0,1,33217,6.707749,-5.138685,-3.373488,0.000000
+0,1,33222,6.707749,-5.217138,-3.687301,0.000000
+0,1,33227,6.707749,-5.217138,-3.687301,0.000000
+0,1,33232,6.786202,-5.374045,-3.883434,0.000000
+0,1,33237,6.786202,-5.374045,-3.883434,0.000000
+0,1,33242,6.903882,-5.570178,-4.158020,0.000000
+0,1,33247,6.903882,-5.570178,-4.158020,0.000000
+0,1,33252,7.217695,-5.609404,-4.275700,0.000000
+0,1,33257,7.217695,-5.609404,-4.275700,0.000000
+0,1,33267,7.492281,-5.530951,-4.314926,0.000000
+0,1,33272,7.570734,-5.491724,-4.197247,0.000000
+0,1,33277,7.570734,-5.491724,-4.197247,0.000000
+0,1,33282,7.884547,-5.530951,-4.275700,0.000000
+0,1,33287,7.884547,-5.530951,-4.275700,0.000000
+0,1,33292,8.119907,-5.491724,-4.236473,0.000000
+0,1,33297,8.119907,-5.491724,-4.236473,0.000000
+0,1,33302,8.119907,-5.648631,-4.314926,0.000000
+0,1,33307,8.316040,-5.530951,-4.314926,0.000000
+0,1,33312,8.316040,-5.530951,-4.314926,0.000000
+0,1,33317,8.551399,-5.295591,-4.550286,0.000000
+0,1,33322,8.551399,-5.295591,-4.550286,0.000000
+0,1,33327,8.747532,-5.374045,-4.707192,0.000000
+0,1,33332,8.747532,-5.374045,-4.707192,0.000000
+0,1,33337,8.982892,-5.295591,-4.785645,0.000000
+0,1,33342,8.982892,-5.295591,-4.785645,0.000000
+0,1,33347,9.022119,-5.217138,-4.942552,0.000000
+0,1,33352,9.022119,-5.217138,-4.942552,0.000000
+0,1,33357,8.982892,-5.060232,-4.942552,0.000000
+0,1,33362,8.982892,-5.060232,-4.942552,0.000000
+0,1,33367,9.022119,-4.981779,-5.138685,0.000000
+0,1,33372,9.022119,-4.981779,-5.138685,0.000000
+0,1,33377,8.943666,-5.177911,-5.060232,0.000000
+0,1,33382,8.943666,-5.177911,-5.060232,0.000000
+0,1,33387,9.139798,-6.119350,-5.099459,0.000000
+0,1,33392,9.139798,-6.119350,-5.099459,0.000000
+0,1,33397,9.179025,-6.746975,-5.177911,0.000000
+0,1,33402,9.179025,-6.746975,-5.177911,0.000000
+0,1,33407,9.061345,-7.021562,-5.452498,0.000000
+0,1,33412,9.061345,-7.021562,-5.452498,0.000000
+0,1,33417,8.982892,-7.100015,-5.609404,0.000000
+0,1,33422,8.982892,-7.100015,-5.609404,0.000000
+0,1,33427,9.022119,-6.982335,-6.001670,0.000000
+0,1,33432,9.022119,-6.982335,-6.001670,0.000000
+0,1,33437,9.022119,-7.021562,-6.197803,0.000000
+0,1,33442,9.022119,-7.021562,-6.197803,0.000000
+0,1,33447,8.786758,-6.903882,-5.844764,0.000000
+0,1,33452,8.786758,-6.903882,-5.844764,0.000000
+0,1,33457,9.257479,-7.178468,-6.511616,0.000000
+0,1,33462,9.257479,-7.178468,-6.511616,0.000000
+0,1,33467,8.865212,-6.511616,-6.629296,0.000000
+0,1,33472,8.865212,-6.511616,-6.629296,0.000000
+0,1,33477,8.825986,-6.746975,-6.590069,0.000000
+0,1,33482,8.825986,-6.746975,-6.590069,0.000000
+0,1,33487,8.982892,-6.590069,-6.786202,0.000000
+0,1,33492,8.982892,-6.590069,-6.786202,0.000000
+0,1,33497,8.865212,-6.354709,-6.590069,0.000000
+0,1,33502,8.865212,-6.354709,-6.590069,0.000000
+0,1,33507,8.629852,-5.883990,-6.040897,0.000000
+0,1,33512,8.629852,-5.883990,-6.040897,0.000000
+0,1,33517,7.963000,-5.530951,-5.374045,0.000000
+0,1,33522,7.963000,-5.530951,-5.374045,0.000000
+0,1,33527,7.806094,-5.491724,-4.903325,0.000000
+0,1,33532,7.806094,-5.491724,-4.903325,0.000000
+0,1,33537,7.492281,-5.570178,-4.393379,0.000000
+0,1,33542,7.492281,-5.570178,-4.393379,0.000000
+0,1,33547,7.335374,-5.491724,-4.079566,0.000000
+0,1,33552,7.335374,-5.491724,-4.079566,0.000000
+0,1,33557,6.903882,-5.687858,-3.648074,0.000000
+0,1,33562,6.903882,-5.687858,-3.648074,0.000000
+0,1,33567,6.668522,-5.805537,-3.569621,0.000000
+0,1,33572,6.668522,-5.805537,-3.569621,0.000000
+0,1,33577,6.393936,-6.080123,-3.412714,0.000000
+0,1,33582,6.393936,-6.080123,-3.412714,0.000000
+0,1,33587,6.197803,-6.354709,-3.216581,0.000000
+0,1,33592,6.197803,-6.354709,-3.216581,0.000000
+0,1,33597,6.119350,-6.707749,-3.138128,0.000000
+0,1,33602,6.119350,-6.707749,-3.138128,0.000000
+0,1,33607,5.962444,-6.786202,-3.020448,0.000000
+0,1,33612,5.962444,-6.786202,-3.020448,0.000000
+0,1,33617,5.883990,-6.864655,-3.177355,0.000000
+0,1,33622,5.883990,-6.864655,-3.177355,0.000000
+0,1,33627,5.962444,-6.864655,-3.295035,0.000000
+0,1,33632,5.962444,-6.864655,-3.295035,0.000000
+0,1,33637,5.923217,-6.786202,-3.451941,0.000000
+0,1,33642,5.923217,-6.786202,-3.451941,0.000000
+0,1,33647,5.805537,-6.472389,-3.608848,0.000000
+0,1,33652,5.805537,-6.472389,-3.608848,0.000000
+0,1,33657,5.883990,-6.197803,-3.883434,0.000000
+0,1,33662,5.883990,-6.197803,-3.883434,0.000000
+0,1,33667,5.883990,-6.001670,-3.922660,0.000000
+0,1,33672,5.883990,-6.001670,-3.922660,0.000000
+0,1,33677,5.805537,-5.962444,-3.961887,0.000000
+0,1,33682,5.805537,-5.962444,-3.961887,0.000000
+0,1,33687,5.648631,-5.727084,-4.001113,0.000000
+0,1,33692,5.648631,-5.727084,-4.001113,0.000000
+0,1,33697,5.530951,-5.766310,-3.961887,0.000000
+0,1,33702,5.530951,-5.766310,-3.961887,0.000000
+0,1,33707,5.452498,-5.844764,-4.118793,0.000000
+0,1,33712,5.452498,-5.844764,-4.118793,0.000000
+0,1,33717,5.334818,-5.883990,-4.001113,0.000000
+0,1,33722,5.334818,-5.883990,-4.001113,0.000000
+0,1,33727,5.060232,-6.080123,-3.922660,0.000000
+0,1,33732,5.060232,-6.080123,-3.922660,0.000000
+0,1,33737,4.903325,-6.158576,-3.804980,0.000000
+0,1,33742,4.903325,-6.158576,-3.804980,0.000000
+0,1,33747,4.746419,-6.276257,-3.765754,0.000000
+0,1,33752,4.746419,-6.276257,-3.765754,0.000000
+0,1,33757,4.746419,-6.276257,-3.765754,0.000000
+0,1,33762,4.746419,-6.276257,-3.687301,0.000000
+0,1,33767,4.746419,-6.276257,-3.687301,0.000000
+0,1,33772,4.707192,-6.276257,-3.530394,0.000000
+0,1,33777,4.707192,-6.276257,-3.530394,0.000000
+0,1,33782,4.903325,-6.237030,-3.530394,0.000000
+0,1,33787,4.903325,-6.237030,-3.530394,0.000000
+0,1,33792,4.981779,-6.197803,-3.295035,0.000000
+0,1,33797,4.981779,-6.197803,-3.295035,0.000000
+0,1,33802,5.177911,-6.040897,-3.334261,0.000000
+0,1,33807,5.177911,-6.040897,-3.334261,0.000000
+0,1,33812,5.374045,-5.805537,-3.098902,0.000000
+0,1,33817,5.374045,-5.805537,-3.098902,0.000000
+0,1,33822,5.491724,-5.766310,-3.020448,0.000000
+0,1,33827,5.491724,-5.766310,-3.020448,0.000000
+0,1,33832,5.570178,-5.570178,-3.098902,0.000000
+0,1,33837,5.570178,-5.570178,-3.098902,0.000000
+0,1,33842,5.844764,-5.609404,-3.216581,0.000000
+0,1,33847,5.844764,-5.609404,-3.216581,0.000000
+0,1,33852,5.844764,-5.530951,-3.255808,0.000000
+0,1,33857,5.844764,-5.530951,-3.255808,0.000000
+0,1,33862,5.962444,-5.530951,-3.255808,0.000000
+0,1,33867,5.962444,-5.530951,-3.255808,0.000000
+0,1,33872,6.119350,-5.648631,-3.295035,0.000000
+0,1,33877,6.119350,-5.648631,-3.295035,0.000000
+0,1,33882,6.197803,-5.687858,-3.255808,0.000000
+0,1,33887,6.197803,-5.687858,-3.255808,0.000000
+0,1,33892,5.334818,-5.530951,-3.765754,0.000000
+0,1,33897,5.334818,-5.530951,-3.765754,0.000000
+0,1,33902,6.511616,-6.668522,-3.098902,0.000000
+0,1,33907,6.511616,-6.668522,-3.098902,0.000000
+0,1,33912,5.844764,-6.001670,-3.177355,0.000000
+0,1,33917,5.844764,-6.001670,-3.177355,0.000000
+0,1,33922,5.805537,-6.393936,-3.844207,0.000000
+0,1,33927,5.805537,-6.393936,-3.844207,0.000000
+0,1,33932,6.707749,-7.335374,-3.412714,0.000000
+0,1,33937,6.707749,-7.335374,-3.412714,0.000000
+0,1,33942,6.864655,-6.668522,-3.608848,0.000000
+0,1,33947,6.864655,-6.668522,-3.608848,0.000000
+0,1,33952,6.746975,-6.707749,-3.844207,0.000000
+0,1,33957,6.746975,-6.707749,-3.844207,0.000000
+0,1,33962,6.707749,-7.021562,-4.236473,0.000000
+0,1,33967,6.707749,-7.021562,-4.236473,0.000000
+0,1,33972,7.492281,-6.825429,-4.118793,0.000000
+0,1,33977,7.492281,-6.825429,-4.118793,0.000000
+0,1,33982,7.609961,-7.100015,-4.001113,0.000000
+0,1,33987,7.609961,-7.100015,-4.001113,0.000000
+0,1,33992,7.531507,-7.100015,-4.628739,0.000000
+0,1,33997,7.531507,-7.100015,-4.628739,0.000000
+0,1,34002,7.727641,-7.060789,-4.550286,0.000000
+0,1,34007,7.727641,-7.060789,-4.550286,0.000000
+0,1,34012,7.492281,-6.825429,-4.628739,0.000000
+0,1,34017,7.492281,-6.825429,-4.628739,0.000000
+0,1,34022,7.453054,-6.629296,-4.589512,0.000000
+0,1,34027,7.453054,-6.629296,-4.589512,0.000000
+0,1,34032,7.335374,-6.550843,-4.393379,0.000000
+0,1,34037,7.335374,-6.550843,-4.393379,0.000000
+0,1,34042,7.256921,-6.354709,-4.432606,0.000000
+0,1,34047,7.256921,-6.354709,-4.432606,0.000000
+0,1,34052,7.256921,-6.197803,-4.393379,0.000000
+0,1,34057,7.256921,-6.197803,-4.393379,0.000000
+0,1,34062,7.374601,-5.962444,-4.432606,0.000000
+0,1,34067,7.374601,-5.962444,-4.432606,0.000000
+0,1,34072,7.492281,-6.472389,-4.079566,0.000000
+0,1,34077,7.492281,-6.472389,-4.079566,0.000000
+0,1,34082,7.256921,-7.021562,-3.961887,0.000000
+0,1,34087,7.256921,-7.021562,-3.961887,0.000000
+0,1,34092,7.884547,-6.590069,-4.079566,0.000000
+0,1,34097,7.884547,-6.590069,-4.079566,0.000000
+0,1,34102,8.512173,-7.649188,-4.628739,0.000000
+0,1,34107,8.512173,-7.649188,-4.628739,0.000000
+0,1,34112,9.100572,-8.080680,-4.746419,0.000000
+0,1,34117,9.100572,-8.080680,-4.746419,0.000000
+0,1,34122,9.375158,-8.002227,-5.099459,0.000000
+0,1,34127,9.375158,-8.002227,-5.099459,0.000000
+0,1,34132,9.492838,-7.570734,-5.060232,0.000000
+0,1,34137,9.492838,-7.570734,-5.060232,0.000000
+0,1,34142,9.061345,-6.668522,-5.021005,0.000000
+0,1,34147,9.061345,-6.668522,-5.021005,0.000000
+0,1,34152,8.512173,-6.354709,-5.177911,0.000000
+0,1,34157,8.512173,-6.354709,-5.177911,0.000000
+0,1,34162,8.472946,-6.040897,-5.491724,0.000000
+0,1,34167,8.472946,-6.040897,-5.491724,0.000000
+0,1,34172,8.198359,-5.334818,-5.727084,0.000000
+0,1,34177,8.198359,-5.334818,-5.727084,0.000000
+0,1,34182,7.963000,-4.864099,-5.844764,0.000000
+0,1,34187,7.963000,-4.864099,-5.844764,0.000000
+0,1,34192,7.727641,-4.471833,-5.844764,0.000000
+0,1,34197,7.727641,-4.471833,-5.844764,0.000000
+0,1,34202,7.492281,-4.628739,-5.648631,0.000000
+0,1,34207,7.492281,-4.628739,-5.648631,0.000000
+0,1,34212,7.492281,-4.628739,-5.648631,0.000000
+0,1,34217,7.178468,-4.864099,-5.452498,0.000000
+0,1,34222,7.178468,-4.864099,-5.452498,0.000000
+0,1,34227,7.100015,-5.021005,-5.962444,0.000000
+0,1,34232,7.100015,-5.021005,-5.962444,0.000000
+0,1,34237,7.335374,-5.413271,-5.727084,0.000000
+0,1,34242,7.335374,-5.413271,-5.727084,0.000000
+0,1,34247,7.413828,-5.491724,-6.001670,0.000000
+0,1,34252,7.413828,-5.491724,-6.001670,0.000000
+0,1,34257,7.453054,-5.609404,-6.040897,0.000000
+0,1,34262,7.453054,-5.609404,-6.040897,0.000000
+0,1,34267,7.570734,-5.491724,-6.158576,0.000000
+0,1,34272,7.570734,-5.491724,-6.158576,0.000000
+0,1,34277,7.845320,-5.334818,-6.119350,0.000000
+0,1,34282,7.845320,-5.334818,-6.119350,0.000000
+0,1,34287,7.923774,-5.256365,-5.962444,0.000000
+0,1,34292,7.923774,-5.256365,-5.962444,0.000000
+0,1,34297,8.119907,-5.060232,-5.648631,0.000000
+0,1,34302,8.119907,-5.060232,-5.648631,0.000000
+0,1,34307,8.080680,-5.021005,-5.374045,0.000000
+0,1,34312,8.080680,-5.021005,-5.374045,0.000000
+0,1,34317,8.002227,-4.785645,-5.060232,0.000000
+0,1,34322,8.002227,-4.785645,-5.060232,0.000000
+0,1,34327,7.806094,-4.864099,-5.256365,0.000000
+0,1,34332,7.806094,-4.864099,-5.256365,0.000000
+0,1,34337,7.531507,-4.785645,-5.138685,0.000000
+0,1,34342,7.531507,-4.785645,-5.138685,0.000000
+0,1,34347,7.178468,-4.824872,-4.864099,0.000000
+0,1,34352,7.178468,-4.824872,-4.864099,0.000000
+0,1,34357,6.943109,-4.864099,-4.589512,0.000000
+0,1,34362,6.943109,-4.864099,-4.589512,0.000000
+0,1,34367,6.590069,-4.864099,-4.550286,0.000000
+0,1,34372,6.590069,-4.864099,-4.550286,0.000000
+0,1,34377,6.315483,-4.785645,-4.197247,0.000000
+0,1,34382,6.315483,-4.785645,-4.197247,0.000000
+0,1,34387,6.080123,-4.746419,-3.804980,0.000000
+0,1,34392,6.080123,-4.746419,-3.804980,0.000000
+0,1,34397,5.923217,-4.824872,-3.883434,0.000000
+0,1,34402,5.923217,-4.824872,-3.883434,0.000000
+0,1,34407,5.805537,-4.942552,-3.804980,0.000000
+0,1,34412,5.805537,-4.942552,-3.804980,0.000000
+0,1,34417,5.530951,-4.903325,-3.765754,0.000000
+0,1,34422,5.530951,-4.903325,-3.765754,0.000000
+0,1,34427,5.334818,-4.981779,-3.687301,0.000000
+0,1,34432,5.334818,-4.981779,-3.687301,0.000000
+0,1,34437,5.491724,-5.099459,-3.412714,0.000000
+0,1,34442,5.491724,-5.099459,-3.412714,0.000000
+0,1,34447,5.256365,-5.138685,-3.451941,0.000000
+0,1,34452,5.256365,-5.138685,-3.451941,0.000000
+0,1,34457,5.217138,-4.942552,-3.295035,0.000000
+0,1,34462,5.217138,-4.942552,-3.295035,0.000000
+0,1,34467,5.491724,-4.942552,-3.255808,0.000000
+0,1,34472,5.491724,-4.942552,-3.255808,0.000000
+0,1,34477,5.491724,-5.060232,-3.334261,0.000000
+0,1,34482,5.491724,-5.060232,-3.334261,0.000000
+0,1,34487,5.609404,-5.021005,-3.255808,0.000000
+0,1,34492,5.609404,-5.021005,-3.255808,0.000000
+0,1,34497,5.687858,-4.981779,-3.020448,0.000000
+0,1,34502,5.687858,-4.981779,-3.020448,0.000000
+0,1,34507,5.883990,-4.981779,-2.824315,0.000000
+0,1,34512,5.883990,-4.981779,-2.824315,0.000000
+0,1,34517,6.001670,-5.060232,-2.863542,0.000000
+0,1,34522,6.001670,-5.060232,-2.863542,0.000000
+0,1,34527,6.040897,-4.942552,-2.824315,0.000000
+0,1,34532,6.040897,-4.942552,-2.824315,0.000000
+0,1,34537,6.080123,-4.942552,-2.981222,0.000000
+0,1,34542,6.080123,-4.942552,-2.981222,0.000000
+0,1,34547,6.197803,-5.099459,-3.255808,0.000000
+0,1,34552,6.197803,-5.099459,-3.255808,0.000000
+0,1,34557,6.511616,-5.099459,-3.530394,0.000000
+0,1,34562,6.511616,-5.099459,-3.530394,0.000000
+0,1,34567,6.629296,-5.217138,-3.804980,0.000000
+0,1,34572,6.629296,-5.217138,-3.804980,0.000000
+0,1,34577,6.668522,-5.413271,-4.001113,0.000000
+0,1,34582,6.668522,-5.413271,-4.001113,0.000000
+0,1,34587,7.060789,-6.001670,-4.275700,0.000000
+0,1,34592,7.060789,-6.001670,-4.275700,0.000000
+0,1,34597,7.021562,-5.530951,-4.197247,0.000000
+0,1,34602,7.021562,-5.530951,-4.197247,0.000000
+0,1,34607,7.531507,-5.609404,-4.354153,0.000000
+0,1,34612,7.531507,-5.609404,-4.354153,0.000000
+0,1,34617,8.237586,-5.727084,-4.432606,0.000000
+0,1,34622,8.237586,-5.727084,-4.432606,0.000000
+0,1,34627,8.590626,-5.530951,-4.393379,0.000000
+0,1,34632,8.590626,-5.530951,-4.393379,0.000000
+0,1,34637,8.786758,-5.413271,-4.354153,0.000000
+0,1,34642,8.786758,-5.413271,-4.354153,0.000000
+0,1,34647,9.022119,-5.295591,-4.550286,0.000000
+0,1,34652,9.022119,-5.295591,-4.550286,0.000000
+0,1,34657,9.335931,-5.334818,-4.511059,0.000000
+0,1,34662,9.257479,-5.334818,-4.511059,0.000000
+0,1,34667,9.257479,-5.334818,-4.511059,0.000000
+0,1,34672,10.042010,-5.648631,-4.824872,0.000000
+0,1,34677,10.042010,-5.648631,-4.824872,0.000000
+0,1,34682,9.218252,-5.452498,-5.177911,0.000000
+0,1,34687,9.218252,-5.452498,-5.177911,0.000000
+0,1,34692,9.649744,-6.119350,-5.217138,0.000000
+0,1,34697,9.649744,-6.119350,-5.217138,0.000000
+0,1,34702,9.767424,-6.825429,-5.727084,0.000000
+0,1,34707,9.767424,-6.825429,-5.727084,0.000000
+0,1,34712,10.159690,-7.178468,-6.354709,0.000000
+0,1,34717,10.159690,-7.178468,-6.354709,0.000000
+0,1,34722,10.434276,-7.335374,-6.237030,0.000000
+0,1,34727,10.434276,-7.335374,-6.237030,0.000000
+0,1,34732,10.159690,-6.982335,-6.746975,0.000000
+0,1,34737,10.159690,-6.982335,-6.746975,0.000000
+0,1,34742,9.963557,-6.668522,-7.413828,0.000000
+0,1,34747,9.963557,-6.668522,-7.413828,0.000000
+0,1,34752,10.081236,-5.962444,-7.139242,0.000000
+0,1,34757,10.081236,-5.962444,-7.139242,0.000000
+0,1,34762,9.845878,-6.001670,-6.982335,0.000000
+0,1,34767,9.845878,-6.001670,-6.982335,0.000000
+0,1,34772,9.414385,-6.237030,-7.178468,0.000000
+0,1,34777,9.414385,-6.237030,-7.178468,0.000000
+0,1,34782,9.100572,-6.315483,-6.943109,0.000000
+0,1,34787,9.100572,-6.315483,-6.943109,0.000000
+0,1,34792,8.394493,-6.668522,-6.276257,0.000000
+0,1,34797,8.394493,-6.668522,-6.276257,0.000000
+0,1,34802,7.963000,-6.354709,-6.393936,0.000000
+0,1,34807,7.963000,-6.354709,-6.393936,0.000000
+0,1,34812,7.100015,-6.119350,-5.923217,0.000000
+0,1,34817,7.100015,-6.119350,-5.923217,0.000000
+0,1,34822,6.786202,-5.962444,-5.609404,0.000000
+0,1,34827,6.786202,-5.962444,-5.609404,0.000000
+0,1,34832,6.237030,-5.491724,-4.824872,0.000000
+0,1,34837,6.237030,-5.491724,-4.824872,0.000000
+0,1,34842,5.962444,-5.413271,-4.354153,0.000000
+0,1,34847,5.962444,-5.413271,-4.354153,0.000000
+0,1,34852,6.237030,-6.276257,-3.804980,0.000000
+0,1,34857,6.237030,-6.276257,-3.804980,0.000000
+0,1,34862,6.040897,-6.080123,-3.726527,0.000000
+0,1,34867,6.040897,-6.080123,-3.726527,0.000000
+0,1,34872,5.883990,-5.962444,-3.451941,0.000000
+0,1,34877,5.883990,-5.962444,-3.451941,0.000000
+0,1,34882,5.883990,-6.237030,-3.177355,0.000000
+0,1,34887,5.883990,-6.237030,-3.177355,0.000000
+0,1,34892,6.040897,-6.354709,-2.981222,0.000000
+0,1,34897,6.040897,-6.354709,-2.981222,0.000000
+0,1,34902,6.080123,-6.315483,-2.863542,0.000000
+0,1,34907,6.080123,-6.315483,-2.863542,0.000000
+0,1,34912,6.315483,-6.550843,-2.902768,0.000000
+0,1,34917,6.315483,-6.550843,-2.902768,0.000000
+0,1,34922,6.472389,-6.707749,-2.981222,0.000000
+0,1,34927,6.472389,-6.707749,-2.981222,0.000000
+0,1,34932,6.511616,-6.629296,-3.020448,0.000000
+0,1,34937,6.511616,-6.629296,-3.020448,0.000000
+0,1,34942,6.707749,-6.511616,-3.334261,0.000000
+0,1,34947,6.707749,-6.511616,-3.334261,0.000000
+0,1,34952,6.786202,-6.276257,-3.765754,0.000000
+0,1,34957,6.786202,-6.276257,-3.765754,0.000000
+0,1,34962,6.746975,-6.080123,-4.040340,0.000000
+0,1,34967,6.746975,-6.080123,-4.040340,0.000000
+0,1,34972,6.668522,-5.923217,-4.275700,0.000000
+0,1,34977,6.668522,-5.923217,-4.275700,0.000000
+0,1,34982,6.590069,-5.727084,-4.393379,0.000000
+0,1,34987,6.590069,-5.727084,-4.393379,0.000000
+0,1,34992,6.276257,-5.609404,-4.511059,0.000000
+0,1,34997,6.276257,-5.609404,-4.511059,0.000000
+0,1,35002,6.001670,-5.805537,-4.667965,0.000000
+0,1,35007,6.001670,-5.805537,-4.667965,0.000000
+0,1,35012,5.805537,-5.883990,-4.707192,0.000000
+0,1,35017,5.805537,-5.883990,-4.707192,0.000000
+0,1,35022,5.452498,-6.001670,-4.667965,0.000000
+0,1,35027,5.452498,-6.001670,-4.667965,0.000000
+0,1,35032,5.177911,-6.080123,-4.589512,0.000000
+0,1,35037,5.177911,-6.080123,-4.589512,0.000000
+0,1,35042,5.060232,-6.119350,-4.432606,0.000000
+0,1,35047,5.060232,-6.119350,-4.432606,0.000000
+0,1,35052,4.942552,-6.001670,-4.118793,0.000000
+0,1,35057,4.942552,-6.001670,-4.118793,0.000000
+0,1,35062,4.942552,-6.080123,-4.001113,0.000000
+0,1,35067,4.942552,-6.080123,-4.001113,0.000000
+0,1,35072,4.981779,-6.040897,-3.804980,0.000000
+0,1,35077,4.981779,-6.040897,-3.804980,0.000000
+0,1,35082,4.864099,-6.040897,-3.530394,0.000000
+0,1,35087,4.864099,-6.040897,-3.530394,0.000000
+0,1,35092,4.942552,-5.844764,-3.569621,0.000000
+0,1,35097,4.942552,-5.844764,-3.569621,0.000000
+0,1,35102,5.060232,-5.766310,-3.451941,0.000000
+0,1,35107,5.060232,-5.766310,-3.451941,0.000000
+0,1,35112,5.060232,-5.766310,-3.451941,0.000000
+0,1,35117,5.217138,-5.530951,-3.491168,0.000000
+0,1,35122,5.217138,-5.530951,-3.491168,0.000000
+0,1,35127,5.452498,-5.334818,-3.608848,0.000000
+0,1,35132,5.452498,-5.334818,-3.608848,0.000000
+0,1,35137,5.570178,-5.177911,-3.569621,0.000000
+0,1,35142,5.570178,-5.177911,-3.569621,0.000000
+0,1,35147,5.766310,-4.942552,-3.608848,0.000000
+0,1,35152,5.766310,-4.942552,-3.608848,0.000000
+0,1,35157,6.040897,-4.707192,-3.687301,0.000000
+0,1,35162,6.040897,-4.707192,-3.687301,0.000000
+0,1,35167,6.197803,-4.628739,-3.569621,0.000000
+0,1,35172,6.197803,-4.628739,-3.569621,0.000000
+0,1,35177,6.237030,-4.471833,-3.883434,0.000000
+0,1,35182,6.237030,-4.471833,-3.883434,0.000000
+0,1,35187,6.197803,-4.589512,-4.079566,0.000000
+0,1,35192,6.197803,-4.589512,-4.079566,0.000000
+0,1,35197,6.119350,-4.707192,-4.471833,0.000000
+0,1,35202,6.119350,-4.707192,-4.471833,0.000000
+0,1,35207,6.158576,-4.746419,-4.824872,0.000000
+0,1,35212,6.158576,-4.746419,-4.824872,0.000000
+0,1,35217,6.158576,-4.824872,-5.060232,0.000000
+0,1,35222,6.158576,-4.824872,-5.060232,0.000000
+0,1,35227,6.276257,-4.864099,-5.256365,0.000000
+0,1,35232,6.276257,-4.864099,-5.256365,0.000000
+0,1,35237,6.433163,-4.942552,-5.295591,0.000000
+0,1,35242,6.433163,-4.942552,-5.295591,0.000000
+0,1,35247,6.590069,-4.903325,-5.452498,0.000000
+0,1,35252,6.590069,-4.903325,-5.452498,0.000000
+0,1,35257,6.629296,-5.021005,-5.530951,0.000000
+0,1,35262,6.629296,-5.021005,-5.530951,0.000000
+0,1,35267,6.864655,-5.099459,-5.687858,0.000000
+0,1,35272,6.864655,-5.099459,-5.687858,0.000000
+0,1,35277,6.982335,-5.099459,-5.648631,0.000000
+0,1,35282,6.982335,-5.099459,-5.648631,0.000000
+0,1,35287,6.864655,-5.334818,-5.766310,0.000000
+0,1,35292,6.864655,-5.334818,-5.766310,0.000000
+0,1,35297,7.021562,-5.452498,-5.570178,0.000000
+0,1,35302,7.021562,-5.452498,-5.570178,0.000000
+0,1,35307,7.060789,-5.491724,-5.413271,0.000000
+0,1,35312,7.060789,-5.491724,-5.413271,0.000000
+0,1,35317,6.943109,-5.413271,-5.334818,0.000000
+0,1,35322,6.943109,-5.413271,-5.334818,0.000000
+0,1,35327,6.825429,-5.334818,-5.334818,0.000000
+0,1,35332,6.825429,-5.334818,-5.334818,0.000000
+0,1,35337,6.707749,-5.295591,-5.217138,0.000000
+0,1,35342,6.707749,-5.295591,-5.217138,0.000000
+0,1,35347,6.629296,-5.177911,-5.217138,0.000000
+0,1,35352,6.629296,-5.177911,-5.217138,0.000000
+0,1,35357,6.590069,-4.981779,-5.177911,0.000000
+0,1,35362,6.590069,-4.981779,-5.177911,0.000000
+0,1,35367,6.433163,-4.785645,-5.021005,0.000000
+0,1,35372,6.433163,-4.785645,-5.021005,0.000000
+0,1,35377,6.629296,-4.864099,-4.981779,0.000000
+0,1,35382,6.629296,-4.864099,-4.981779,0.000000
+0,1,35387,7.021562,-5.217138,-4.746419,0.000000
+0,1,35392,7.021562,-5.217138,-4.746419,0.000000
+0,1,35397,7.609961,-5.844764,-4.942552,0.000000
+0,1,35402,7.609961,-5.844764,-4.942552,0.000000
+0,1,35407,8.002227,-6.080123,-5.217138,0.000000
+0,1,35412,8.002227,-6.080123,-5.217138,0.000000
+0,1,35417,8.159133,-6.237030,-5.334818,0.000000
+0,1,35422,8.159133,-6.237030,-5.334818,0.000000
+0,1,35427,8.119907,-6.119350,-5.452498,0.000000
+0,1,35432,8.119907,-6.119350,-5.452498,0.000000
+0,1,35437,8.159133,-6.197803,-5.766310,0.000000
+0,1,35442,8.159133,-6.197803,-5.766310,0.000000
+0,1,35447,8.237586,-6.158576,-5.923217,0.000000
+0,1,35452,8.237586,-6.158576,-5.923217,0.000000
+0,1,35457,8.512173,-6.197803,-6.158576,0.000000
+0,1,35462,8.512173,-6.197803,-6.158576,0.000000
+0,1,35467,8.786758,-6.315483,-6.354709,0.000000
+0,1,35472,8.786758,-6.315483,-6.354709,0.000000
+0,1,35477,9.375158,-6.158576,-6.433163,0.000000
+0,1,35482,9.375158,-6.158576,-6.433163,0.000000
+0,1,35487,9.492838,-5.805537,-6.197803,0.000000
+0,1,35492,9.492838,-5.805537,-6.197803,0.000000
+0,1,35497,9.492838,-5.295591,-6.040897,0.000000
+0,1,35502,9.492838,-5.295591,-6.040897,0.000000
+0,1,35507,9.296705,-5.021005,-5.766310,0.000000
+0,1,35512,9.296705,-5.021005,-5.766310,0.000000
+0,1,35517,9.139798,-4.942552,-5.413271,0.000000
+0,1,35522,9.139798,-4.942552,-5.413271,0.000000
+0,1,35527,9.061345,-5.060232,-5.295591,0.000000
+0,1,35532,9.061345,-5.060232,-5.295591,0.000000
+0,1,35537,8.904439,-5.374045,-5.256365,0.000000
+0,1,35542,8.904439,-5.374045,-5.256365,0.000000
+0,1,35547,8.590626,-5.687858,-5.256365,0.000000
+0,1,35552,8.590626,-5.687858,-5.256365,0.000000
+0,1,35557,8.590626,-5.687858,-5.413271,0.000000
+0,1,35562,8.355267,-5.923217,-5.374045,0.000000
+0,1,35567,8.355267,-5.923217,-5.374045,0.000000
+0,1,35572,8.276814,-6.158576,-5.256365,0.000000
+0,1,35577,8.276814,-6.158576,-5.256365,0.000000
+0,1,35582,8.159133,-6.393936,-5.060232,0.000000
+0,1,35587,8.159133,-6.393936,-5.060232,0.000000
+0,1,35592,8.159133,-6.472389,-4.942552,0.000000
+0,1,35597,8.159133,-6.472389,-4.942552,0.000000
+0,1,35602,8.237586,-6.393936,-4.785645,0.000000
+0,1,35607,8.237586,-6.393936,-4.785645,0.000000
+0,1,35612,8.198359,-6.354709,-4.511059,0.000000
+0,1,35617,8.198359,-6.354709,-4.511059,0.000000
diff --git a/reform2-lpc-fw/src/drivers/storage/fatfs/ccsbcs.c b/reform2-lpc-fw/src/drivers/storage/fatfs/ccsbcs.c
new file mode 100644
index 0000000000000000000000000000000000000000..f0d211eb7555a14dd3084cebe8a1a1cf41de6a87
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/storage/fatfs/ccsbcs.c
@@ -0,0 +1,540 @@
+/*------------------------------------------------------------------------*/
+/* Unicode - Local code bidirectional converter  (C)ChaN, 2009            */
+/* (SBCS code pages)                                                      */
+/*------------------------------------------------------------------------*/
+/*  437   U.S. (OEM)
+/   720   Arabic (OEM)
+/   1256  Arabic (Windows)
+/   737   Greek (OEM)
+/   1253  Greek (Windows)
+/   1250  Central Europe (Windows)
+/   775   Baltic (OEM)
+/   1257  Baltic (Windows)
+/   850   Multilingual Latin 1 (OEM)
+/   852   Latin 2 (OEM)
+/   1252  Latin 1 (Windows)
+/   855   Cyrillic (OEM)
+/   1251  Cyrillic (Windows)
+/   866   Russian (OEM)
+/   857   Turkish (OEM)
+/   1254  Turkish (Windows)
+/   858   Multilingual Latin 1 + Euro (OEM)
+/   862   Hebrew (OEM)
+/   1255  Hebrew (Windows)
+/   874   Thai (OEM, Windows)
+/   1258  Vietnam (OEM, Windows)
+*/
+
+#include "ff.h"
+
+
+#if _CODE_PAGE == 437
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP437(0x80-0xFF) to Unicode conversion table */
+	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
+	0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
+	0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
+	0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
+	0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
+	0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+	0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
+	0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+	0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
+	0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
+	0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
+	0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 720
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP720(0x80-0xFF) to Unicode conversion table */
+	0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7,
+	0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9,
+	0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
+	0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
+	0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
+	0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+	0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
+	0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+	0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642,
+	0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
+	0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0xO650, 0x2248,
+	0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 737
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP737(0x80-0xFF) to Unicode conversion table */
+	0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398,
+	0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
+	0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
+	0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
+	0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0,
+	0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
+	0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+	0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
+	0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+	0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD,
+	0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
+	0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248,
+	0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 775
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP775(0x80-0xFF) to Unicode conversion table */
+	0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107,
+	0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
+	0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A,
+	0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
+	0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6,
+	0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118,
+	0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
+	0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B,
+	0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+	0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144,
+	0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
+	0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E,
+	0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 850
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP850(0x80-0xFF) to Unicode conversion table */
+	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
+	0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
+	0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
+	0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
+	0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
+	0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
+	0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
+	0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
+	0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
+	0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
+	0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
+	0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 852
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP852(0x80-0xFF) to Unicode conversion table */
+	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7,
+	0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
+	0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A,
+	0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E,
+	0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A,
+	0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
+	0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE,
+	0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
+	0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161,
+	0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
+	0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8,
+	0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 855
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP855(0x80-0xFF) to Unicode conversion table */
+	0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404,
+	0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
+	0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C,
+	0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
+	0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414,
+	0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438,
+	0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
+	0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E,
+	0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
+	0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443,
+	0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
+	0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D,
+	0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 857
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP857(0x80-0xFF) to Unicode conversion table */
+	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
+	0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
+	0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
+	0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F,
+	0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
+	0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
+	0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE,
+	0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
+	0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000,
+	0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
+	0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
+	0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 858
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP858(0x80-0xFF) to Unicode conversion table */
+	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
+	0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
+	0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
+	0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
+	0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
+	0x00A9, 0x2563, 0x2551, 0x2557, 0x2550, 0x00A2, 0x00A5, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
+	0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x20AC, 0x00CD, 0x00CE,
+	0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00C6, 0x00CC, 0x2580,
+	0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
+	0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
+	0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
+	0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 862
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP862(0x80-0xFF) to Unicode conversion table */
+	0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
+	0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
+	0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
+	0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
+	0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
+	0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+	0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
+	0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+	0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
+	0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
+	0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
+	0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 866
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP866(0x80-0xFF) to Unicode conversion table */
+	0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
+	0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
+	0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+	0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
+	0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
+	0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
+	0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
+	0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+	0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
+	0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+	0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
+	0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
+	0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E,
+	0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
+};
+
+#elif _CODE_PAGE == 874
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP874(0x80-0xFF) to Unicode conversion table */
+	0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
+	0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
+	0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
+	0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
+	0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
+	0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
+	0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
+	0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F,
+	0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
+	0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
+	0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
+	0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+#elif _CODE_PAGE == 1250
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP1250(0x80-0xFF) to Unicode conversion table */
+	0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
+	0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
+	0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+	0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
+	0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7,
+	0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
+	0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+	0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
+	0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
+	0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
+	0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
+	0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
+	0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
+	0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
+	0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
+	0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
+};
+
+#elif _CODE_PAGE == 1251
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP1251(0x80-0xFF) to Unicode conversion table */
+	0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
+	0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
+	0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+	0x0000, 0x2111, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
+	0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
+	0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
+	0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
+	0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
+	0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
+	0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
+	0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+	0x0428, 0x0429, 0x042A, 0x042D, 0x042C, 0x042D, 0x042E, 0x042F,
+	0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
+	0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
+	0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
+	0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F
+};
+
+#elif _CODE_PAGE == 1252
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP1252(0x80-0xFF) to Unicode conversion table */
+	0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+	0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
+	0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+	0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178,
+	0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+	0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+	0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+	0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+	0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+	0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+	0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+	0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+	0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+	0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+	0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+	0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
+};
+
+#elif _CODE_PAGE == 1253
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP1253(0x80-0xFF) to Unicode conversion table */
+	0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+	0x0000, 0x2030, 0x0000, 0x2039, 0x000C, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+	0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+	0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015,
+	0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7,
+	0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
+	0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+	0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
+	0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
+	0x03A8, 0x03A9, 0x03AA, 0x03AD, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
+	0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
+	0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
+	0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
+	0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000
+};
+
+#elif _CODE_PAGE == 1254
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP1254(0x80-0xFF) to Unicode conversion table */
+	0x20AC, 0x0000, 0x210A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+	0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+	0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
+	0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+	0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+	0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+	0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+	0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+	0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+	0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+	0x00D8, 0x00D9, 0x00DA, 0x00BD, 0x00DC, 0x0130, 0x015E, 0x00DF,
+	0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+	0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+	0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+	0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF
+};
+
+#elif _CODE_PAGE == 1255
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP1255(0x80-0xFF) to Unicode conversion table */
+	0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+	0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+	0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+	0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+	0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+	0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+	0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
+	0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
+	0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3,
+	0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
+	0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
+	0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
+	0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000
+};
+
+#elif _CODE_PAGE == 1256
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP1256(0x80-0xFF) to Unicode conversion table */
+	0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+	0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
+	0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+	0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA,
+	0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+	0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+	0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+	0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F,
+	0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
+	0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
+	0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7,
+	0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0640, 0x0642, 0x0643,
+	0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7,
+	0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF,
+	0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7,
+	0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2
+}
+
+#elif _CODE_PAGE == 1257
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP1257(0x80-0xFF) to Unicode conversion table */
+	0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
+	0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8,
+	0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+	0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000,
+	0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7,
+	0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+	0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+	0x00B8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
+	0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
+	0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
+	0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
+	0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
+	0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
+	0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
+	0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
+	0x0173, 0x014E, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9
+};
+
+#elif _CODE_PAGE == 1258
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP1258(0x80-0xFF) to Unicode conversion table */
+	0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+	0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+	0x02DC, 0x2122, 0x0000, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
+	0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+	0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+	0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+	0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+	0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+	0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF,
+	0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7,
+	0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF,
+	0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+	0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF,
+	0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7,
+	0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF
+};
+
+#endif
+
+
+#if !_TBLDEF || !_USE_LFN
+#error This file is not needed in current configuration. Remove from the project.
+#endif
+
+
+WCHAR ff_convert (	/* Converted character, Returns zero on error */
+	WCHAR	src,	/* Character code to be converted */
+	UINT	dir		/* 0: Unicode to OEMCP, 1: OEMCP to Unicode */
+)
+{
+	WCHAR c;
+
+
+	if (src < 0x80) {	/* ASCII */
+		c = src;
+
+	} else {
+		if (dir) {		/* OEMCP to Unicode */
+			c = (src >= 0x100) ? 0 : Tbl[src - 0x80];
+
+		} else {		/* Unicode to OEMCP */
+			for (c = 0; c < 0x80; c++) {
+				if (src == Tbl[c]) break;
+			}
+			c = (c + 0x80) & 0xFF;
+		}
+	}
+
+	return c;
+}
+
+
+WCHAR ff_wtoupper (	/* Upper converted character */
+	WCHAR chr		/* Input character */
+)
+{
+	static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 };
+	static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 };
+	int i;
+
+
+	for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ;
+
+	return tbl_lower[i] ? tbl_upper[i] : chr;
+}
diff --git a/reform2-lpc-fw/src/drivers/storage/fatfs/diskio.h b/reform2-lpc-fw/src/drivers/storage/fatfs/diskio.h
new file mode 100644
index 0000000000000000000000000000000000000000..f491f45769a4cb11c615564f8a9f5c5734a5eb33
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/storage/fatfs/diskio.h
@@ -0,0 +1,89 @@
+/*-----------------------------------------------------------------------
+/  Low level disk interface modlue include file  R0.05   (C)ChaN, 2007
+/-----------------------------------------------------------------------*/
+
+#ifndef _DISKIO
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _READONLY        0        /* 1: Read-only mode */
+#define _USE_IOCTL        1
+
+#include "integer.h"
+
+
+/* Status of Disk Functions */
+typedef BYTE        DSTATUS;
+
+/* Results of Disk Functions */
+typedef enum {
+        RES_OK = 0,                /* 0: Successful */
+        RES_ERROR,                /* 1: R/W Error */
+        RES_WRPRT,                /* 2: Write Protected */
+        RES_NOTRDY,                /* 3: Not Ready */
+        RES_PARERR                /* 4: Invalid Parameter */
+} DRESULT;
+
+
+/*---------------------------------------*/
+/* Prototypes for disk control functions */
+
+DSTATUS disk_initialize (BYTE);
+DSTATUS disk_status (BYTE);
+DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);
+#if        _READONLY == 0
+DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);
+#endif
+DRESULT disk_ioctl (BYTE, BYTE, void*);
+void    disk_timerproc (void);
+
+
+
+
+/* Disk Status Bits (DSTATUS) */
+
+#define STA_NOINIT                0x01        /* Drive not initialized */
+#define STA_NODISK                0x02        /* No medium in the drive */
+#define STA_PROTECT               0x04        /* Write protected */
+
+
+
+/* Command code for disk_ioctrl() */
+
+/* Generic command */
+#define CTRL_SYNC                 0        /* Mandatory for write functions */
+#define GET_SECTOR_COUNT          1        /* Mandatory for only f_mkfs() */
+#define GET_SECTOR_SIZE           2
+#define GET_BLOCK_SIZE            3        /* Mandatory for only f_mkfs() */
+#define CTRL_POWER                4
+#define CTRL_LOCK                 5
+#define CTRL_EJECT                6
+/* MMC/SDC command */
+#define MMC_GET_TYPE              10
+#define MMC_GET_CSD               11
+#define MMC_GET_CID               12
+#define MMC_GET_OCR               13
+#define MMC_GET_SDSTAT            14
+/* ATA/CF command */
+#define ATA_GET_REV               20
+#define ATA_GET_MODEL             21
+#define ATA_GET_SN                22
+
+
+
+/* Card type flags (CardType) */
+#define CT_MMC                    0x01        /* MMC ver 3 */
+#define CT_SD1                    0x02        /* SD ver 1 */
+#define CT_SD2                    0x04        /* SD ver 2 */
+#define CT_SDC                    (CT_SD1|CT_SD2)        /* SD */
+#define CT_BLOCK                  0x08        /* Block addressing */
+
+#define _DISKIO
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/storage/fatfs/ff.c b/reform2-lpc-fw/src/drivers/storage/fatfs/ff.c
new file mode 100644
index 0000000000000000000000000000000000000000..9a214632cb88d8b28db67228bb06edb51eda6a81
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/storage/fatfs/ff.c
@@ -0,0 +1,3159 @@
+/*----------------------------------------------------------------------------/
+/  FatFs - FAT file system module  R0.07e                    (C)ChaN, 2009
+/-----------------------------------------------------------------------------/
+/ FatFs module is a generic FAT file system module for small embedded systems.
+/ This is a free software that opened for education, research and commercial
+/ developments under license policy of following trems.
+/
+/  Copyright (C) 2009, ChaN, all right reserved.
+/
+/ * The FatFs module is a free software and there is NO WARRANTY.
+/ * No restriction on use. You can use, modify and redistribute it for
+/   personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
+/ * Redistributions of source code must retain the above copyright notice.
+/
+/-----------------------------------------------------------------------------/
+/ Feb 26,'06 R0.00  Prototype.
+/
+/ Apr 29,'06 R0.01  First stable version.
+/
+/ Jun 01,'06 R0.02  Added FAT12 support.
+/                   Removed unbuffered mode.
+/                   Fixed a problem on small (<32M) patition.
+/ Jun 10,'06 R0.02a Added a configuration option (_FS_MINIMUM).
+/
+/ Sep 22,'06 R0.03  Added f_rename().
+/                   Changed option _FS_MINIMUM to _FS_MINIMIZE.
+/ Dec 11,'06 R0.03a Improved cluster scan algolithm to write files fast.
+/                   Fixed f_mkdir() creates incorrect directory on FAT32.
+/
+/ Feb 04,'07 R0.04  Supported multiple drive system.
+/                   Changed some interfaces for multiple drive system.
+/                   Changed f_mountdrv() to f_mount().
+/                   Added f_mkfs().
+/ Apr 01,'07 R0.04a Supported multiple partitions on a plysical drive.
+/                   Added a capability of extending file size to f_lseek().
+/                   Added minimization level 3.
+/                   Fixed an endian sensitive code in f_mkfs().
+/ May 05,'07 R0.04b Added a configuration option _USE_NTFLAG.
+/                   Added FSInfo support.
+/                   Fixed DBCS name can result FR_INVALID_NAME.
+/                   Fixed short seek (<= csize) collapses the file object.
+/
+/ Aug 25,'07 R0.05  Changed arguments of f_read(), f_write() and f_mkfs().
+/                   Fixed f_mkfs() on FAT32 creates incorrect FSInfo.
+/                   Fixed f_mkdir() on FAT32 creates incorrect directory.
+/ Feb 03,'08 R0.05a Added f_truncate() and f_utime().
+/                   Fixed off by one error at FAT sub-type determination.
+/                   Fixed btr in f_read() can be mistruncated.
+/                   Fixed cached sector is not flushed when create and close
+/                   without write.
+/
+/ Apr 01,'08 R0.06  Added fputc(), fputs(), fprintf() and fgets().
+/                   Improved performance of f_lseek() on moving to the same
+/                   or following cluster.
+/
+/ Apr 01,'09 R0.07  Merged Tiny-FatFs as a buffer configuration option.
+/                   Added long file name support.
+/                   Added multiple code page support.
+/                   Added re-entrancy for multitask operation.
+/                   Added auto cluster size selection to f_mkfs().
+/                   Added rewind option to f_readdir().
+/                   Changed result code of critical errors.
+/                   Renamed string functions to avoid name collision.
+/ Apr 14,'09 R0.07a Separated out OS dependent code on reentrant cfg.
+/                   Added multiple sector size support.
+/ Jun 21,'09 R0.07c Fixed f_unlink() can return FR_OK on error.
+/                   Fixed wrong cache control in f_lseek().
+/                   Added relative path feature.
+/                   Added f_chdir() and f_chdrive().
+/                   Added proper case conversion to extended char.
+/ Nov 03,'09 R0.07e Separated out configuration options from ff.h to ffconf.h.
+/                   Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH.
+/                   Fixed name matching error on the 13 char boundary.
+/                   Added a configuration option, _LFN_UNICODE.
+/                   Changed f_readdir() to return the SFN with always upper
+/                   case on non-LFN cfg.
+/---------------------------------------------------------------------------*/
+
+#include "projectconfig.h"
+
+#ifdef CFG_SDCARD
+
+#include "ff.h"			/* FatFs configurations and declarations */
+#include "diskio.h"		/* Declarations of low level disk I/O functions */
+
+/*--------------------------------------------------------------------------
+
+   Module Private Definitions
+
+---------------------------------------------------------------------------*/
+
+#if _FATFS != 0x007E
+#error Wrong include file (ff.h).
+#endif
+
+#if _FS_REENTRANT
+#if _USE_LFN == 1
+#error Static LFN work area must not be used in re-entrant configuration.
+#endif
+#define	ENTER_FF(fs)		{ if (!lock_fs(fs)) return FR_TIMEOUT; }
+#define	LEAVE_FF(fs, res)	{ unlock_fs(fs, res); return res; }
+
+#else
+#define	ENTER_FF(fs)
+#define LEAVE_FF(fs, res)	return res
+
+#endif
+
+#define	ABORT(fs, res)		{ fp->flag |= FA__ERROR; LEAVE_FF(fs, res); }
+
+#ifndef NULL
+#define	NULL	0
+#endif
+
+/* Name status flags */
+#define NS			11		/* Offset of name status byte */
+#define NS_LOSS		0x01	/* Out of 8.3 format */
+#define NS_LFN		0x02	/* Force to create LFN entry */
+#define NS_LAST		0x04	/* Last segment */
+#define NS_BODY		0x08	/* Lower case flag (body) */
+#define NS_EXT		0x10	/* Lower case flag (ext) */
+#define NS_DOT		0x20	/* Dot entry */
+
+
+
+
+/*--------------------------------------------------------------------------
+
+   Private Work Area
+
+---------------------------------------------------------------------------*/
+
+#if _DRIVES < 1 || _DRIVES > 9
+#error Number of drives must be 1-9.
+#endif
+static
+FATFS *FatFs[_DRIVES];	/* Pointer to the file system objects (logical drives) */
+
+static
+WORD Fsid;				/* File system mount ID */
+
+#if _FS_RPATH
+static
+BYTE Drive;				/* Current drive */
+#endif
+
+
+#if _USE_LFN == 1	/* LFN with static LFN working buffer */
+static
+WCHAR LfnBuf[_MAX_LFN + 1];
+#define	NAMEBUF(sp,lp)	BYTE sp[12]; WCHAR *lp = LfnBuf
+#define INITBUF(dj,sp,lp)	dj.fn = sp; dj.lfn = lp
+
+#elif _USE_LFN > 1	/* LFN with dynamic LFN working buffer */
+#define	NAMEBUF(sp,lp)	BYTE sp[12]; WCHAR lbuf[_MAX_LFN + 1], *lp = lbuf
+#define INITBUF(dj,sp,lp)	dj.fn = sp; dj.lfn = lp
+
+#else				/* No LFN */
+#define	NAMEBUF(sp,lp)	BYTE sp[12]
+#define INITBUF(dj,sp,lp)	dj.fn = sp
+
+#endif
+
+
+
+
+/*--------------------------------------------------------------------------
+
+   Module Private Functions
+
+---------------------------------------------------------------------------*/
+
+
+/*-----------------------------------------------------------------------*/
+/* String functions                                                      */
+/*-----------------------------------------------------------------------*/
+
+/* Copy memory to memory */
+static
+void mem_cpy (void* dst, const void* src, int cnt) {
+	char *d = (char*)dst;
+	const char *s = (const char *)src;
+	while (cnt--) *d++ = *s++;
+}
+
+/* Fill memory */
+static
+void mem_set (void* dst, int val, int cnt) {
+	char *d = (char*)dst;
+	while (cnt--) *d++ = (char)val;
+}
+
+/* Compare memory to memory */
+static
+int mem_cmp (const void* dst, const void* src, int cnt) {
+	const char *d = (const char *)dst, *s = (const char *)src;
+	int r = 0;
+	while (cnt-- && (r = *d++ - *s++) == 0) ;
+	return r;
+}
+
+/* Check if chr is contained in the string */
+static
+int chk_chr (const char* str, int chr) {
+	while (*str && *str != chr) str++;
+	return *str;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Request/Release grant to access the volume                            */
+/*-----------------------------------------------------------------------*/
+#if _FS_REENTRANT
+
+static
+BOOL lock_fs (
+	FATFS *fs		/* File system object */
+)
+{
+	return ff_req_grant(fs->sobj);
+}
+
+
+static
+void unlock_fs (
+	FATFS *fs,		/* File system object */
+	FRESULT res		/* Result code to be returned */
+)
+{
+	if (res != FR_NOT_ENABLED &&
+		res != FR_INVALID_DRIVE &&
+		res != FR_INVALID_OBJECT &&
+		res != FR_TIMEOUT) {
+		ff_rel_grant(fs->sobj);
+	}
+}
+#endif
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Change window offset                                                  */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT move_window (
+	FATFS *fs,		/* File system object */
+	DWORD sector	/* Sector number to make apperance in the fs->win[] */
+)					/* Move to zero only writes back dirty window */
+{
+	DWORD wsect;
+
+
+	wsect = fs->winsect;
+	if (wsect != sector) {	/* Changed current window */
+#if !_FS_READONLY
+		if (fs->wflag) {	/* Write back dirty window if needed */
+			if (disk_write(fs->drive, fs->win, wsect, 1) != RES_OK)
+				return FR_DISK_ERR;
+			fs->wflag = 0;
+			if (wsect < (fs->fatbase + fs->sects_fat)) {	/* In FAT area */
+				BYTE nf;
+				for (nf = fs->n_fats; nf > 1; nf--) {	/* Refrect the change to all FAT copies */
+					wsect += fs->sects_fat;
+					disk_write(fs->drive, fs->win, wsect, 1);
+				}
+			}
+		}
+#endif
+		if (sector) {
+			if (disk_read(fs->drive, fs->win, sector, 1) != RES_OK)
+				return FR_DISK_ERR;
+			fs->winsect = sector;
+		}
+	}
+
+	return FR_OK;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Clean-up cached data                                                  */
+/*-----------------------------------------------------------------------*/
+#if !_FS_READONLY
+static
+FRESULT sync (	/* FR_OK: successful, FR_DISK_ERR: failed */
+	FATFS *fs	/* File system object */
+)
+{
+	FRESULT res;
+
+
+	res = move_window(fs, 0);
+	if (res == FR_OK) {
+		/* Update FSInfo sector if needed */
+		if (fs->fs_type == FS_FAT32 && fs->fsi_flag) {
+			fs->winsect = 0;
+			mem_set(fs->win, 0, 512);
+			ST_WORD(fs->win+BS_55AA, 0xAA55);
+			ST_DWORD(fs->win+FSI_LeadSig, 0x41615252);
+			ST_DWORD(fs->win+FSI_StrucSig, 0x61417272);
+			ST_DWORD(fs->win+FSI_Free_Count, fs->free_clust);
+			ST_DWORD(fs->win+FSI_Nxt_Free, fs->last_clust);
+			disk_write(fs->drive, fs->win, fs->fsi_sector, 1);
+			fs->fsi_flag = 0;
+		}
+		/* Make sure that no pending write process in the physical drive */
+		if (disk_ioctl(fs->drive, CTRL_SYNC, (void*)NULL) != RES_OK)
+			res = FR_DISK_ERR;
+	}
+
+	return res;
+}
+#endif
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* FAT access - Read value of a FAT entry                                */
+/*-----------------------------------------------------------------------*/
+
+
+DWORD get_fat (	/* 0xFFFFFFFF:Disk error, 1:Interal error, Else:Cluster status */
+	FATFS *fs,	/* File system object */
+	DWORD clst	/* Cluster# to get the link information */
+)
+{
+	UINT wc, bc;
+	DWORD fsect;
+
+
+	if (clst < 2 || clst >= fs->max_clust)	/* Range check */
+		return 1;
+
+	fsect = fs->fatbase;
+	switch (fs->fs_type) {
+	case FS_FAT12 :
+		bc = clst; bc += bc / 2;
+		if (move_window(fs, fsect + (bc / SS(fs)))) break;
+		wc = fs->win[bc & (SS(fs) - 1)]; bc++;
+		if (move_window(fs, fsect + (bc / SS(fs)))) break;
+		wc |= (WORD)fs->win[bc & (SS(fs) - 1)] << 8;
+		return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);
+
+	case FS_FAT16 :
+		if (move_window(fs, fsect + (clst / (SS(fs) / 2)))) break;
+		return LD_WORD(&fs->win[((WORD)clst * 2) & (SS(fs) - 1)]);
+
+	case FS_FAT32 :
+		if (move_window(fs, fsect + (clst / (SS(fs) / 4)))) break;
+		return LD_DWORD(&fs->win[((WORD)clst * 4) & (SS(fs) - 1)]) & 0x0FFFFFFF;
+	}
+
+	return 0xFFFFFFFF;	/* An error occured at the disk I/O layer */
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* FAT access - Change value of a FAT entry                              */
+/*-----------------------------------------------------------------------*/
+#if !_FS_READONLY
+
+FRESULT put_fat (
+	FATFS *fs,	/* File system object */
+	DWORD clst,	/* Cluster# to be changed in range of 2 to fs->max_clust - 1 */
+	DWORD val	/* New value to mark the cluster */
+)
+{
+	UINT bc;
+	BYTE *p;
+	DWORD fsect;
+	FRESULT res;
+
+
+	if (clst < 2 || clst >= fs->max_clust) {	/* Range check */
+		res = FR_INT_ERR;
+
+	} else {
+		fsect = fs->fatbase;
+		switch (fs->fs_type) {
+		case FS_FAT12 :
+			bc = clst; bc += bc / 2;
+			res = move_window(fs, fsect + (bc / SS(fs)));
+			if (res != FR_OK) break;
+			p = &fs->win[bc & (SS(fs) - 1)];
+			*p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val;
+			bc++;
+			fs->wflag = 1;
+			res = move_window(fs, fsect + (bc / SS(fs)));
+			if (res != FR_OK) break;
+			p = &fs->win[bc & (SS(fs) - 1)];
+			*p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F));
+			break;
+
+		case FS_FAT16 :
+			res = move_window(fs, fsect + (clst / (SS(fs) / 2)));
+			if (res != FR_OK) break;
+			ST_WORD(&fs->win[((WORD)clst * 2) & (SS(fs) - 1)], (WORD)val);
+			break;
+
+		case FS_FAT32 :
+			res = move_window(fs, fsect + (clst / (SS(fs) / 4)));
+			if (res != FR_OK) break;
+			ST_DWORD(&fs->win[((WORD)clst * 4) & (SS(fs) - 1)], val);
+			break;
+
+		default :
+			res = FR_INT_ERR;
+		}
+		fs->wflag = 1;
+	}
+
+	return res;
+}
+#endif /* !_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* FAT handling - Remove a cluster chain                                 */
+/*-----------------------------------------------------------------------*/
+#if !_FS_READONLY
+static
+FRESULT remove_chain (
+	FATFS *fs,			/* File system object */
+	DWORD clst			/* Cluster# to remove a chain from */
+)
+{
+	FRESULT res;
+	DWORD nxt;
+
+
+	if (clst < 2 || clst >= fs->max_clust) {	/* Check the range of cluster# */
+		res = FR_INT_ERR;
+
+	} else {
+		res = FR_OK;
+		while (clst < fs->max_clust) {			/* Not a last link? */
+			nxt = get_fat(fs, clst);			/* Get cluster status */
+			if (nxt == 0) break;				/* Empty cluster? */
+			if (nxt == 1) { res = FR_INT_ERR; break; }	/* Internal error? */
+			if (nxt == 0xFFFFFFFF) { res = FR_DISK_ERR; break; }	/* Disk error? */
+			res = put_fat(fs, clst, 0);			/* Mark the cluster "empty" */
+			if (res != FR_OK) break;
+			if (fs->free_clust != 0xFFFFFFFF) {	/* Update FSInfo */
+				fs->free_clust++;
+				fs->fsi_flag = 1;
+			}
+			clst = nxt;	/* Next cluster */
+		}
+	}
+
+	return res;
+}
+#endif
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* FAT handling - Stretch or Create a cluster chain                      */
+/*-----------------------------------------------------------------------*/
+#if !_FS_READONLY
+static
+DWORD create_chain (	/* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */
+	FATFS *fs,			/* File system object */
+	DWORD clst			/* Cluster# to stretch. 0 means create a new chain. */
+)
+{
+	DWORD cs, ncl, scl, mcl;
+
+
+	mcl = fs->max_clust;
+	if (clst == 0) {		/* Create new chain */
+		scl = fs->last_clust;			/* Get suggested start point */
+		if (scl == 0 || scl >= mcl) scl = 1;
+	}
+	else {					/* Stretch existing chain */
+		cs = get_fat(fs, clst);			/* Check the cluster status */
+		if (cs < 2) return 1;			/* It is an invalid cluster */
+		if (cs < mcl) return cs;		/* It is already followed by next cluster */
+		scl = clst;
+	}
+
+	ncl = scl;				/* Start cluster */
+	for (;;) {
+		ncl++;							/* Next cluster */
+		if (ncl >= mcl) {				/* Wrap around */
+			ncl = 2;
+			if (ncl > scl) return 0;	/* No free custer */
+		}
+		cs = get_fat(fs, ncl);			/* Get the cluster status */
+		if (cs == 0) break;				/* Found a free cluster */
+		if (cs == 0xFFFFFFFF || cs == 1)/* An error occured */
+			return cs;
+		if (ncl == scl) return 0;		/* No free custer */
+	}
+
+	if (put_fat(fs, ncl, 0x0FFFFFFF))	/* Mark the new cluster "in use" */
+		return 0xFFFFFFFF;
+	if (clst != 0) {					/* Link it to the previous one if needed */
+		if (put_fat(fs, clst, ncl))
+			return 0xFFFFFFFF;
+	}
+
+	fs->last_clust = ncl;				/* Update FSINFO */
+	if (fs->free_clust != 0xFFFFFFFF) {
+		fs->free_clust--;
+		fs->fsi_flag = 1;
+	}
+
+	return ncl;		/* Return new cluster number */
+}
+#endif /* !_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Get sector# from cluster#                                             */
+/*-----------------------------------------------------------------------*/
+
+
+DWORD clust2sect (	/* !=0: Sector number, 0: Failed - invalid cluster# */
+	FATFS *fs,		/* File system object */
+	DWORD clst		/* Cluster# to be converted */
+)
+{
+	clst -= 2;
+	if (clst >= (fs->max_clust - 2)) return 0;		/* Invalid cluster# */
+	return clst * fs->csize + fs->database;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Directory handling - Seek directory index                             */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT dir_seek (
+	DIR *dj,		/* Pointer to directory object */
+	WORD idx		/* Directory index number */
+)
+{
+	DWORD clst;
+	WORD ic;
+
+
+	dj->index = idx;
+	clst = dj->sclust;
+	if (clst == 1 || clst >= dj->fs->max_clust)	/* Check start cluster range */
+		return FR_INT_ERR;
+	if (!clst && dj->fs->fs_type == FS_FAT32)	/* Replace cluster# 0 with root cluster# if in FAT32 */
+		clst = dj->fs->dirbase;
+
+	if (clst == 0) {	/* Static table */
+		dj->clust = clst;
+		if (idx >= dj->fs->n_rootdir)		/* Index is out of range */
+			return FR_INT_ERR;
+		dj->sect = dj->fs->dirbase + idx / (SS(dj->fs) / 32);	/* Sector# */
+	}
+	else {				/* Dynamic table */
+		ic = SS(dj->fs) / 32 * dj->fs->csize;	/* Entries per cluster */
+		while (idx >= ic) {	/* Follow cluster chain */
+			clst = get_fat(dj->fs, clst);				/* Get next cluster */
+			if (clst == 0xFFFFFFFF) return FR_DISK_ERR;	/* Disk error */
+			if (clst < 2 || clst >= dj->fs->max_clust)	/* Reached to end of table or int error */
+				return FR_INT_ERR;
+			idx -= ic;
+		}
+		dj->clust = clst;
+		dj->sect = clust2sect(dj->fs, clst) + idx / (SS(dj->fs) / 32);	/* Sector# */
+	}
+
+	dj->dir = dj->fs->win + (idx % (SS(dj->fs) / 32)) * 32;	/* Ptr to the entry in the sector */
+
+	return FR_OK;	/* Seek succeeded */
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Directory handling - Move directory index next                        */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT dir_next (	/* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:EOT and could not streach */
+	DIR *dj,		/* Pointer to directory object */
+	BOOL streach	/* FALSE: Do not streach table, TRUE: Streach table if needed */
+)
+{
+	DWORD clst;
+	WORD i;
+
+
+	i = dj->index + 1;
+	if (!i || !dj->sect)	/* Report EOT when index has reached 65535 */
+		return FR_NO_FILE;
+
+	if (!(i % (SS(dj->fs) / 32))) {	/* Sector changed? */
+		dj->sect++;					/* Next sector */
+
+		if (dj->clust == 0) {	/* Static table */
+			if (i >= dj->fs->n_rootdir)	/* Report EOT when end of table */
+				return FR_NO_FILE;
+		}
+		else {					/* Dynamic table */
+			if (((i / (SS(dj->fs) / 32)) & (dj->fs->csize - 1)) == 0) {	/* Cluster changed? */
+				clst = get_fat(dj->fs, dj->clust);				/* Get next cluster */
+				if (clst <= 1) return FR_INT_ERR;
+				if (clst == 0xFFFFFFFF) return FR_DISK_ERR;
+				if (clst >= dj->fs->max_clust) {				/* When it reached end of dynamic table */
+#if !_FS_READONLY
+					BYTE c;
+					if (!streach) return FR_NO_FILE;			/* When do not streach, report EOT */
+					clst = create_chain(dj->fs, dj->clust);		/* Streach cluster chain */
+					if (clst == 0) return FR_DENIED;			/* No free cluster */
+					if (clst == 1) return FR_INT_ERR;
+					if (clst == 0xFFFFFFFF) return FR_DISK_ERR;
+					/* Clean-up streached table */
+					if (move_window(dj->fs, 0)) return FR_DISK_ERR;	/* Flush active window */
+					mem_set(dj->fs->win, 0, SS(dj->fs));			/* Clear window buffer */
+					dj->fs->winsect = clust2sect(dj->fs, clst);	/* Cluster start sector */
+					for (c = 0; c < dj->fs->csize; c++) {		/* Fill the new cluster with 0 */
+						dj->fs->wflag = 1;
+						if (move_window(dj->fs, 0)) return FR_DISK_ERR;
+						dj->fs->winsect++;
+					}
+					dj->fs->winsect -= c;						/* Rewind window address */
+#else
+					return FR_NO_FILE;			/* Report EOT */
+#endif
+				}
+				dj->clust = clst;				/* Initialize data for new cluster */
+				dj->sect = clust2sect(dj->fs, clst);
+			}
+		}
+	}
+
+	dj->index = i;
+	dj->dir = dj->fs->win + (i % (SS(dj->fs) / 32)) * 32;
+
+	return FR_OK;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* LFN handling - Test/Pick/Fit an LFN segment from/to directory entry   */
+/*-----------------------------------------------------------------------*/
+#if _USE_LFN
+static
+const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30};	/* Offset of LFN chars in the directory entry */
+
+
+static
+BOOL cmp_lfn (			/* TRUE:Matched, FALSE:Not matched */
+	WCHAR *lfnbuf,		/* Pointer to the LFN to be compared */
+	BYTE *dir			/* Pointer to the directory entry containing a part of LFN */
+)
+{
+	int i, s;
+	WCHAR wc, uc;
+
+
+	i = ((dir[LDIR_Ord] & 0xBF) - 1) * 13;	/* Get offset in the LFN buffer */
+	s = 0; wc = 1;
+	do {
+		uc = LD_WORD(dir+LfnOfs[s]);	/* Pick an LFN character from the entry */
+		if (wc) {	/* Last char has not been processed */
+			wc = ff_wtoupper(uc);		/* Convert it to upper case */
+			if (i >= _MAX_LFN || wc != ff_wtoupper(lfnbuf[i++]))	/* Compare it */
+				return FALSE;			/* Not matched */
+		} else {
+			if (uc != 0xFFFF) return FALSE;	/* Check filler */
+		}
+	} while (++s < 13);				/* Repeat until all chars in the entry are checked */
+
+	if ((dir[LDIR_Ord] & 0x40) && wc && lfnbuf[i])	/* Last segment matched but different length */
+		return FALSE;
+
+	return TRUE;					/* The part of LFN matched */
+}
+
+
+
+static
+BOOL pick_lfn (			/* TRUE:Succeeded, FALSE:Buffer overflow */
+	WCHAR *lfnbuf,		/* Pointer to the Unicode-LFN buffer */
+	BYTE *dir			/* Pointer to the directory entry */
+)
+{
+	int i, s;
+	WCHAR wc, uc;
+
+
+	i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13;	/* Offset in the LFN buffer */
+
+	s = 0; wc = 1;
+	do {
+		uc = LD_WORD(dir+LfnOfs[s]);			/* Pick an LFN character from the entry */
+		if (wc) {	/* Last char has not been processed */
+			if (i >= _MAX_LFN) return FALSE;	/* Buffer overflow? */
+			lfnbuf[i++] = wc = uc;				/* Store it */
+		} else {
+			if (uc != 0xFFFF) return FALSE;		/* Check filler */
+		}
+	} while (++s < 13);						/* Read all character in the entry */
+
+	if (dir[LDIR_Ord] & 0x40) {				/* Put terminator if it is the last LFN part */
+		if (i >= _MAX_LFN) return FALSE;	/* Buffer overflow? */
+		lfnbuf[i] = 0;
+	}
+
+	return TRUE;
+}
+
+
+#if !_FS_READONLY
+static
+void fit_lfn (
+	const WCHAR *lfnbuf,	/* Pointer to the LFN buffer */
+	BYTE *dir,				/* Pointer to the directory entry */
+	BYTE ord,				/* LFN order (1-20) */
+	BYTE sum				/* SFN sum */
+)
+{
+	int i, s;
+	WCHAR wc;
+
+
+	dir[LDIR_Chksum] = sum;			/* Set check sum */
+	dir[LDIR_Attr] = AM_LFN;		/* Set attribute. LFN entry */
+	dir[LDIR_Type] = 0;
+	ST_WORD(dir+LDIR_FstClusLO, 0);
+
+	i = (ord - 1) * 13;				/* Get offset in the LFN buffer */
+	s = wc = 0;
+	do {
+		if (wc != 0xFFFF) wc = lfnbuf[i++];	/* Get an effective char */
+		ST_WORD(dir+LfnOfs[s], wc);	/* Put it */
+		if (!wc) wc = 0xFFFF;		/* Padding chars following last char */
+	} while (++s < 13);
+	if (wc == 0xFFFF || !lfnbuf[i]) ord |= 0x40;	/* Bottom LFN part is the start of LFN sequence */
+	dir[LDIR_Ord] = ord;			/* Set the LFN order */
+}
+
+#endif
+#endif
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Create numbered name                                                  */
+/*-----------------------------------------------------------------------*/
+#if _USE_LFN
+void gen_numname (
+	BYTE *dst,			/* Pointer to genartated SFN */
+	const BYTE *src,	/* Pointer to source SFN to be modified */
+	const WCHAR *lfn,	/* Pointer to LFN */
+	WORD num			/* Sequense number */
+)
+{
+	char ns[8];
+	int i, j;
+
+
+	mem_cpy(dst, src, 11);
+
+	if (num > 5) {	/* On many collisions, generate a hash number instead of sequencial number */
+		do num = (num >> 1) + (num << 15) + (WORD)*lfn++; while (*lfn);
+	}
+
+	/* itoa */
+	i = 7;
+	do {
+		ns[i--] = (num % 10) + '0';
+		num /= 10;
+	} while (num);
+	ns[i] = '~';
+
+	/* Append the number */
+	for (j = 0; j < i && dst[j] != ' '; j++) {
+		if (IsDBCS1(dst[j])) {
+			if (j == i - 1) break;
+			j++;
+		}
+	}
+	do {
+		dst[j++] = (i < 8) ? ns[i++] : ' ';
+	} while (j < 8);
+}
+#endif
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Calculate sum of an SFN                                               */
+/*-----------------------------------------------------------------------*/
+#if _USE_LFN
+static
+BYTE sum_sfn (
+	const BYTE *dir		/* Ptr to directory entry */
+)
+{
+	BYTE sum = 0;
+	int n = 11;
+
+	do sum = (sum >> 1) + (sum << 7) + *dir++; while (--n);
+	return sum;
+}
+#endif
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Directory handling - Find an object in the directory                  */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT dir_find (
+	DIR *dj			/* Pointer to the directory object linked to the file name */
+)
+{
+	FRESULT res;
+	BYTE c, *dir;
+#if _USE_LFN
+	BYTE a, ord, sum;
+#endif
+
+	res = dir_seek(dj, 0);			/* Rewind directory object */
+	if (res != FR_OK) return res;
+
+#if _USE_LFN
+	ord = sum = 0xFF;
+#endif
+	do {
+		res = move_window(dj->fs, dj->sect);
+		if (res != FR_OK) break;
+		dir = dj->dir;					/* Ptr to the directory entry of current index */
+		c = dir[DIR_Name];
+		if (c == 0) { res = FR_NO_FILE; break; }	/* Reached to end of table */
+#if _USE_LFN	/* LFN configuration */
+		a = dir[DIR_Attr] & AM_MASK;
+		if (c == 0xE5 || ((a & AM_VOL) && a != AM_LFN)) {	/* An entry without valid data */
+			ord = 0xFF;
+		} else {
+			if (a == AM_LFN) {			/* An LFN entry is found */
+				if (dj->lfn) {
+					if (c & 0x40) {		/* Is it start of LFN sequence? */
+						sum = dir[LDIR_Chksum];
+						c &= 0xBF; ord = c;	/* LFN start order */
+						dj->lfn_idx = dj->index;
+					}
+					/* Check validity of the LFN entry and compare it with given name */
+					ord = (c == ord && sum == dir[LDIR_Chksum] && cmp_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF;
+				}
+			} else {					/* An SFN entry is found */
+				if (!ord && sum == sum_sfn(dir)) break;	/* LFN matched? */
+				ord = 0xFF; dj->lfn_idx = 0xFFFF;	/* Reset LFN sequence */
+				if (!(dj->fn[NS] & NS_LOSS) && !mem_cmp(dir, dj->fn, 11)) break;	/* SFN matched? */
+			}
+		}
+#else		/* Non LFN configuration */
+		if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */
+			break;
+#endif
+		res = dir_next(dj, FALSE);		/* Next entry */
+	} while (res == FR_OK);
+
+	return res;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read an object from the directory                                     */
+/*-----------------------------------------------------------------------*/
+#if _FS_MINIMIZE <= 1
+static
+FRESULT dir_read (
+	DIR *dj			/* Pointer to the directory object that pointing the entry to be read */
+)
+{
+	FRESULT res;
+	BYTE c, *dir;
+#if _USE_LFN
+	BYTE a, ord = 0xFF, sum = 0xFF;
+#endif
+
+	res = FR_NO_FILE;
+	while (dj->sect) {
+		res = move_window(dj->fs, dj->sect);
+		if (res != FR_OK) break;
+		dir = dj->dir;					/* Ptr to the directory entry of current index */
+		c = dir[DIR_Name];
+		if (c == 0) { res = FR_NO_FILE; break; }	/* Reached to end of table */
+#if _USE_LFN	/* LFN configuration */
+		a = dir[DIR_Attr] & AM_MASK;
+		if (c == 0xE5 || (!_FS_RPATH && c == '.') || ((a & AM_VOL) && a != AM_LFN)) {	/* An entry without valid data */
+			ord = 0xFF;
+		} else {
+			if (a == AM_LFN) {			/* An LFN entry is found */
+				if (c & 0x40) {			/* Is it start of LFN sequence? */
+					sum = dir[LDIR_Chksum];
+					c &= 0xBF; ord = c;
+					dj->lfn_idx = dj->index;
+				}
+				/* Check LFN validity and capture it */
+				ord = (c == ord && sum == dir[LDIR_Chksum] && pick_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF;
+			} else {					/* An SFN entry is found */
+				if (ord || sum != sum_sfn(dir))	/* Is there a valid LFN? */
+					dj->lfn_idx = 0xFFFF;		/* It has no LFN. */
+				break;
+			}
+		}
+#else		/* Non LFN configuration */
+		if (c != 0xE5 && (_FS_RPATH || c != '.') && !(dir[DIR_Attr] & AM_VOL))	/* Is it a valid entry? */
+			break;
+#endif
+		res = dir_next(dj, FALSE);				/* Next entry */
+		if (res != FR_OK) break;
+	}
+
+	if (res != FR_OK) dj->sect = 0;
+
+	return res;
+}
+#endif
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Register an object to the directory                                   */
+/*-----------------------------------------------------------------------*/
+#if !_FS_READONLY
+static
+FRESULT dir_register (	/* FR_OK:Successful, FR_DENIED:No free entry or too many SFN collision, FR_DISK_ERR:Disk error */
+	DIR *dj				/* Target directory with object name to be created */
+)
+{
+	FRESULT res;
+	BYTE c, *dir;
+#if _USE_LFN	/* LFN configuration */
+	WORD n, ne, is;
+	BYTE sn[12], *fn, sum;
+	WCHAR *lfn;
+
+
+	fn = dj->fn; lfn = dj->lfn;
+	mem_cpy(sn, fn, 12);
+
+	if (_FS_RPATH && (sn[NS] & NS_DOT)) return FR_INVALID_NAME;	/* Cannot create dot entry */
+
+	if (sn[NS] & NS_LOSS) {			/* When LFN is out of 8.3 format, generate a numbered name */
+		fn[NS] = 0; dj->lfn = NULL;			/* Find only SFN */
+		for (n = 1; n < 100; n++) {
+			gen_numname(fn, sn, lfn, n);	/* Generate a numbered name */
+			res = dir_find(dj);				/* Check if the name collides with existing SFN */
+			if (res != FR_OK) break;
+		}
+		if (n == 100) return FR_DENIED;		/* Abort if too many collisions */
+		if (res != FR_NO_FILE) return res;	/* Abort if the result is other than 'not collided' */
+		fn[NS] = sn[NS]; dj->lfn = lfn;
+	}
+
+	if (sn[NS] & NS_LFN) {			/* When LFN is to be created, reserve reserve an SFN + LFN entries. */
+		for (ne = 0; lfn[ne]; ne++) ;
+		ne = (ne + 25) / 13;
+	} else {						/* Otherwise reserve only an SFN entry. */
+		ne = 1;
+	}
+
+	/* Reserve contiguous entries */
+	res = dir_seek(dj, 0);
+	if (res != FR_OK) return res;
+	n = is = 0;
+	do {
+		res = move_window(dj->fs, dj->sect);
+		if (res != FR_OK) break;
+		c = *dj->dir;				/* Check the entry status */
+		if (c == 0xE5 || c == 0) {	/* Is it a blank entry? */
+			if (n == 0) is = dj->index;	/* First index of the contigulus entry */
+			if (++n == ne) break;	/* A contiguous entry that requiered count is found */
+		} else {
+			n = 0;					/* Not a blank entry. Restart to search */
+		}
+		res = dir_next(dj, TRUE);	/* Next entry with table streach */
+	} while (res == FR_OK);
+
+	if (res == FR_OK && ne > 1) {	/* Initialize LFN entry if needed */
+		res = dir_seek(dj, is);
+		if (res == FR_OK) {
+			sum = sum_sfn(dj->fn);	/* Sum of the SFN tied to the LFN */
+			ne--;
+			do {					/* Store LFN entries in bottom first */
+				res = move_window(dj->fs, dj->sect);
+				if (res != FR_OK) break;
+				fit_lfn(dj->lfn, dj->dir, (BYTE)ne, sum);
+				dj->fs->wflag = 1;
+				res = dir_next(dj, FALSE);	/* Next entry */
+			} while (res == FR_OK && --ne);
+		}
+	}
+
+#else	/* Non LFN configuration */
+	res = dir_seek(dj, 0);
+	if (res == FR_OK) {
+		do {	/* Find a blank entry for the SFN */
+			res = move_window(dj->fs, dj->sect);
+			if (res != FR_OK) break;
+			c = *dj->dir;
+			if (c == 0xE5 || c == 0) break;	/* Is it a blank entry? */
+			res = dir_next(dj, TRUE);		/* Next entry with table streach */
+		} while (res == FR_OK);
+	}
+#endif
+
+	if (res == FR_OK) {		/* Initialize the SFN entry */
+		res = move_window(dj->fs, dj->sect);
+		if (res == FR_OK) {
+			dir = dj->dir;
+			mem_set(dir, 0, 32);		/* Clean the entry */
+			mem_cpy(dir, dj->fn, 11);	/* Put SFN */
+			dir[DIR_NTres] = *(dj->fn+NS) & (NS_BODY | NS_EXT);	/* Put NT flag */
+			dj->fs->wflag = 1;
+		}
+	}
+
+	return res;
+}
+#endif /* !_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Remove an object from the directory                                   */
+/*-----------------------------------------------------------------------*/
+#if !_FS_READONLY && !_FS_MINIMIZE
+static
+FRESULT dir_remove (	/* FR_OK: Successful, FR_DISK_ERR: A disk error */
+	DIR *dj				/* Directory object pointing the entry to be removed */
+)
+{
+	FRESULT res;
+#if _USE_LFN	/* LFN configuration */
+	WORD i;
+
+	i = dj->index;	/* SFN index */
+	res = dir_seek(dj, (WORD)((dj->lfn_idx == 0xFFFF) ? i : dj->lfn_idx));	/* Goto the SFN or top of the LFN entries */
+	if (res == FR_OK) {
+		do {
+			res = move_window(dj->fs, dj->sect);
+			if (res != FR_OK) break;
+			*dj->dir = 0xE5;			/* Mark the entry "deleted" */
+			dj->fs->wflag = 1;
+			if (dj->index >= i) break;	/* When reached SFN, all entries of the object has been deleted. */
+			res = dir_next(dj, FALSE);	/* Next entry */
+		} while (res == FR_OK);
+		if (res == FR_NO_FILE) res = FR_INT_ERR;
+	}
+
+#else			/* Non LFN configuration */
+	res = dir_seek(dj, dj->index);
+	if (res == FR_OK) {
+		res = move_window(dj->fs, dj->sect);
+		if (res == FR_OK) {
+			*dj->dir = 0xE5;			/* Mark the entry "deleted" */
+			dj->fs->wflag = 1;
+		}
+	}
+#endif
+
+	return res;
+}
+#endif /* !_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Pick a segment and create the object name in directory form           */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT create_name (
+	DIR *dj,			/* Pointer to the directory object */
+	const XCHAR **path	/* Pointer to pointer to the segment in the path string */
+)
+{
+#ifdef _EXCVT
+	static const BYTE cvt[] = _EXCVT;
+#endif
+
+#if _USE_LFN	/* LFN configuration */
+	BYTE b, cf;
+	WCHAR w, *lfn;
+	int i, ni, si, di;
+	const XCHAR *p;
+
+	/* Create LFN in Unicode */
+	si = di = 0;
+	p = *path;
+	lfn = dj->lfn;
+	for (;;) {
+		w = p[si++];					/* Get a character */
+		if (w < ' ' || w == '/' || w == '\\') break;	/* Break on end of segment */
+		if (di >= _MAX_LFN)				/* Reject too long name */
+			return FR_INVALID_NAME;
+#if !_LFN_UNICODE
+		w &= 0xFF;
+		if (IsDBCS1(w)) {				/* If it is a DBC 1st byte */
+			b = p[si++];				/* Get 2nd byte */
+			if (!IsDBCS2(b))			/* Reject invalid code for DBC */
+				return FR_INVALID_NAME;
+			w = (w << 8) + b;
+		}
+		w = ff_convert(w, 1);			/* Convert OEM to Unicode */
+		if (!w) return FR_INVALID_NAME;	/* Reject invalid code */
+#endif
+		if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) /* Reject illegal chars for LFN */
+			return FR_INVALID_NAME;
+		lfn[di++] = w;					/* Store the Unicode char */
+	}
+	*path = &p[si];						/* Rerurn pointer to the next segment */
+	cf = (w < ' ') ? NS_LAST : 0;		/* Set last segment flag if end of path */
+#if _FS_RPATH
+	if ((di == 1 && lfn[di - 1] == '.') || /* Is this a dot entry? */
+		(di == 2 && lfn[di - 1] == '.' && lfn[di - 2] == '.')) {
+		lfn[di] = 0;
+		for (i = 0; i < 11; i++)
+			dj->fn[i] = (i < di) ? '.' : ' ';
+		dj->fn[i] = cf | NS_DOT;		/* This is a dot entry */
+		return FR_OK;
+	}
+#endif
+	while (di) {						/* Strip trailing spaces and dots */
+		w = lfn[di - 1];
+		if (w != ' ' && w != '.') break;
+		di--;
+	}
+	if (!di) return FR_INVALID_NAME;	/* Reject null string */
+
+	lfn[di] = 0;						/* LFN is created */
+
+	/* Create SFN in directory form */
+	mem_set(dj->fn, ' ', 11);
+	for (si = 0; lfn[si] == ' ' || lfn[si] == '.'; si++) ;	/* Strip leading spaces and dots */
+	if (si) cf |= NS_LOSS | NS_LFN;
+	while (di && lfn[di - 1] != '.') di--;	/* Find extension (di<=si: no extension) */
+
+	b = i = 0; ni = 8;
+	for (;;) {
+		w = lfn[si++];					/* Get an LFN char */
+		if (!w) break;					/* Break on enf of the LFN */
+		if (w == ' ' || (w == '.' && si != di)) {	/* Remove spaces and dots */
+			cf |= NS_LOSS | NS_LFN; continue;
+		}
+
+		if (i >= ni || si == di) {		/* Extension or end of SFN */
+			if (ni == 11) {				/* Long extension */
+				cf |= NS_LOSS | NS_LFN; break;
+			}
+			if (si != di) cf |= NS_LOSS | NS_LFN;	/* Out of 8.3 format */
+			if (si > di) break;			/* No extension */
+			si = di; i = 8; ni = 11;	/* Enter extension section */
+			b <<= 2; continue;
+		}
+
+		if (w >= 0x80) {				/* Non ASCII char */
+#ifdef _EXCVT
+			w = ff_convert(w, 0);		/* Unicode -> OEM code */
+			if (w) w = cvt[w - 0x80];	/* Convert extended char to upper (SBCS) */
+#else
+			w = ff_convert(ff_wtoupper(w), 0);	/* Upper converted Unicode -> OEM code */
+#endif
+			cf |= NS_LFN;				/* Force create LFN entry */
+		}
+
+		if (_DF1S && w >= 0x100) {		/* Double byte char */
+			if (i >= ni - 1) {
+				cf |= NS_LOSS | NS_LFN; i = ni; continue;
+			}
+			dj->fn[i++] = (BYTE)(w >> 8);
+		} else {						/* Single byte char */
+			if (!w || chk_chr("+,;[=]", w)) {		/* Replace illegal chars for SFN */
+				w = '_'; cf |= NS_LOSS | NS_LFN;	/* Lossy conversion */
+			} else {
+				if (IsUpper(w)) {		/* ASCII large capital */
+					b |= 2;
+				} else {
+					if (IsLower(w)) {	/* ASCII small capital */
+						b |= 1; w -= 0x20;
+					}
+				}
+			}
+		}
+		dj->fn[i++] = (BYTE)w;
+	}
+
+	if (dj->fn[0] == 0xE5) dj->fn[0] = 0x05;	/* If the first char collides with deleted mark, replace it with 0x05 */
+
+	if (ni == 8) b <<= 2;
+	if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03)	/* Create LFN entry when there are composite capitals */
+		cf |= NS_LFN;
+	if (!(cf & NS_LFN)) {						/* When LFN is in 8.3 format without extended char, NT flags are created */
+		if ((b & 0x03) == 0x01) cf |= NS_EXT;	/* NT flag (Extension has only small capital) */
+		if ((b & 0x0C) == 0x04) cf |= NS_BODY;	/* NT flag (Filename has only small capital) */
+	}
+
+	dj->fn[NS] = cf;	/* SFN is created */
+
+	return FR_OK;
+
+
+#else	/* Non-LFN configuration */
+	BYTE b, c, d, *sfn;
+	int ni, si, i;
+	const char *p;
+
+	/* Create file name in directory form */
+	sfn = dj->fn;
+	mem_set(sfn, ' ', 11);
+	si = i = b = 0; ni = 8;
+	p = *path;
+#if _FS_RPATH
+	if (p[si] == '.') { /* Is this a dot entry? */
+		for (;;) {
+			c = p[si++];
+			if (c != '.' || si >= 3) break;
+			sfn[i++] = c;
+		}
+		if (c != '/' && c != '\\' && c > ' ') return FR_INVALID_NAME;
+		*path = &p[si];									/* Rerurn pointer to the next segment */
+		sfn[NS] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT;	/* Set last segment flag if end of path */
+		return FR_OK;
+	}
+#endif
+	for (;;) {
+		c = p[si++];
+		if (c <= ' ' || c == '/' || c == '\\') break;	/* Break on end of segment */
+		if (c == '.' || i >= ni) {
+			if (ni != 8 || c != '.') return FR_INVALID_NAME;
+			i = 8; ni = 11;
+			b <<= 2; continue;
+		}
+		if (c >= 0x80) {				/* Extended char */
+#ifdef _EXCVT
+			c = cvt[c - 0x80];			/* Convert extend char (SBCS) */
+#else
+			b |= 3;						/* Eliminate NT flag if ext char is exist */
+#if !_DF1S	/* ASCII only cfg */
+			return FR_INVALID_NAME;
+#endif
+#endif
+		}
+		if (IsDBCS1(c)) {				/* DBC 1st byte? */
+			d = p[si++];				/* Get 2nd byte */
+			if (!IsDBCS2(d) || i >= ni - 1)	/* Reject invalid DBC */
+				return FR_INVALID_NAME;
+			sfn[i++] = c;
+			sfn[i++] = d;
+		} else {						/* Single byte code */
+			if (chk_chr(" \"*+,[=]|\x7F", c))	/* Reject illegal chrs for SFN */
+				return FR_INVALID_NAME;
+			if (IsUpper(c)) {			/* ASCII large capital? */
+				b |= 2;
+			} else {
+				if (IsLower(c)) {		/* ASCII small capital? */
+					b |= 1; c -= 0x20;
+				}
+			}
+			sfn[i++] = c;
+		}
+	}
+	*path = &p[si];						/* Rerurn pointer to the next segment */
+	c = (c <= ' ') ? NS_LAST : 0;		/* Set last segment flag if end of path */
+
+	if (!i) return FR_INVALID_NAME;		/* Reject null string */
+	if (sfn[0] == 0xE5) sfn[0] = 0x05;	/* When first char collides with 0xE5, replace it with 0x05 */
+
+	if (ni == 8) b <<= 2;
+	if ((b & 0x03) == 0x01) c |= NS_EXT;	/* NT flag (Extension has only small capital) */
+	if ((b & 0x0C) == 0x04) c |= NS_BODY;	/* NT flag (Filename has only small capital) */
+
+	sfn[NS] = c;		/* Store NT flag, File name is created */
+
+	return FR_OK;
+#endif
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Get file information from directory entry                             */
+/*-----------------------------------------------------------------------*/
+#if _FS_MINIMIZE <= 1
+static
+void get_fileinfo (		/* No return code */
+	DIR *dj,			/* Pointer to the directory object */
+	FILINFO *fno	 	/* Pointer to the file information to be filled */
+)
+{
+	int i;
+	BYTE c, nt, *dir;
+	char *p;
+
+
+	p = fno->fname;
+	if (dj->sect) {
+		dir = dj->dir;
+		nt = dir[DIR_NTres];		/* NT flag */
+		for (i = 0; i < 8; i++) {	/* Copy name body */
+			c = dir[i];
+			if (c == ' ') break;
+			if (c == 0x05) c = 0xE5;
+			if (_USE_LFN && (nt & NS_BODY) && IsUpper(c)) c += 0x20;
+			*p++ = c;
+		}
+		if (dir[8] != ' ') {		/* Copy name extension */
+			*p++ = '.';
+			for (i = 8; i < 11; i++) {
+				c = dir[i];
+				if (c == ' ') break;
+				if (_USE_LFN && (nt & NS_EXT) && IsUpper(c)) c += 0x20;
+				*p++ = c;
+			}
+		}
+		fno->fattrib = dir[DIR_Attr];				/* Attribute */
+		fno->fsize = LD_DWORD(dir+DIR_FileSize);	/* Size */
+		fno->fdate = LD_WORD(dir+DIR_WrtDate);		/* Date */
+		fno->ftime = LD_WORD(dir+DIR_WrtTime);		/* Time */
+	}
+	*p = 0;
+
+#if _USE_LFN
+	if (fno->lfname) {
+		XCHAR *tp = fno->lfname;
+		WCHAR w, *lfn;
+
+		i = 0;
+		if (dj->sect && dj->lfn_idx != 0xFFFF) {/* Get LFN if available */
+			lfn = dj->lfn;
+			while ((w = *lfn++) != 0) {			/* Get an LFN char */
+#if !_LFN_UNICODE
+				w = ff_convert(w, 0);			/* Unicode -> OEM conversion */
+				if (!w) { i = 0; break; }		/* Could not convert, no LFN */
+				if (_DF1S && w >= 0x100)		/* Put 1st byte if it is a DBC */
+					tp[i++] = (XCHAR)(w >> 8);
+#endif
+				if (i >= fno->lfsize - 1) { i = 0; break; }	/* Buffer overrun, no LFN */
+				tp[i++] = (XCHAR)w;
+			}
+		}
+		tp[i] = 0;	/* Terminator */
+	}
+#endif
+}
+#endif /* _FS_MINIMIZE <= 1 */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Follow a file path                                                    */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT follow_path (	/* FR_OK(0): successful, !=0: error code */
+	DIR *dj,			/* Directory object to return last directory and found object */
+	const XCHAR *path	/* Full-path string to find a file or directory */
+)
+{
+	FRESULT res;
+	BYTE *dir, last;
+
+
+	while (!_USE_LFN && *path == ' ') path++;	/* Skip leading spaces */
+#if _FS_RPATH
+	if (*path == '/' || *path == '\\') { /* There is a heading separator */
+		path++;	dj->sclust = 0;		/* Strip it and start from the root dir */
+	} else {							/* No heading saparator */
+		dj->sclust = dj->fs->cdir;	/* Start from the current dir */
+	}
+#else
+	if (*path == '/' || *path == '\\')	/* Strip heading separator if exist */
+		path++;
+	dj->sclust = 0;						/* Start from the root dir */
+#endif
+
+	if ((UINT)*path < ' ') {			/* Null path means the start directory itself */
+		res = dir_seek(dj, 0);
+		dj->dir = NULL;
+
+	} else {							/* Follow path */
+		for (;;) {
+			res = create_name(dj, &path);	/* Get a segment */
+			if (res != FR_OK) break;
+			res = dir_find(dj);				/* Find it */
+			last = *(dj->fn+NS) & NS_LAST;
+			if (res != FR_OK) {				/* Could not find the object */
+				if (res == FR_NO_FILE && !last)
+					res = FR_NO_PATH;
+				break;
+			}
+			if (last) break;				/* Last segment match. Function completed. */
+			dir = dj->dir;					/* There is next segment. Follow the sub directory */
+			if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */
+				res = FR_NO_PATH; break;
+			}
+			dj->sclust = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO);
+		}
+	}
+
+	return res;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Load boot record and check if it is an FAT boot record                */
+/*-----------------------------------------------------------------------*/
+
+static
+BYTE check_fs (	/* 0:The FAT boot record, 1:Valid boot record but not an FAT, 2:Not a boot record, 3:Error */
+	FATFS *fs,	/* File system object */
+	DWORD sect	/* Sector# (lba) to check if it is an FAT boot record or not */
+)
+{
+	if (disk_read(fs->drive, fs->win, sect, 1) != RES_OK)	/* Load boot record */
+		return 3;
+	if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55)		/* Check record signature (always placed at offset 510 even if the sector size is >512) */
+		return 2;
+
+	if ((LD_DWORD(&fs->win[BS_FilSysType]) & 0xFFFFFF) == 0x544146)	/* Check "FAT" string */
+		return 0;
+	if ((LD_DWORD(&fs->win[BS_FilSysType32]) & 0xFFFFFF) == 0x544146)
+		return 0;
+
+	return 1;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Make sure that the file system is valid                               */
+/*-----------------------------------------------------------------------*/
+
+
+FRESULT chk_mounted (	/* FR_OK(0): successful, !=0: any error occured */
+	const XCHAR **path,	/* Pointer to pointer to the path name (drive number) */
+	FATFS **rfs,		/* Pointer to pointer to the found file system object */
+	BYTE chk_wp			/* !=0: Check media write protection for write access */
+)
+{
+	BYTE fmt, *tbl;
+	UINT vol;
+	DSTATUS stat;
+	DWORD bsect, fsize, tsect, mclst;
+	const XCHAR *p = *path;
+	FATFS *fs;
+
+	/* Get logical drive number from the path name */
+	vol = p[0] - '0';				/* Is there a drive number? */
+	if (vol <= 9 && p[1] == ':') {	/* Found a drive number, get and strip it */
+		p += 2; *path = p;			/* Return pointer to the path name */
+	} else {						/* No drive number is given */
+#if _FS_RPATH
+		vol = Drive;				/* Use current drive */
+#else
+		vol = 0;					/* Use drive 0 */
+#endif
+	}
+
+	/* Check if the logical drive is valid or not */
+	if (vol >= _DRIVES) 			/* Is the drive number valid? */
+		return FR_INVALID_DRIVE;
+	*rfs = fs = FatFs[vol];			/* Returen pointer to the corresponding file system object */
+	if (!fs) return FR_NOT_ENABLED;	/* Is the file system object available? */
+
+	ENTER_FF(fs);					/* Lock file system */
+
+	if (fs->fs_type) {				/* If the logical drive has been mounted */
+		stat = disk_status(fs->drive);
+		if (!(stat & STA_NOINIT)) {	/* and the physical drive is kept initialized (has not been changed), */
+#if !_FS_READONLY
+			if (chk_wp && (stat & STA_PROTECT))	/* Check write protection if needed */
+				return FR_WRITE_PROTECTED;
+#endif
+			return FR_OK;			/* The file system object is valid */
+		}
+	}
+
+	/* The logical drive must be mounted. Following code attempts to mount the volume */
+
+	fs->fs_type = 0;					/* Clear the file system object */
+	fs->drive = (BYTE)LD2PD(vol);		/* Bind the logical drive and a physical drive */
+	stat = disk_initialize(fs->drive);	/* Initialize low level disk I/O layer */
+	if (stat & STA_NOINIT)				/* Check if the drive is ready */
+		return FR_NOT_READY;
+#if _MAX_SS != 512						/* Get disk sector size if needed */
+	if (disk_ioctl(fs->drive, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS)
+		return FR_NO_FILESYSTEM;
+#endif
+#if !_FS_READONLY
+	if (chk_wp && (stat & STA_PROTECT))	/* Check disk write protection if needed */
+		return FR_WRITE_PROTECTED;
+#endif
+	/* Search FAT partition on the drive */
+	fmt = check_fs(fs, bsect = 0);		/* Check sector 0 as an SFD format */
+	if (fmt == 1) {						/* Not an FAT boot record, it may be patitioned */
+		/* Check a partition listed in top of the partition table */
+		tbl = &fs->win[MBR_Table + LD2PT(vol) * 16];	/* Partition table */
+		if (tbl[4]) {									/* Is the partition existing? */
+			bsect = LD_DWORD(&tbl[8]);					/* Partition offset in LBA */
+			fmt = check_fs(fs, bsect);					/* Check the partition */
+		}
+	}
+	if (fmt == 3) return FR_DISK_ERR;
+	if (fmt || LD_WORD(fs->win+BPB_BytsPerSec) != SS(fs))	/* No valid FAT patition is found */
+		return FR_NO_FILESYSTEM;
+
+	/* Initialize the file system object */
+	fsize = LD_WORD(fs->win+BPB_FATSz16);				/* Number of sectors per FAT */
+	if (!fsize) fsize = LD_DWORD(fs->win+BPB_FATSz32);
+	fs->sects_fat = fsize;
+	fs->n_fats = fs->win[BPB_NumFATs];					/* Number of FAT copies */
+	fsize *= fs->n_fats;								/* (Number of sectors in FAT area) */
+	fs->fatbase = bsect + LD_WORD(fs->win+BPB_RsvdSecCnt); /* FAT start sector (lba) */
+	fs->csize = fs->win[BPB_SecPerClus];				/* Number of sectors per cluster */
+	fs->n_rootdir = LD_WORD(fs->win+BPB_RootEntCnt);	/* Nmuber of root directory entries */
+	tsect = LD_WORD(fs->win+BPB_TotSec16);				/* Number of sectors on the volume */
+	if (!tsect) tsect = LD_DWORD(fs->win+BPB_TotSec32);
+	fs->max_clust = mclst = (tsect						/* Last cluster# + 1 (Number of clusters + 2) */
+		- LD_WORD(fs->win+BPB_RsvdSecCnt) - fsize - fs->n_rootdir / (SS(fs)/32)
+		) / fs->csize + 2;
+
+	fmt = FS_FAT12;										/* Determine the FAT sub type */
+	if (mclst >= 0xFF7) fmt = FS_FAT16;					/* Number of clusters >= 0xFF5 */
+	if (mclst >= 0xFFF7) fmt = FS_FAT32;				/* Number of clusters >= 0xFFF5 */
+
+	if (fmt == FS_FAT32)
+		fs->dirbase = LD_DWORD(fs->win+BPB_RootClus);	/* Root directory start cluster */
+	else
+		fs->dirbase = fs->fatbase + fsize;				/* Root directory start sector (lba) */
+	fs->database = fs->fatbase + fsize + fs->n_rootdir / (SS(fs)/32);	/* Data start sector (lba) */
+
+#if !_FS_READONLY
+	/* Initialize allocation information */
+	fs->free_clust = 0xFFFFFFFF;
+	fs->wflag = 0;
+	/* Get fsinfo if needed */
+	if (fmt == FS_FAT32) {
+	 	fs->fsi_flag = 0;
+		fs->fsi_sector = bsect + LD_WORD(fs->win+BPB_FSInfo);
+		if (disk_read(fs->drive, fs->win, fs->fsi_sector, 1) == RES_OK &&
+			LD_WORD(fs->win+BS_55AA) == 0xAA55 &&
+			LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 &&
+			LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) {
+			fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free);
+			fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count);
+		}
+	}
+#endif
+	fs->fs_type = fmt;		/* FAT sub-type */
+	fs->winsect = 0;		/* Invalidate sector cache */
+#if _FS_RPATH
+	fs->cdir = 0;			/* Current directory (root dir) */
+#endif
+	fs->id = ++Fsid;		/* File system mount ID */
+
+	return FR_OK;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Check if the file/dir object is valid or not                          */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT validate (	/* FR_OK(0): The object is valid, !=0: Invalid */
+	FATFS *fs,		/* Pointer to the file system object */
+	WORD id			/* Member id of the target object to be checked */
+)
+{
+	if (!fs || !fs->fs_type || fs->id != id)
+		return FR_INVALID_OBJECT;
+
+	ENTER_FF(fs);		/* Lock file system */
+
+	if (disk_status(fs->drive) & STA_NOINIT)
+		return FR_NOT_READY;
+
+	return FR_OK;
+}
+
+
+
+
+/*--------------------------------------------------------------------------
+
+   Public Functions
+
+--------------------------------------------------------------------------*/
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Mount/Unmount a Locical Drive                                         */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_mount (
+	BYTE vol,		/* Logical drive number to be mounted/unmounted */
+	FATFS *fs		/* Pointer to new file system object (NULL for unmount)*/
+)
+{
+	FATFS *rfs;
+
+
+	if (vol >= _DRIVES)				/* Check if the drive number is valid */
+		return FR_INVALID_DRIVE;
+	rfs = FatFs[vol];				/* Get current fs object */
+
+	if (rfs) {
+#if _FS_REENTRANT					/* Discard sync object of the current volume */
+		if (!ff_del_syncobj(rfs->sobj)) return FR_INT_ERR;
+#endif
+		rfs->fs_type = 0;			/* Clear old fs object */
+	}
+
+	if (fs) {
+		fs->fs_type = 0;			/* Clear new fs object */
+#if _FS_REENTRANT					/* Create sync object for the new volume */
+		if (!ff_cre_syncobj(vol, &fs->sobj)) return FR_INT_ERR;
+#endif
+	}
+	FatFs[vol] = fs;				/* Register new fs object */
+
+	return FR_OK;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Open or Create a File                                                 */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_open (
+	FIL *fp,			/* Pointer to the blank file object */
+	const XCHAR *path,	/* Pointer to the file name */
+	BYTE mode			/* Access mode and file open mode flags */
+)
+{
+	FRESULT res;
+	DIR dj;
+	NAMEBUF(sfn, lfn);
+	BYTE *dir;
+
+
+	fp->fs = NULL;		/* Clear file object */
+#if !_FS_READONLY
+	mode &= (FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW);
+	res = chk_mounted(&path, &dj.fs, (BYTE)(mode & (FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)));
+#else
+	mode &= FA_READ;
+	res = chk_mounted(&path, &dj.fs, 0);
+#endif
+	if (res != FR_OK) LEAVE_FF(dj.fs, res);
+	INITBUF(dj, sfn, lfn);
+	res = follow_path(&dj, path);	/* Follow the file path */
+
+#if !_FS_READONLY
+	/* Create or Open a file */
+	if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) {
+		DWORD ps, cl;
+
+		if (res != FR_OK) {			/* No file, create new */
+			if (res == FR_NO_FILE)	/* There is no file to open, create a new entry */
+				res = dir_register(&dj);
+			if (res != FR_OK) LEAVE_FF(dj.fs, res);
+			mode |= FA_CREATE_ALWAYS;
+			dir = dj.dir;			/* Created entry (SFN entry) */
+		}
+		else {						/* Any object is already existing */
+			if (mode & FA_CREATE_NEW)			/* Cannot create new */
+				LEAVE_FF(dj.fs, FR_EXIST);
+			dir = dj.dir;
+			if (!dir || (dir[DIR_Attr] & (AM_RDO | AM_DIR)))	/* Cannot overwrite it (R/O or DIR) */
+				LEAVE_FF(dj.fs, FR_DENIED);
+			if (mode & FA_CREATE_ALWAYS) {		/* Resize it to zero on over write mode */
+				cl = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO);	/* Get start cluster */
+				ST_WORD(dir+DIR_FstClusHI, 0);	/* cluster = 0 */
+				ST_WORD(dir+DIR_FstClusLO, 0);
+				ST_DWORD(dir+DIR_FileSize, 0);	/* size = 0 */
+				dj.fs->wflag = 1;
+				ps = dj.fs->winsect;			/* Remove the cluster chain */
+				if (cl) {
+					res = remove_chain(dj.fs, cl);
+					if (res) LEAVE_FF(dj.fs, res);
+					dj.fs->last_clust = cl - 1;	/* Reuse the cluster hole */
+				}
+				res = move_window(dj.fs, ps);
+				if (res != FR_OK) LEAVE_FF(dj.fs, res);
+			}
+		}
+		if (mode & FA_CREATE_ALWAYS) {
+			dir[DIR_Attr] = 0;					/* Reset attribute */
+			ps = get_fattime();
+			ST_DWORD(dir+DIR_CrtTime, ps);		/* Created time */
+			dj.fs->wflag = 1;
+			mode |= FA__WRITTEN;				/* Set file changed flag */
+		}
+	}
+	/* Open an existing file */
+	else {
+#endif /* !_FS_READONLY */
+		if (res != FR_OK) LEAVE_FF(dj.fs, res);	/* Follow failed */
+		dir = dj.dir;
+		if (!dir || (dir[DIR_Attr] & AM_DIR))	/* It is a directory */
+			LEAVE_FF(dj.fs, FR_NO_FILE);
+#if !_FS_READONLY
+		if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */
+			LEAVE_FF(dj.fs, FR_DENIED);
+	}
+	fp->dir_sect = dj.fs->winsect;		/* Pointer to the directory entry */
+	fp->dir_ptr = dj.dir;
+#endif
+	fp->flag = mode;					/* File access mode */
+	fp->org_clust =						/* File start cluster */
+		((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO);
+	fp->fsize = LD_DWORD(dir+DIR_FileSize);	/* File size */
+	fp->fptr = 0; fp->csect = 255;		/* File pointer */
+	fp->dsect = 0;
+	fp->fs = dj.fs; fp->id = dj.fs->id;	/* Owner file system object of the file */
+
+	LEAVE_FF(dj.fs, FR_OK);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read File                                                             */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_read (
+	FIL *fp, 		/* Pointer to the file object */
+	void *buff,		/* Pointer to data buffer */
+	UINT btr,		/* Number of bytes to read */
+	UINT *br		/* Pointer to number of bytes read */
+)
+{
+	FRESULT res;
+	DWORD clst, sect, remain;
+	UINT rcnt, cc;
+	BYTE *rbuff = buff;
+
+
+	*br = 0;	/* Initialize bytes read */
+
+	res = validate(fp->fs, fp->id);					/* Check validity of the object */
+	if (res != FR_OK) LEAVE_FF(fp->fs, res);
+	if (fp->flag & FA__ERROR)						/* Check abort flag */
+		LEAVE_FF(fp->fs, FR_INT_ERR);
+	if (!(fp->flag & FA_READ)) 						/* Check access mode */
+		LEAVE_FF(fp->fs, FR_DENIED);
+	remain = fp->fsize - fp->fptr;
+	if (btr > remain) btr = (UINT)remain;			/* Truncate btr by remaining bytes */
+
+	for ( ;  btr;									/* Repeat until all data transferred */
+		rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) {
+		if ((fp->fptr % SS(fp->fs)) == 0) {			/* On the sector boundary? */
+			if (fp->csect >= fp->fs->csize) {		/* On the cluster boundary? */
+				clst = (fp->fptr == 0) ?			/* On the top of the file? */
+					fp->org_clust : get_fat(fp->fs, fp->curr_clust);
+				if (clst <= 1) ABORT(fp->fs, FR_INT_ERR);
+				if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
+				fp->curr_clust = clst;				/* Update current cluster */
+				fp->csect = 0;						/* Reset sector offset in the cluster */
+			}
+			sect = clust2sect(fp->fs, fp->curr_clust);	/* Get current sector */
+			if (!sect) ABORT(fp->fs, FR_INT_ERR);
+			sect += fp->csect;
+			cc = btr / SS(fp->fs);					/* When remaining bytes >= sector size, */
+			if (cc) {								/* Read maximum contiguous sectors directly */
+				if (fp->csect + cc > fp->fs->csize)	/* Clip at cluster boundary */
+					cc = fp->fs->csize - fp->csect;
+				if (disk_read(fp->fs->drive, rbuff, sect, (BYTE)cc) != RES_OK)
+					ABORT(fp->fs, FR_DISK_ERR);
+#if !_FS_READONLY && _FS_MINIMIZE <= 2
+#if _FS_TINY
+				if (fp->fs->wflag && fp->fs->winsect - sect < cc)		/* Replace one of the read sectors with cached data if it contains a dirty sector */
+					mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs));
+#else
+				if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc)	/* Replace one of the read sectors with cached data if it contains a dirty sector */
+					mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs));
+#endif
+#endif
+				fp->csect += (BYTE)cc;				/* Next sector address in the cluster */
+				rcnt = SS(fp->fs) * cc;				/* Number of bytes transferred */
+				continue;
+			}
+#if !_FS_TINY
+#if !_FS_READONLY
+			if (fp->flag & FA__DIRTY) {			/* Write sector I/O buffer if needed */
+				if (disk_write(fp->fs->drive, fp->buf, fp->dsect, 1) != RES_OK)
+					ABORT(fp->fs, FR_DISK_ERR);
+				fp->flag &= ~FA__DIRTY;
+			}
+#endif
+			if (fp->dsect != sect) {			/* Fill sector buffer with file data */
+				if (disk_read(fp->fs->drive, fp->buf, sect, 1) != RES_OK)
+					ABORT(fp->fs, FR_DISK_ERR);
+			}
+#endif
+			fp->dsect = sect;
+			fp->csect++;							/* Next sector address in the cluster */
+		}
+		rcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs));	/* Get partial sector data from sector buffer */
+		if (rcnt > btr) rcnt = btr;
+#if _FS_TINY
+		if (move_window(fp->fs, fp->dsect))			/* Move sector window */
+			ABORT(fp->fs, FR_DISK_ERR);
+		mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt);	/* Pick partial sector */
+#else
+		mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt);	/* Pick partial sector */
+#endif
+	}
+
+	LEAVE_FF(fp->fs, FR_OK);
+}
+
+
+
+
+#if !_FS_READONLY
+/*-----------------------------------------------------------------------*/
+/* Write File                                                            */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_write (
+	FIL *fp,			/* Pointer to the file object */
+	const void *buff,	/* Pointer to the data to be written */
+	UINT btw,			/* Number of bytes to write */
+	UINT *bw			/* Pointer to number of bytes written */
+)
+{
+	FRESULT res;
+	DWORD clst, sect;
+	UINT wcnt, cc;
+	const BYTE *wbuff = buff;
+
+
+	*bw = 0;	/* Initialize bytes written */
+
+	res = validate(fp->fs, fp->id);					/* Check validity of the object */
+	if (res != FR_OK) LEAVE_FF(fp->fs, res);
+	if (fp->flag & FA__ERROR)						/* Check abort flag */
+		LEAVE_FF(fp->fs, FR_INT_ERR);
+	if (!(fp->flag & FA_WRITE))						/* Check access mode */
+		LEAVE_FF(fp->fs, FR_DENIED);
+	if (fp->fsize + btw < fp->fsize) btw = 0;		/* File size cannot reach 4GB */
+
+	for ( ;  btw;									/* Repeat until all data transferred */
+		wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) {
+		if ((fp->fptr % SS(fp->fs)) == 0) {			/* On the sector boundary? */
+			if (fp->csect >= fp->fs->csize) {		/* On the cluster boundary? */
+				if (fp->fptr == 0) {				/* On the top of the file? */
+					clst = fp->org_clust;			/* Follow from the origin */
+					if (clst == 0)					/* When there is no cluster chain, */
+						fp->org_clust = clst = create_chain(fp->fs, 0);	/* Create a new cluster chain */
+				} else {							/* Middle or end of the file */
+					clst = create_chain(fp->fs, fp->curr_clust);			/* Follow or streach cluster chain */
+				}
+				if (clst == 0) break;				/* Could not allocate a new cluster (disk full) */
+				if (clst == 1) ABORT(fp->fs, FR_INT_ERR);
+				if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
+				fp->curr_clust = clst;				/* Update current cluster */
+				fp->csect = 0;						/* Reset sector address in the cluster */
+			}
+#if _FS_TINY
+			if (fp->fs->winsect == fp->dsect && move_window(fp->fs, 0))	/* Write back data buffer prior to following direct transfer */
+				ABORT(fp->fs, FR_DISK_ERR);
+#else
+			if (fp->flag & FA__DIRTY) {		/* Write back data buffer prior to following direct transfer */
+				if (disk_write(fp->fs->drive, fp->buf, fp->dsect, 1) != RES_OK)
+					ABORT(fp->fs, FR_DISK_ERR);
+				fp->flag &= ~FA__DIRTY;
+			}
+#endif
+			sect = clust2sect(fp->fs, fp->curr_clust);	/* Get current sector */
+			if (!sect) ABORT(fp->fs, FR_INT_ERR);
+			sect += fp->csect;
+			cc = btw / SS(fp->fs);					/* When remaining bytes >= sector size, */
+			if (cc) {								/* Write maximum contiguous sectors directly */
+				if (fp->csect + cc > fp->fs->csize)	/* Clip at cluster boundary */
+					cc = fp->fs->csize - fp->csect;
+				if (disk_write(fp->fs->drive, wbuff, sect, (BYTE)cc) != RES_OK)
+					ABORT(fp->fs, FR_DISK_ERR);
+#if _FS_TINY
+				if (fp->fs->winsect - sect < cc) {	/* Refill sector cache if it gets dirty by the direct write */
+					mem_cpy(fp->fs->win, wbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), SS(fp->fs));
+					fp->fs->wflag = 0;
+				}
+#else
+				if (fp->dsect - sect < cc) {		/* Refill sector cache if it gets dirty by the direct write */
+					mem_cpy(fp->buf, wbuff + ((fp->dsect - sect) * SS(fp->fs)), SS(fp->fs));
+					fp->flag &= ~FA__DIRTY;
+				}
+#endif
+				fp->csect += (BYTE)cc;				/* Next sector address in the cluster */
+				wcnt = SS(fp->fs) * cc;				/* Number of bytes transferred */
+				continue;
+			}
+#if _FS_TINY
+			if (fp->fptr >= fp->fsize) {			/* Avoid silly buffer filling at growing edge */
+				if (move_window(fp->fs, 0)) ABORT(fp->fs, FR_DISK_ERR);
+				fp->fs->winsect = sect;
+			}
+#else
+			if (fp->dsect != sect) {				/* Fill sector buffer with file data */
+				if (fp->fptr < fp->fsize &&
+					disk_read(fp->fs->drive, fp->buf, sect, 1) != RES_OK)
+						ABORT(fp->fs, FR_DISK_ERR);
+			}
+#endif
+			fp->dsect = sect;
+			fp->csect++;							/* Next sector address in the cluster */
+		}
+		wcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs));	/* Put partial sector into file I/O buffer */
+		if (wcnt > btw) wcnt = btw;
+#if _FS_TINY
+		if (move_window(fp->fs, fp->dsect))			/* Move sector window */
+			ABORT(fp->fs, FR_DISK_ERR);
+		mem_cpy(&fp->fs->win[fp->fptr % SS(fp->fs)], wbuff, wcnt);	/* Fit partial sector */
+		fp->fs->wflag = 1;
+#else
+		mem_cpy(&fp->buf[fp->fptr % SS(fp->fs)], wbuff, wcnt);	/* Fit partial sector */
+		fp->flag |= FA__DIRTY;
+#endif
+	}
+
+	if (fp->fptr > fp->fsize) fp->fsize = fp->fptr;	/* Update file size if needed */
+	fp->flag |= FA__WRITTEN;						/* Set file changed flag */
+
+	LEAVE_FF(fp->fs, FR_OK);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Synchronize the File Object                                           */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_sync (
+	FIL *fp		/* Pointer to the file object */
+)
+{
+	FRESULT res;
+	DWORD tim;
+	BYTE *dir;
+
+
+	res = validate(fp->fs, fp->id);		/* Check validity of the object */
+	if (res == FR_OK) {
+		if (fp->flag & FA__WRITTEN) {	/* Has the file been written? */
+#if !_FS_TINY	/* Write-back dirty buffer */
+			if (fp->flag & FA__DIRTY) {
+				if (disk_write(fp->fs->drive, fp->buf, fp->dsect, 1) != RES_OK)
+					LEAVE_FF(fp->fs, FR_DISK_ERR);
+				fp->flag &= ~FA__DIRTY;
+			}
+#endif
+			/* Update the directory entry */
+			res = move_window(fp->fs, fp->dir_sect);
+			if (res == FR_OK) {
+				dir = fp->dir_ptr;
+				dir[DIR_Attr] |= AM_ARC;					/* Set archive bit */
+				ST_DWORD(dir+DIR_FileSize, fp->fsize);		/* Update file size */
+				ST_WORD(dir+DIR_FstClusLO, fp->org_clust);	/* Update start cluster */
+				ST_WORD(dir+DIR_FstClusHI, fp->org_clust >> 16);
+				tim = get_fattime();			/* Updated time */
+				ST_DWORD(dir+DIR_WrtTime, tim);
+				fp->flag &= ~FA__WRITTEN;
+				fp->fs->wflag = 1;
+				res = sync(fp->fs);
+			}
+		}
+	}
+
+	LEAVE_FF(fp->fs, res);
+}
+
+#endif /* !_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Close File                                                            */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_close (
+	FIL *fp		/* Pointer to the file object to be closed */
+)
+{
+	FRESULT res;
+
+
+#if _FS_READONLY
+	res = validate(fp->fs, fp->id);
+	if (res == FR_OK) fp->fs = NULL;
+	LEAVE_FF(fp->fs, res);
+#else
+	res = f_sync(fp);
+	if (res == FR_OK) fp->fs = NULL;
+	return res;
+#endif
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Change Current Drive/Directory                                        */
+/*-----------------------------------------------------------------------*/
+
+#if _FS_RPATH
+
+FRESULT f_chdrive (
+	BYTE drv		/* Drive number */
+)
+{
+	if (drv >= _DRIVES) return FR_INVALID_DRIVE;
+
+	Drive = drv;
+
+	return FR_OK;
+}
+
+
+
+
+FRESULT f_chdir (
+	const XCHAR *path	/* Pointer to the directory path */
+)
+{
+	FRESULT res;
+	DIR dj;
+	NAMEBUF(sfn, lfn);
+	BYTE *dir;
+
+
+	res = chk_mounted(&path, &dj.fs, 0);
+	if (res == FR_OK) {
+		INITBUF(dj, sfn, lfn);
+		res = follow_path(&dj, path);		/* Follow the file path */
+		if (res == FR_OK) {					/* Follow completed */
+			dir = dj.dir;					/* Pointer to the entry */
+			if (!dir) {
+				dj.fs->cdir = 0;			/* No entry (root dir) */
+			} else {
+				if (dir[DIR_Attr] & AM_DIR)	/* Reached to the dir */
+					dj.fs->cdir = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO);
+				else
+					res = FR_NO_PATH;		/* Could not reach the dir (it is a file) */
+			}
+		}
+		if (res == FR_NO_FILE) res = FR_NO_PATH;
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+
+#endif
+
+
+
+#if _FS_MINIMIZE <= 2
+/*-----------------------------------------------------------------------*/
+/* Seek File R/W Pointer                                                 */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_lseek (
+	FIL *fp,		/* Pointer to the file object */
+	DWORD ofs		/* File pointer from top of file */
+)
+{
+	FRESULT res;
+	DWORD clst, bcs, nsect, ifptr;
+
+
+	res = validate(fp->fs, fp->id);		/* Check validity of the object */
+	if (res != FR_OK) LEAVE_FF(fp->fs, res);
+	if (fp->flag & FA__ERROR)			/* Check abort flag */
+		LEAVE_FF(fp->fs, FR_INT_ERR);
+	if (ofs > fp->fsize					/* In read-only mode, clip offset with the file size */
+#if !_FS_READONLY
+		 && !(fp->flag & FA_WRITE)
+#endif
+		) ofs = fp->fsize;
+
+	ifptr = fp->fptr;
+	fp->fptr = nsect = 0; fp->csect = 255;
+	if (ofs > 0) {
+		bcs = (DWORD)fp->fs->csize * SS(fp->fs);	/* Cluster size (byte) */
+		if (ifptr > 0 &&
+			(ofs - 1) / bcs >= (ifptr - 1) / bcs) {	/* When seek to same or following cluster, */
+			fp->fptr = (ifptr - 1) & ~(bcs - 1);	/* start from the current cluster */
+			ofs -= fp->fptr;
+			clst = fp->curr_clust;
+		} else {									/* When seek to back cluster, */
+			clst = fp->org_clust;					/* start from the first cluster */
+#if !_FS_READONLY
+			if (clst == 0) {						/* If no cluster chain, create a new chain */
+				clst = create_chain(fp->fs, 0);
+				if (clst == 1) ABORT(fp->fs, FR_INT_ERR);
+				if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
+				fp->org_clust = clst;
+			}
+#endif
+			fp->curr_clust = clst;
+		}
+		if (clst != 0) {
+			while (ofs > bcs) {						/* Cluster following loop */
+#if !_FS_READONLY
+				if (fp->flag & FA_WRITE) {			/* Check if in write mode or not */
+					clst = create_chain(fp->fs, clst);	/* Force streached if in write mode */
+					if (clst == 0) {				/* When disk gets full, clip file size */
+						ofs = bcs; break;
+					}
+				} else
+#endif
+					clst = get_fat(fp->fs, clst);	/* Follow cluster chain if not in write mode */
+				if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
+				if (clst <= 1 || clst >= fp->fs->max_clust) ABORT(fp->fs, FR_INT_ERR);
+				fp->curr_clust = clst;
+				fp->fptr += bcs;
+				ofs -= bcs;
+			}
+			fp->fptr += ofs;
+			fp->csect = (BYTE)(ofs / SS(fp->fs));	/* Sector offset in the cluster */
+			if (ofs % SS(fp->fs)) {
+				nsect = clust2sect(fp->fs, clst);	/* Current sector */
+				if (!nsect) ABORT(fp->fs, FR_INT_ERR);
+				nsect += fp->csect;
+				fp->csect++;
+			}
+		}
+	}
+	if (fp->fptr % SS(fp->fs) && nsect != fp->dsect) {
+#if !_FS_TINY
+#if !_FS_READONLY
+		if (fp->flag & FA__DIRTY) {			/* Write-back dirty buffer if needed */
+			if (disk_write(fp->fs->drive, fp->buf, fp->dsect, 1) != RES_OK)
+				ABORT(fp->fs, FR_DISK_ERR);
+			fp->flag &= ~FA__DIRTY;
+		}
+#endif
+		if (disk_read(fp->fs->drive, fp->buf, nsect, 1) != RES_OK)
+			ABORT(fp->fs, FR_DISK_ERR);
+#endif
+		fp->dsect = nsect;
+	}
+#if !_FS_READONLY
+	if (fp->fptr > fp->fsize) {			/* Set changed flag if the file size is extended */
+		fp->fsize = fp->fptr;
+		fp->flag |= FA__WRITTEN;
+	}
+#endif
+
+	LEAVE_FF(fp->fs, res);
+}
+
+
+
+
+#if _FS_MINIMIZE <= 1
+/*-----------------------------------------------------------------------*/
+/* Create a Directroy Object                                             */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_opendir (
+	DIR *dj,			/* Pointer to directory object to create */
+	const XCHAR *path	/* Pointer to the directory path */
+)
+{
+	FRESULT res;
+	NAMEBUF(sfn, lfn);
+	BYTE *dir;
+
+
+	res = chk_mounted(&path, &dj->fs, 0);
+	if (res == FR_OK) {
+		INITBUF((*dj), sfn, lfn);
+		res = follow_path(dj, path);			/* Follow the path to the directory */
+		if (res == FR_OK) {						/* Follow completed */
+			dir = dj->dir;
+			if (dir) {							/* It is not the root dir */
+				if (dir[DIR_Attr] & AM_DIR) {	/* The object is a directory */
+					dj->sclust = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO);
+				} else {						/* The object is not a directory */
+					res = FR_NO_PATH;
+				}
+			}
+			if (res == FR_OK) {
+				dj->id = dj->fs->id;
+				res = dir_seek(dj, 0);			/* Rewind dir */
+			}
+		}
+		if (res == FR_NO_FILE) res = FR_NO_PATH;
+	}
+
+	LEAVE_FF(dj->fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read Directory Entry in Sequense                                      */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_readdir (
+	DIR *dj,			/* Pointer to the open directory object */
+	FILINFO *fno		/* Pointer to file information to return */
+)
+{
+	FRESULT res;
+	NAMEBUF(sfn, lfn);
+
+
+	res = validate(dj->fs, dj->id);			/* Check validity of the object */
+	if (res == FR_OK) {
+		INITBUF((*dj), sfn, lfn);
+		if (!fno) {
+			res = dir_seek(dj, 0);
+		} else {
+			res = dir_read(dj);
+			if (res == FR_NO_FILE) {
+				dj->sect = 0;
+				res = FR_OK;
+			}
+			if (res == FR_OK) {				/* A valid entry is found */
+				get_fileinfo(dj, fno);		/* Get the object information */
+				res = dir_next(dj, FALSE);	/* Increment index for next */
+				if (res == FR_NO_FILE) {
+					dj->sect = 0;
+					res = FR_OK;
+				}
+			}
+		}
+	}
+
+	LEAVE_FF(dj->fs, res);
+}
+
+
+
+#if _FS_MINIMIZE == 0
+/*-----------------------------------------------------------------------*/
+/* Get File Status                                                       */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_stat (
+	const XCHAR *path,	/* Pointer to the file path */
+	FILINFO *fno		/* Pointer to file information to return */
+)
+{
+	FRESULT res;
+	DIR dj;
+	NAMEBUF(sfn, lfn);
+
+
+	res = chk_mounted(&path, &dj.fs, 0);
+	if (res == FR_OK) {
+		INITBUF(dj, sfn, lfn);
+		res = follow_path(&dj, path);	/* Follow the file path */
+		if (res == FR_OK) {				/* Follwo completed */
+			if (dj.dir)	/* Found an object */
+				get_fileinfo(&dj, fno);
+			else		/* It is root dir */
+				res = FR_INVALID_NAME;
+		}
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+
+
+
+#if !_FS_READONLY
+/*-----------------------------------------------------------------------*/
+/* Get Number of Free Clusters                                           */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_getfree (
+	const XCHAR *path,	/* Pointer to the logical drive number (root dir) */
+	DWORD *nclst,		/* Pointer to the variable to return number of free clusters */
+	FATFS **fatfs		/* Pointer to pointer to corresponding file system object to return */
+)
+{
+	FRESULT res;
+	DWORD n, clst, sect, stat;
+	UINT i;
+	BYTE fat, *p;
+
+
+	/* Get drive number */
+	res = chk_mounted(&path, fatfs, 0);
+	if (res != FR_OK) LEAVE_FF(*fatfs, res);
+
+	/* If number of free cluster is valid, return it without cluster scan. */
+	if ((*fatfs)->free_clust <= (*fatfs)->max_clust - 2) {
+		*nclst = (*fatfs)->free_clust;
+		LEAVE_FF(*fatfs, FR_OK);
+	}
+
+	/* Get number of free clusters */
+	fat = (*fatfs)->fs_type;
+	n = 0;
+	if (fat == FS_FAT12) {
+		clst = 2;
+		do {
+			stat = get_fat(*fatfs, clst);
+			if (stat == 0xFFFFFFFF) LEAVE_FF(*fatfs, FR_DISK_ERR);
+			if (stat == 1) LEAVE_FF(*fatfs, FR_INT_ERR);
+			if (stat == 0) n++;
+		} while (++clst < (*fatfs)->max_clust);
+	} else {
+		clst = (*fatfs)->max_clust;
+		sect = (*fatfs)->fatbase;
+		i = 0; p = 0;
+		do {
+			if (!i) {
+				res = move_window(*fatfs, sect++);
+				if (res != FR_OK)
+					LEAVE_FF(*fatfs, res);
+				p = (*fatfs)->win;
+				i = SS(*fatfs);
+			}
+			if (fat == FS_FAT16) {
+				if (LD_WORD(p) == 0) n++;
+				p += 2; i -= 2;
+			} else {
+				if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) n++;
+				p += 4; i -= 4;
+			}
+		} while (--clst);
+	}
+	(*fatfs)->free_clust = n;
+	if (fat == FS_FAT32) (*fatfs)->fsi_flag = 1;
+	*nclst = n;
+
+	LEAVE_FF(*fatfs, FR_OK);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Truncate File                                                         */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_truncate (
+	FIL *fp		/* Pointer to the file object */
+)
+{
+	FRESULT res;
+	DWORD ncl;
+
+
+	res = validate(fp->fs, fp->id);		/* Check validity of the object */
+	if (res != FR_OK) LEAVE_FF(fp->fs, res);
+	if (fp->flag & FA__ERROR)			/* Check abort flag */
+		LEAVE_FF(fp->fs, FR_INT_ERR);
+	if (!(fp->flag & FA_WRITE))			/* Check access mode */
+		LEAVE_FF(fp->fs, FR_DENIED);
+
+	if (fp->fsize > fp->fptr) {
+		fp->fsize = fp->fptr;	/* Set file size to current R/W point */
+		fp->flag |= FA__WRITTEN;
+		if (fp->fptr == 0) {	/* When set file size to zero, remove entire cluster chain */
+			res = remove_chain(fp->fs, fp->org_clust);
+			fp->org_clust = 0;
+		} else {				/* When truncate a part of the file, remove remaining clusters */
+			ncl = get_fat(fp->fs, fp->curr_clust);
+			res = FR_OK;
+			if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR;
+			if (ncl == 1) res = FR_INT_ERR;
+			if (res == FR_OK && ncl < fp->fs->max_clust) {
+				res = put_fat(fp->fs, fp->curr_clust, 0x0FFFFFFF);
+				if (res == FR_OK) res = remove_chain(fp->fs, ncl);
+			}
+		}
+	}
+	if (res != FR_OK) fp->flag |= FA__ERROR;
+
+	LEAVE_FF(fp->fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Delete a File or Directory                                            */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_unlink (
+	const XCHAR *path		/* Pointer to the file or directory path */
+)
+{
+	FRESULT res;
+	DIR dj, sdj;
+	NAMEBUF(sfn, lfn);
+	BYTE *dir;
+	DWORD dclst;
+
+
+	res = chk_mounted(&path, &dj.fs, 1);
+	if (res != FR_OK) LEAVE_FF(dj.fs, res);
+
+	INITBUF(dj, sfn, lfn);
+	res = follow_path(&dj, path);			/* Follow the file path */
+	if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))
+		res = FR_INVALID_NAME;
+	if (res != FR_OK) LEAVE_FF(dj.fs, res); /* Follow failed */
+
+	dir = dj.dir;
+	if (!dir)								/* Is it the root directory? */
+		LEAVE_FF(dj.fs, FR_INVALID_NAME);
+	if (dir[DIR_Attr] & AM_RDO)				/* Is it a R/O object? */
+		LEAVE_FF(dj.fs, FR_DENIED);
+	dclst = ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) | LD_WORD(dir+DIR_FstClusLO);
+
+	if (dir[DIR_Attr] & AM_DIR) {			/* It is a sub-directory */
+		if (dclst < 2) LEAVE_FF(dj.fs, FR_INT_ERR);
+		mem_cpy(&sdj, &dj, sizeof(DIR));	/* Check if the sub-dir is empty or not */
+		sdj.sclust = dclst;
+		res = dir_seek(&sdj, 2);
+		if (res != FR_OK) LEAVE_FF(dj.fs, res);
+		res = dir_read(&sdj);
+		if (res == FR_OK) res = FR_DENIED;	/* Not empty sub-dir */
+		if (res != FR_NO_FILE) LEAVE_FF(dj.fs, res);
+	}
+
+	res = dir_remove(&dj);					/* Remove directory entry */
+	if (res == FR_OK) {
+		if (dclst)
+			res = remove_chain(dj.fs, dclst);	/* Remove the cluster chain */
+		if (res == FR_OK) res = sync(dj.fs);
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Create a Directory                                                    */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_mkdir (
+	const XCHAR *path		/* Pointer to the directory path */
+)
+{
+	FRESULT res;
+	DIR dj;
+	NAMEBUF(sfn, lfn);
+	BYTE *dir, n;
+	DWORD dsect, dclst, pclst, tim;
+
+
+	res = chk_mounted(&path, &dj.fs, 1);
+	if (res != FR_OK) LEAVE_FF(dj.fs, res);
+
+	INITBUF(dj, sfn, lfn);
+	res = follow_path(&dj, path);			/* Follow the file path */
+	if (res == FR_OK) res = FR_EXIST;		/* Any file or directory is already existing */
+	if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NS] & NS_DOT))
+		res = FR_INVALID_NAME;
+	if (res != FR_NO_FILE)					/* Any error occured */
+		LEAVE_FF(dj.fs, res);
+
+	dclst = create_chain(dj.fs, 0);			/* Allocate a new cluster for new directory table */
+	res = FR_OK;
+	if (dclst == 0) res = FR_DENIED;
+	if (dclst == 1) res = FR_INT_ERR;
+	if (dclst == 0xFFFFFFFF) res = FR_DISK_ERR;
+	if (res == FR_OK)
+		res = move_window(dj.fs, 0);
+	if (res != FR_OK) LEAVE_FF(dj.fs, res);
+	dsect = clust2sect(dj.fs, dclst);
+
+	dir = dj.fs->win;						/* Initialize the new directory table */
+	mem_set(dir, 0, SS(dj.fs));
+	mem_set(dir+DIR_Name, ' ', 8+3);		/* Create "." entry */
+	dir[DIR_Name] = '.';
+	dir[DIR_Attr] = AM_DIR;
+	tim = get_fattime();
+	ST_DWORD(dir+DIR_WrtTime, tim);
+	ST_WORD(dir+DIR_FstClusLO, dclst);
+	ST_WORD(dir+DIR_FstClusHI, dclst >> 16);
+	mem_cpy(dir+32, dir, 32); 			/* Create ".." entry */
+	dir[33] = '.';
+	pclst = dj.sclust;
+	if (dj.fs->fs_type == FS_FAT32 && pclst == dj.fs->dirbase)
+		pclst = 0;
+	ST_WORD(dir+32+DIR_FstClusLO, pclst);
+	ST_WORD(dir+32+DIR_FstClusHI, pclst >> 16);
+	for (n = 0; n < dj.fs->csize; n++) {	/* Write dot entries and clear left sectors */
+		dj.fs->winsect = dsect++;
+		dj.fs->wflag = 1;
+		res = move_window(dj.fs, 0);
+		if (res) LEAVE_FF(dj.fs, res);
+		mem_set(dir, 0, SS(dj.fs));
+	}
+
+	res = dir_register(&dj);
+	if (res != FR_OK) {
+		remove_chain(dj.fs, dclst);
+	} else {
+		dir = dj.dir;
+		dir[DIR_Attr] = AM_DIR;					/* Attribute */
+		ST_DWORD(dir+DIR_WrtTime, tim);			/* Crated time */
+		ST_WORD(dir+DIR_FstClusLO, dclst);		/* Table start cluster */
+		ST_WORD(dir+DIR_FstClusHI, dclst >> 16);
+		dj.fs->wflag = 1;
+		res = sync(dj.fs);
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Change File Attribute                                                 */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_chmod (
+	const XCHAR *path,	/* Pointer to the file path */
+	BYTE value,			/* Attribute bits */
+	BYTE mask			/* Attribute mask to change */
+)
+{
+	FRESULT res;
+	DIR dj;
+	NAMEBUF(sfn, lfn);
+	BYTE *dir;
+
+
+	res = chk_mounted(&path, &dj.fs, 1);
+	if (res == FR_OK) {
+		INITBUF(dj, sfn, lfn);
+		res = follow_path(&dj, path);		/* Follow the file path */
+		if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))
+			res = FR_INVALID_NAME;
+		if (res == FR_OK) {
+			dir = dj.dir;
+			if (!dir) {						/* Is it a root directory? */
+				res = FR_INVALID_NAME;
+			} else {						/* File or sub directory */
+				mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC;	/* Valid attribute mask */
+				dir[DIR_Attr] = (value & mask) | (dir[DIR_Attr] & (BYTE)~mask);	/* Apply attribute change */
+				dj.fs->wflag = 1;
+				res = sync(dj.fs);
+			}
+		}
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Change Timestamp                                                      */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_utime (
+	const XCHAR *path,	/* Pointer to the file/directory name */
+	const FILINFO *fno	/* Pointer to the timestamp to be set */
+)
+{
+	FRESULT res;
+	DIR dj;
+	NAMEBUF(sfn, lfn);
+	BYTE *dir;
+
+
+	res = chk_mounted(&path, &dj.fs, 1);
+	if (res == FR_OK) {
+		INITBUF(dj, sfn, lfn);
+		res = follow_path(&dj, path);	/* Follow the file path */
+		if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))
+			res = FR_INVALID_NAME;
+		if (res == FR_OK) {
+			dir = dj.dir;
+			if (!dir) {				/* Root directory */
+				res = FR_INVALID_NAME;
+			} else {				/* File or sub-directory */
+				ST_WORD(dir+DIR_WrtTime, fno->ftime);
+				ST_WORD(dir+DIR_WrtDate, fno->fdate);
+				dj.fs->wflag = 1;
+				res = sync(dj.fs);
+			}
+		}
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Rename File/Directory                                                 */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_rename (
+	const XCHAR *path_old,	/* Pointer to the old name */
+	const XCHAR *path_new	/* Pointer to the new name */
+)
+{
+	FRESULT res;
+	DIR dj_old, dj_new;
+	NAMEBUF(sfn, lfn);
+	BYTE buf[21], *dir;
+	DWORD dw;
+
+
+	INITBUF(dj_old, sfn, lfn);
+	res = chk_mounted(&path_old, &dj_old.fs, 1);
+	if (res == FR_OK) {
+		dj_new.fs = dj_old.fs;
+		res = follow_path(&dj_old, path_old);	/* Check old object */
+		if (_FS_RPATH && res == FR_OK && (dj_old.fn[NS] & NS_DOT))
+			res = FR_INVALID_NAME;
+	}
+	if (res != FR_OK) LEAVE_FF(dj_old.fs, res);	/* The old object is not found */
+
+	if (!dj_old.dir) LEAVE_FF(dj_old.fs, FR_NO_FILE);	/* Is root dir? */
+	mem_cpy(buf, dj_old.dir+DIR_Attr, 21);		/* Save the object information */
+
+	mem_cpy(&dj_new, &dj_old, sizeof(DIR));
+	res = follow_path(&dj_new, path_new);		/* Check new object */
+	if (res == FR_OK) res = FR_EXIST;			/* The new object name is already existing */
+	if (res == FR_NO_FILE) { 					/* Is it a valid path and no name collision? */
+		res = dir_register(&dj_new);			/* Register the new object */
+		if (res == FR_OK) {
+			dir = dj_new.dir;					/* Copy object information into new entry */
+			mem_cpy(dir+13, buf+2, 19);
+			dir[DIR_Attr] = buf[0] | AM_ARC;
+			dj_old.fs->wflag = 1;
+			if (dir[DIR_Attr] & AM_DIR) {		/* Update .. entry in the directory if needed */
+				dw = clust2sect(dj_new.fs, (DWORD)LD_WORD(dir+DIR_FstClusHI) | LD_WORD(dir+DIR_FstClusLO));
+				if (!dw) {
+					res = FR_INT_ERR;
+				} else {
+					res = move_window(dj_new.fs, dw);
+					dir = dj_new.fs->win+32;
+					if (res == FR_OK && dir[1] == '.') {
+						dw = (dj_new.fs->fs_type == FS_FAT32 && dj_new.sclust == dj_new.fs->dirbase) ? 0 : dj_new.sclust;
+						ST_WORD(dir+DIR_FstClusLO, dw);
+						ST_WORD(dir+DIR_FstClusHI, dw >> 16);
+						dj_new.fs->wflag = 1;
+					}
+				}
+			}
+			if (res == FR_OK) {
+				res = dir_remove(&dj_old);			/* Remove old entry */
+				if (res == FR_OK)
+					res = sync(dj_old.fs);
+			}
+		}
+	}
+
+	LEAVE_FF(dj_old.fs, res);
+}
+
+#endif /* !_FS_READONLY */
+#endif /* _FS_MINIMIZE == 0 */
+#endif /* _FS_MINIMIZE <= 1 */
+#endif /* _FS_MINIMIZE <= 2 */
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Forward data to the stream directly (Available on only _FS_TINY cfg)  */
+/*-----------------------------------------------------------------------*/
+#if _USE_FORWARD && _FS_TINY
+
+FRESULT f_forward (
+	FIL *fp, 						/* Pointer to the file object */
+	UINT (*func)(const BYTE*,UINT),	/* Pointer to the streaming function */
+	UINT btr,						/* Number of bytes to forward */
+	UINT *bf						/* Pointer to number of bytes forwarded */
+)
+{
+	FRESULT res;
+	DWORD remain, clst, sect;
+	UINT rcnt;
+
+
+	*bf = 0;
+
+	res = validate(fp->fs, fp->id);					/* Check validity of the object */
+	if (res != FR_OK) LEAVE_FF(fp->fs, res);
+	if (fp->flag & FA__ERROR)						/* Check error flag */
+		LEAVE_FF(fp->fs, FR_INT_ERR);
+	if (!(fp->flag & FA_READ))						/* Check access mode */
+		LEAVE_FF(fp->fs, FR_DENIED);
+
+	remain = fp->fsize - fp->fptr;
+	if (btr > remain) btr = (UINT)remain;			/* Truncate btr by remaining bytes */
+
+	for ( ;  btr && (*func)(NULL, 0);				/* Repeat until all data transferred or stream becomes busy */
+		fp->fptr += rcnt, *bf += rcnt, btr -= rcnt) {
+		if ((fp->fptr % SS(fp->fs)) == 0) {			/* On the sector boundary? */
+			if (fp->csect >= fp->fs->csize) {		/* On the cluster boundary? */
+				clst = (fp->fptr == 0) ?			/* On the top of the file? */
+					fp->org_clust : get_fat(fp->fs, fp->curr_clust);
+				if (clst <= 1) ABORT(fp->fs, FR_INT_ERR);
+				if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
+				fp->curr_clust = clst;				/* Update current cluster */
+				fp->csect = 0;						/* Reset sector address in the cluster */
+			}
+			fp->csect++;							/* Next sector address in the cluster */
+		}
+		sect = clust2sect(fp->fs, fp->curr_clust);	/* Get current data sector */
+		if (!sect) ABORT(fp->fs, FR_INT_ERR);
+		sect += fp->csect - 1;
+		if (move_window(fp->fs, sect))				/* Move sector window */
+			ABORT(fp->fs, FR_DISK_ERR);
+		fp->dsect = sect;
+		rcnt = SS(fp->fs) - (WORD)(fp->fptr % SS(fp->fs));	/* Forward data from sector window */
+		if (rcnt > btr) rcnt = btr;
+		rcnt = (*func)(&fp->fs->win[(WORD)fp->fptr % SS(fp->fs)], rcnt);
+		if (!rcnt) ABORT(fp->fs, FR_INT_ERR);
+	}
+
+	LEAVE_FF(fp->fs, FR_OK);
+}
+#endif /* _USE_FORWARD */
+
+
+
+#if _USE_MKFS && !_FS_READONLY
+/*-----------------------------------------------------------------------*/
+/* Create File System on the Drive                                       */
+/*-----------------------------------------------------------------------*/
+#define N_ROOTDIR	512			/* Multiple of 32 and <= 2048 */
+#define N_FATS		1			/* 1 or 2 */
+#define MAX_SECTOR	131072000UL	/* Maximum partition size */
+#define MIN_SECTOR	2000UL		/* Minimum partition size */
+
+
+FRESULT f_mkfs (
+	BYTE drv,			/* Logical drive number */
+	BYTE partition,		/* Partitioning rule 0:FDISK, 1:SFD */
+	WORD allocsize		/* Allocation unit size [bytes] */
+)
+{
+	static const DWORD sstbl[] = { 2048000, 1024000, 512000, 256000, 128000, 64000, 32000, 16000, 8000, 4000,   0 };
+	static const WORD cstbl[] =  {   32768,   16384,   8192,   4096,   2048, 16384,  8192,  4096, 2048, 1024, 512 };
+	BYTE fmt, m, *tbl;
+	DWORD b_part, b_fat, b_dir, b_data;		/* Area offset (LBA) */
+	DWORD n_part, n_rsv, n_fat, n_dir;		/* Area size */
+	DWORD n_clst, d, n;
+	WORD as;
+	FATFS *fs;
+	DSTATUS stat;
+
+
+	/* Check validity of the parameters */
+	if (drv >= _DRIVES) return FR_INVALID_DRIVE;
+	if (partition >= 2) return FR_MKFS_ABORTED;
+
+	/* Check mounted drive and clear work area */
+	fs = FatFs[drv];
+	if (!fs) return FR_NOT_ENABLED;
+	fs->fs_type = 0;
+	drv = LD2PD(drv);
+
+	/* Get disk statics */
+	stat = disk_initialize(drv);
+	if (stat & STA_NOINIT) return FR_NOT_READY;
+	if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
+#if _MAX_SS != 512						/* Get disk sector size */
+	if (disk_ioctl(drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK
+		|| SS(fs) > _MAX_SS)
+		return FR_MKFS_ABORTED;
+#endif
+	if (disk_ioctl(drv, GET_SECTOR_COUNT, &n_part) != RES_OK || n_part < MIN_SECTOR)
+		return FR_MKFS_ABORTED;
+	if (n_part > MAX_SECTOR) n_part = MAX_SECTOR;
+	b_part = (!partition) ? 63 : 0;		/* Boot sector */
+	n_part -= b_part;
+	for (d = 512; d <= 32768U && d != allocsize; d <<= 1) ;	/* Check validity of the allocation unit size */
+	if (d != allocsize) allocsize = 0;
+	if (!allocsize) {					/* Auto selection of cluster size */
+		d = n_part;
+		for (as = SS(fs); as > 512U; as >>= 1) d >>= 1;
+		for (n = 0; d < sstbl[n]; n++) ;
+		allocsize = cstbl[n];
+	}
+	if (allocsize < SS(fs)) allocsize = SS(fs);
+
+	allocsize /= SS(fs);		/* Number of sectors per cluster */
+
+	/* Pre-compute number of clusters and FAT type */
+	n_clst = n_part / allocsize;
+	fmt = FS_FAT12;
+	if (n_clst >= 0xFF5) fmt = FS_FAT16;
+	if (n_clst >= 0xFFF5) fmt = FS_FAT32;
+
+	/* Determine offset and size of FAT structure */
+	switch (fmt) {
+	case FS_FAT12:
+		n_fat = ((n_clst * 3 + 1) / 2 + 3 + SS(fs) - 1) / SS(fs);
+		n_rsv = 1 + partition;
+		n_dir = N_ROOTDIR * 32 / SS(fs);
+		break;
+	case FS_FAT16:
+		n_fat = ((n_clst * 2) + 4 + SS(fs) - 1) / SS(fs);
+		n_rsv = 1 + partition;
+		n_dir = N_ROOTDIR * 32 / SS(fs);
+		break;
+	default:
+		n_fat = ((n_clst * 4) + 8 + SS(fs) - 1) / SS(fs);
+		n_rsv = 33 - partition;
+		n_dir = 0;
+	}
+	b_fat = b_part + n_rsv;			/* FATs start sector */
+	b_dir = b_fat + n_fat * N_FATS;	/* Directory start sector */
+	b_data = b_dir + n_dir;			/* Data start sector */
+
+	/* Align data start sector to erase block boundary (for flash memory media) */
+	if (disk_ioctl(drv, GET_BLOCK_SIZE, &n) != RES_OK) return FR_MKFS_ABORTED;
+	n = (b_data + n - 1) & ~(n - 1);
+	n_fat += (n - b_data) / N_FATS;
+	/* b_dir and b_data are no longer used below */
+
+	/* Determine number of cluster and final check of validity of the FAT type */
+	n_clst = (n_part - n_rsv - n_fat * N_FATS - n_dir) / allocsize;
+	if (   (fmt == FS_FAT16 && n_clst < 0xFF5)
+		|| (fmt == FS_FAT32 && n_clst < 0xFFF5))
+		return FR_MKFS_ABORTED;
+
+	/* Create partition table if needed */
+	if (!partition) {
+		DWORD n_disk = b_part + n_part;
+
+		mem_set(fs->win, 0, SS(fs));
+		tbl = fs->win+MBR_Table;
+		ST_DWORD(tbl, 0x00010180);		/* Partition start in CHS */
+		if (n_disk < 63UL * 255 * 1024) {	/* Partition end in CHS */
+			n_disk = n_disk / 63 / 255;
+			tbl[7] = (BYTE)n_disk;
+			tbl[6] = (BYTE)((n_disk >> 2) | 63);
+		} else {
+			ST_WORD(&tbl[6], 0xFFFF);
+		}
+		tbl[5] = 254;
+		if (fmt != FS_FAT32)			/* System ID */
+			tbl[4] = (n_part < 0x10000) ? 0x04 : 0x06;
+		else
+			tbl[4] = 0x0c;
+		ST_DWORD(tbl+8, 63);			/* Partition start in LBA */
+		ST_DWORD(tbl+12, n_part);		/* Partition size in LBA */
+		ST_WORD(tbl+64, 0xAA55);		/* Signature */
+		if (disk_write(drv, fs->win, 0, 1) != RES_OK)
+			return FR_DISK_ERR;
+		partition = 0xF8;
+	} else {
+		partition = 0xF0;
+	}
+
+	/* Create boot record */
+	tbl = fs->win;								/* Clear buffer */
+	mem_set(tbl, 0, SS(fs));
+	ST_DWORD(tbl+BS_jmpBoot, 0x90FEEB);			/* Boot code (jmp $, nop) */
+	ST_WORD(tbl+BPB_BytsPerSec, SS(fs));		/* Sector size */
+	tbl[BPB_SecPerClus] = (BYTE)allocsize;		/* Sectors per cluster */
+	ST_WORD(tbl+BPB_RsvdSecCnt, n_rsv);			/* Reserved sectors */
+	tbl[BPB_NumFATs] = N_FATS;					/* Number of FATs */
+	ST_WORD(tbl+BPB_RootEntCnt, SS(fs) / 32 * n_dir); /* Number of rootdir entries */
+	if (n_part < 0x10000) {						/* Number of total sectors */
+		ST_WORD(tbl+BPB_TotSec16, n_part);
+	} else {
+		ST_DWORD(tbl+BPB_TotSec32, n_part);
+	}
+	tbl[BPB_Media] = partition;					/* Media descripter */
+	ST_WORD(tbl+BPB_SecPerTrk, 63);				/* Number of sectors per track */
+	ST_WORD(tbl+BPB_NumHeads, 255);				/* Number of heads */
+	ST_DWORD(tbl+BPB_HiddSec, b_part);			/* Hidden sectors */
+	n = get_fattime();							/* Use current time as a VSN */
+	if (fmt != FS_FAT32) {
+		ST_DWORD(tbl+BS_VolID, n);				/* Volume serial number */
+		ST_WORD(tbl+BPB_FATSz16, n_fat);		/* Number of secters per FAT */
+		tbl[BS_DrvNum] = 0x80;					/* Drive number */
+		tbl[BS_BootSig] = 0x29;					/* Extended boot signature */
+		mem_cpy(tbl+BS_VolLab, "NO NAME    FAT     ", 19);	/* Volume lavel, FAT signature */
+	} else {
+		ST_DWORD(tbl+BS_VolID32, n);			/* Volume serial number */
+		ST_DWORD(tbl+BPB_FATSz32, n_fat);		/* Number of secters per FAT */
+		ST_DWORD(tbl+BPB_RootClus, 2);			/* Root directory cluster (2) */
+		ST_WORD(tbl+BPB_FSInfo, 1);				/* FSInfo record offset (bs+1) */
+		ST_WORD(tbl+BPB_BkBootSec, 6);			/* Backup boot record offset (bs+6) */
+		tbl[BS_DrvNum32] = 0x80;				/* Drive number */
+		tbl[BS_BootSig32] = 0x29;				/* Extended boot signature */
+		mem_cpy(tbl+BS_VolLab32, "NO NAME    FAT32   ", 19);	/* Volume lavel, FAT signature */
+	}
+	ST_WORD(tbl+BS_55AA, 0xAA55);				/* Signature */
+	if (SS(fs) > 512U) {
+		ST_WORD(tbl+SS(fs)-2, 0xAA55);
+	}
+	if (disk_write(drv, tbl, b_part+0, 1) != RES_OK)
+		return FR_DISK_ERR;
+	if (fmt == FS_FAT32)
+		disk_write(drv, tbl, b_part+6, 1);
+
+	/* Initialize FAT area */
+	for (m = 0; m < N_FATS; m++) {
+		mem_set(tbl, 0, SS(fs));		/* 1st sector of the FAT  */
+		if (fmt != FS_FAT32) {
+			n = (fmt == FS_FAT12) ? 0x00FFFF00 : 0xFFFFFF00;
+			n |= partition;
+			ST_DWORD(tbl, n);				/* Reserve cluster #0-1 (FAT12/16) */
+		} else {
+			ST_DWORD(tbl+0, 0xFFFFFFF8);	/* Reserve cluster #0-1 (FAT32) */
+			ST_DWORD(tbl+4, 0xFFFFFFFF);
+			ST_DWORD(tbl+8, 0x0FFFFFFF);	/* Reserve cluster #2 for root dir */
+		}
+		if (disk_write(drv, tbl, b_fat++, 1) != RES_OK)
+			return FR_DISK_ERR;
+		mem_set(tbl, 0, SS(fs));		/* Following FAT entries are filled by zero */
+		for (n = 1; n < n_fat; n++) {
+			if (disk_write(drv, tbl, b_fat++, 1) != RES_OK)
+				return FR_DISK_ERR;
+		}
+	}
+
+	/* Initialize Root directory */
+	m = (BYTE)((fmt == FS_FAT32) ? allocsize : n_dir);
+	do {
+		if (disk_write(drv, tbl, b_fat++, 1) != RES_OK)
+			return FR_DISK_ERR;
+	} while (--m);
+
+	/* Create FSInfo record if needed */
+	if (fmt == FS_FAT32) {
+		ST_WORD(tbl+BS_55AA, 0xAA55);
+		ST_DWORD(tbl+FSI_LeadSig, 0x41615252);
+		ST_DWORD(tbl+FSI_StrucSig, 0x61417272);
+		ST_DWORD(tbl+FSI_Free_Count, n_clst - 1);
+		ST_DWORD(tbl+FSI_Nxt_Free, 0xFFFFFFFF);
+		disk_write(drv, tbl, b_part+1, 1);
+		disk_write(drv, tbl, b_part+7, 1);
+	}
+
+	return (disk_ioctl(drv, CTRL_SYNC, (void*)NULL) == RES_OK) ? FR_OK : FR_DISK_ERR;
+}
+
+#endif /* _USE_MKFS && !_FS_READONLY */
+
+
+
+
+#if _USE_STRFUNC
+/*-----------------------------------------------------------------------*/
+/* Get a string from the file                                            */
+/*-----------------------------------------------------------------------*/
+char* f_gets (
+	char* buff,	/* Pointer to the string buffer to read */
+	int len,	/* Size of string buffer */
+	FIL* fil	/* Pointer to the file object */
+)
+{
+	int i = 0;
+	char *p = buff;
+	UINT rc;
+
+
+	while (i < len - 1) {			/* Read bytes until buffer gets filled */
+		f_read(fil, p, 1, &rc);
+		if (rc != 1) break;			/* Break when no data to read */
+#if _USE_STRFUNC >= 2
+		if (*p == '\r') continue;	/* Strip '\r' */
+#endif
+		i++;
+		if (*p++ == '\n') break;	/* Break when reached end of line */
+	}
+	*p = 0;
+	return i ? buff : NULL;			/* When no data read (eof or error), return with error. */
+}
+
+
+
+#if !_FS_READONLY
+#include <stdarg.h>
+/*-----------------------------------------------------------------------*/
+/* Put a character to the file                                           */
+/*-----------------------------------------------------------------------*/
+int f_putc (
+	int chr,	/* A character to be output */
+	FIL* fil	/* Ponter to the file object */
+)
+{
+	UINT bw;
+	char c;
+
+
+#if _USE_STRFUNC >= 2
+	if (chr == '\n') f_putc ('\r', fil);	/* LF -> CRLF conversion */
+#endif
+	if (!fil) {	/* Special value may be used to switch the destination to any other device */
+	/*	put_console(chr);	*/
+		return chr;
+	}
+	c = (char)chr;
+	f_write(fil, &c, 1, &bw);	/* Write a byte to the file */
+	return bw ? chr : EOF;		/* Return the result */
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Put a string to the file                                              */
+/*-----------------------------------------------------------------------*/
+int f_puts (
+	const char* str,	/* Pointer to the string to be output */
+	FIL* fil			/* Pointer to the file object */
+)
+{
+	int n;
+
+
+	for (n = 0; *str; str++, n++) {
+		if (f_putc(*str, fil) == EOF) return EOF;
+	}
+	return n;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Put a formatted string to the file                                    */
+/*-----------------------------------------------------------------------*/
+int f_printf (
+	FIL* fil,			/* Pointer to the file object */
+	const char* str,	/* Pointer to the format string */
+	...					/* Optional arguments... */
+)
+{
+	va_list arp;
+	UCHAR c, f, r;
+	ULONG val;
+	char s[16];
+	int i, w, res, cc;
+
+
+	va_start(arp, str);
+
+	for (cc = res = 0; cc != EOF; res += cc) {
+		c = *str++;
+		if (c == 0) break;			/* End of string */
+		if (c != '%') {				/* Non escape cahracter */
+			cc = f_putc(c, fil);
+			if (cc != EOF) cc = 1;
+			continue;
+		}
+		w = f = 0;
+		c = *str++;
+		if (c == '0') {				/* Flag: '0' padding */
+			f = 1; c = *str++;
+		}
+		while (c >= '0' && c <= '9') {	/* Precision */
+			w = w * 10 + (c - '0');
+			c = *str++;
+		}
+		if (c == 'l') {				/* Prefix: Size is long int */
+			f |= 2; c = *str++;
+		}
+		if (c == 's') {				/* Type is string */
+			cc = f_puts(va_arg(arp, char*), fil);
+			continue;
+		}
+		if (c == 'c') {				/* Type is character */
+			cc = f_putc(va_arg(arp, int), fil);
+			if (cc != EOF) cc = 1;
+			continue;
+		}
+		r = 0;
+		if (c == 'd') r = 10;		/* Type is signed decimal */
+		if (c == 'u') r = 10;		/* Type is unsigned decimal */
+		if (c == 'X') r = 16;		/* Type is unsigned hexdecimal */
+		if (r == 0) break;			/* Unknown type */
+		if (f & 2) {				/* Get the value */
+			val = (ULONG)va_arg(arp, long);
+		} else {
+			val = (c == 'd') ? (ULONG)(long)va_arg(arp, int) : (ULONG)va_arg(arp, unsigned int);
+		}
+		/* Put numeral string */
+		if (c == 'd') {
+			if (val & 0x80000000) {
+				val = 0 - val;
+				f |= 4;
+			}
+		}
+		i = sizeof(s) - 1; s[i] = 0;
+		do {
+			c = (UCHAR)(val % r + '0');
+			if (c > '9') c += 7;
+			s[--i] = c;
+			val /= r;
+		} while (i && val);
+		if (i && (f & 4)) s[--i] = '-';
+		w = sizeof(s) - 1 - w;
+		while (i && i > w) s[--i] = (f & 1) ? '0' : ' ';
+		cc = f_puts(&s[i], fil);
+	}
+
+	va_end(arp);
+	return (cc == EOF) ? cc : res;
+}
+
+#endif /* !_FS_READONLY */
+#endif /* _USE_STRFUNC */
+
+#endif /* CFG_SDCARD */
diff --git a/reform2-lpc-fw/src/drivers/storage/fatfs/ff.h b/reform2-lpc-fw/src/drivers/storage/fatfs/ff.h
new file mode 100644
index 0000000000000000000000000000000000000000..6e037bbd8a572b0ee1e80fc53d2d4165efdb0f64
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/storage/fatfs/ff.h
@@ -0,0 +1,604 @@
+/*---------------------------------------------------------------------------/
+/  FatFs - FAT file system module include file  R0.07e       (C)ChaN, 2009
+/----------------------------------------------------------------------------/
+/ FatFs module is a generic FAT file system module for small embedded systems.
+/ This is a free software that opened for education, research and commercial
+/ developments under license policy of following trems.
+/
+/  Copyright (C) 2009, ChaN, all right reserved.
+/
+/ * The FatFs module is a free software and there is NO WARRANTY.
+/ * No restriction on use. You can use, modify and redistribute it for
+/   personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
+/ * Redistributions of source code must retain the above copyright notice.
+/----------------------------------------------------------------------------*/
+
+#ifndef _FATFS
+#define _FATFS	0x007E
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "integer.h"	/* Basic integer types */
+#include "ffconf.h"		/* FatFs configuration options */
+
+#if _FATFS != _FFCONFIG
+#error Wrong configuration file (ffconf.h).
+#endif
+
+
+/* DBCS code ranges and SBCS extend char conversion table */
+
+#if _CODE_PAGE == 932	/* Japanese Shift-JIS */
+#define _DF1S	0x81	/* DBC 1st byte range 1 start */
+#define _DF1E	0x9F	/* DBC 1st byte range 1 end */
+#define _DF2S	0xE0	/* DBC 1st byte range 2 start */
+#define _DF2E	0xFC	/* DBC 1st byte range 2 end */
+#define _DS1S	0x40	/* DBC 2nd byte range 1 start */
+#define _DS1E	0x7E	/* DBC 2nd byte range 1 end */
+#define _DS2S	0x80	/* DBC 2nd byte range 2 start */
+#define _DS2E	0xFC	/* DBC 2nd byte range 2 end */
+
+#elif _CODE_PAGE == 936	/* Simplified Chinese GBK */
+#define _DF1S	0x81
+#define _DF1E	0xFE
+#define _DS1S	0x40
+#define _DS1E	0x7E
+#define _DS2S	0x80
+#define _DS2E	0xFE
+
+#elif _CODE_PAGE == 949	/* Korean */
+#define _DF1S	0x81
+#define _DF1E	0xFE
+#define _DS1S	0x41
+#define _DS1E	0x5A
+#define _DS2S	0x61
+#define _DS2E	0x7A
+#define _DS3S	0x81
+#define _DS3E	0xFE
+
+#elif _CODE_PAGE == 950	/* Traditional Chinese Big5 */
+#define _DF1S	0x81
+#define _DF1E	0xFE
+#define _DS1S	0x40
+#define _DS1E	0x7E
+#define _DS2S	0xA1
+#define _DS2E	0xFE
+
+#elif _CODE_PAGE == 437	/* U.S. (OEM) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+				0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 720	/* Arabic (OEM) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+				0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 737	/* Greek (OEM) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \
+				0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 775	/* Baltic (OEM) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
+				0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 850	/* Multilingual Latin 1 (OEM) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
+				0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 852	/* Latin 2 (OEM) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \
+				0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}
+
+#elif _CODE_PAGE == 855	/* Cyrillic (OEM) */
+#define _DF1S	0
+#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \
+				0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \
+				0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 857	/* Turkish (OEM) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \
+				0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 858	/* Multilingual Latin 1 + Euro (OEM) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
+				0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 862	/* Hebrew (OEM) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+				0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 866	/* Russian (OEM) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+				0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 874	/* Thai (OEM, Windows) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+				0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
+				0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
+
+#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
+				0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF}
+
+#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \
+				0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
+
+#elif _CODE_PAGE == 1253 /* Greek (Windows) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+				0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \
+				0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF}
+
+#elif _CODE_PAGE == 1254 /* Turkish (Windows) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \
+				0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
+
+#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+				0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 1256 /* Arabic (Windows) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \
+				0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF}
+
+#elif _CODE_PAGE == 1257 /* Baltic (Windows) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+				0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
+
+#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */
+#define _DF1S	0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \
+				0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F}
+
+#elif _CODE_PAGE == 1	/* ASCII (for only non-LFN cfg) */
+#define _DF1S	0
+
+#else
+#error Unknown code page
+
+#endif
+
+
+
+/* Character code support macros */
+
+#define IsUpper(c)	(((c)>='A')&&((c)<='Z'))
+#define IsLower(c)	(((c)>='a')&&((c)<='z'))
+
+#if _DF1S		/* DBCS configuration */
+
+#ifdef _DF2S	/* Two 1st byte areas */
+#define IsDBCS1(c)	(((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))
+#else			/* One 1st byte area */
+#define IsDBCS1(c)	((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E)
+#endif
+
+#ifdef _DS3S	/* Three 2nd byte areas */
+#define IsDBCS2(c)	(((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E))
+#else			/* Two 2nd byte areas */
+#define IsDBCS2(c)	(((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))
+#endif
+
+#else			/* SBCS configuration */
+
+#define IsDBCS1(c)	0
+#define IsDBCS2(c)	0
+
+#endif /* _DF1S */
+
+
+
+/* Definitions corresponds to multi partition */
+
+#if _MULTI_PARTITION		/* Multiple partition configuration */
+
+typedef struct _PARTITION {
+	BYTE pd;	/* Physical drive# */
+	BYTE pt;	/* Partition # (0-3) */
+} PARTITION;
+
+extern
+const PARTITION Drives[];			/* Logical drive# to physical location conversion table */
+#define LD2PD(drv) (Drives[drv].pd)	/* Get physical drive# */
+#define LD2PT(drv) (Drives[drv].pt)	/* Get partition# */
+
+#else						/* Single partition configuration */
+
+#define LD2PD(drv) (drv)	/* Physical drive# is equal to the logical drive# */
+#define LD2PT(drv) 0		/* Always mounts the 1st partition */
+
+#endif
+
+
+
+/* Definitions corresponds to multiple sector size */
+
+#if _MAX_SS == 512		/* Single sector size */
+#define	SS(fs)	512U
+
+#elif _MAX_SS == 1024 || _MAX_SS == 2048 || _MAX_SS == 4096	/* Multiple sector size */
+#define	SS(fs)	((fs)->s_size)
+
+#else
+#error Sector size must be 512, 1024, 2048 or 4096.
+
+#endif
+
+
+
+/* Type of file name on FatFs API */
+
+#if _LFN_UNICODE && _USE_LFN
+typedef WCHAR XCHAR;	/* Unicode */
+#else
+typedef char XCHAR;		/* SBCS, DBCS */
+#endif
+
+
+
+/* File system object structure */
+
+typedef struct _FATFS_ {
+	BYTE	fs_type;	/* FAT sub type */
+	BYTE	drive;		/* Physical drive number */
+	BYTE	csize;		/* Number of sectors per cluster */
+	BYTE	n_fats;		/* Number of FAT copies */
+	BYTE	wflag;		/* win[] dirty flag (1:must be written back) */
+	BYTE	fsi_flag;	/* fsinfo dirty flag (1:must be written back) */
+	WORD	id;			/* File system mount ID */
+	WORD	n_rootdir;	/* Number of root directory entries (0 on FAT32) */
+#if _FS_REENTRANT
+	_SYNC_t	sobj;		/* Identifier of sync object */
+#endif
+#if _MAX_SS != 512
+	WORD	s_size;		/* Sector size */
+#endif
+#if !_FS_READONLY
+	DWORD	last_clust;	/* Last allocated cluster */
+	DWORD	free_clust;	/* Number of free clusters */
+	DWORD	fsi_sector;	/* fsinfo sector */
+#endif
+#if _FS_RPATH
+	DWORD	cdir;		/* Current directory (0:root)*/
+#endif
+	DWORD	sects_fat;	/* Sectors per fat */
+	DWORD	max_clust;	/* Maximum cluster# + 1. Number of clusters is max_clust - 2 */
+	DWORD	fatbase;	/* FAT start sector */
+	DWORD	dirbase;	/* Root directory start sector (Cluster# on FAT32) */
+	DWORD	database;	/* Data start sector */
+	DWORD	winsect;	/* Current sector appearing in the win[] */
+	BYTE	win[_MAX_SS];/* Disk access window for Directory/FAT */
+} FATFS;
+
+
+
+/* Directory object structure */
+
+typedef struct _DIR_ {
+	FATFS*	fs;			/* Pointer to the owner file system object */
+	WORD	id;			/* Owner file system mount ID */
+	WORD	index;		/* Current read/write index number */
+	DWORD	sclust;		/* Table start cluster (0:Static table) */
+	DWORD	clust;		/* Current cluster */
+	DWORD	sect;		/* Current sector */
+	BYTE*	dir;		/* Pointer to the current SFN entry in the win[] */
+	BYTE*	fn;			/* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
+#if _USE_LFN
+	WCHAR*	lfn;		/* Pointer to the LFN working buffer */
+	WORD	lfn_idx;	/* Last matched LFN index number (0xFFFF:No LFN) */
+#endif
+} DIR;
+
+
+
+/* File object structure */
+
+typedef struct _FIL_ {
+	FATFS*	fs;			/* Pointer to the owner file system object */
+	WORD	id;			/* Owner file system mount ID */
+	BYTE	flag;		/* File status flags */
+	BYTE	csect;		/* Sector address in the cluster */
+	DWORD	fptr;		/* File R/W pointer */
+	DWORD	fsize;		/* File size */
+	DWORD	org_clust;	/* File start cluster */
+	DWORD	curr_clust;	/* Current cluster */
+	DWORD	dsect;		/* Current data sector */
+#if !_FS_READONLY
+	DWORD	dir_sect;	/* Sector containing the directory entry */
+	BYTE*	dir_ptr;	/* Ponter to the directory entry in the window */
+#endif
+#if !_FS_TINY
+	BYTE	buf[_MAX_SS];/* File R/W buffer */
+#endif
+} FIL;
+
+
+
+/* File status structure */
+
+typedef struct _FILINFO_ {
+	DWORD	fsize;		/* File size */
+	WORD	fdate;		/* Last modified date */
+	WORD	ftime;		/* Last modified time */
+	BYTE	fattrib;	/* Attribute */
+	char	fname[13];	/* Short file name (8.3 format) */
+#if _USE_LFN
+	XCHAR*	lfname;		/* Pointer to the LFN buffer */
+	int 	lfsize;		/* Size of LFN buffer [chrs] */
+#endif
+} FILINFO;
+
+
+
+/* File function return code (FRESULT) */
+
+typedef enum {
+	FR_OK = 0,			/* 0 */
+	FR_DISK_ERR,		/* 1 */
+	FR_INT_ERR,			/* 2 */
+	FR_NOT_READY,		/* 3 */
+	FR_NO_FILE,			/* 4 */
+	FR_NO_PATH,			/* 5 */
+	FR_INVALID_NAME,	/* 6 */
+	FR_DENIED,			/* 7 */
+	FR_EXIST,			/* 8 */
+	FR_INVALID_OBJECT,	/* 9 */
+	FR_WRITE_PROTECTED,	/* 10 */
+	FR_INVALID_DRIVE,	/* 11 */
+	FR_NOT_ENABLED,		/* 12 */
+	FR_NO_FILESYSTEM,	/* 13 */
+	FR_MKFS_ABORTED,	/* 14 */
+	FR_TIMEOUT			/* 15 */
+} FRESULT;
+
+
+
+/*--------------------------------------------------------------*/
+/* FatFs module application interface                           */
+
+FRESULT f_mount (BYTE, FATFS*);						/* Mount/Unmount a logical drive */
+FRESULT f_open (FIL*, const XCHAR*, BYTE);			/* Open or create a file */
+FRESULT f_read (FIL*, void*, UINT, UINT*);			/* Read data from a file */
+FRESULT f_write (FIL*, const void*, UINT, UINT*);	/* Write data to a file */
+FRESULT f_lseek (FIL*, DWORD);						/* Move file pointer of a file object */
+FRESULT f_close (FIL*);								/* Close an open file object */
+FRESULT f_opendir (DIR*, const XCHAR*);				/* Open an existing directory */
+FRESULT f_readdir (DIR*, FILINFO*);					/* Read a directory item */
+FRESULT f_stat (const XCHAR*, FILINFO*);			/* Get file status */
+FRESULT f_getfree (const XCHAR*, DWORD*, FATFS**);	/* Get number of free clusters on the drive */
+FRESULT f_truncate (FIL*);							/* Truncate file */
+FRESULT f_sync (FIL*);								/* Flush cached data of a writing file */
+FRESULT f_unlink (const XCHAR*);					/* Delete an existing file or directory */
+FRESULT	f_mkdir (const XCHAR*);						/* Create a new directory */
+FRESULT f_chmod (const XCHAR*, BYTE, BYTE);			/* Change attriburte of the file/dir */
+FRESULT f_utime (const XCHAR*, const FILINFO*);		/* Change timestamp of the file/dir */
+FRESULT f_rename (const XCHAR*, const XCHAR*);		/* Rename/Move a file or directory */
+FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*);	/* Forward data to the stream */
+FRESULT f_mkfs (BYTE, BYTE, WORD);					/* Create a file system on the drive */
+FRESULT f_chdir (const XCHAR*);						/* Change current directory */
+FRESULT f_chdrive (BYTE);							/* Change current drive */
+
+#if _USE_STRFUNC
+int f_putc (int, FIL*);								/* Put a character to the file */
+int f_puts (const char*, FIL*);						/* Put a string to the file */
+int f_printf (FIL*, const char*, ...);				/* Put a formatted string to the file */
+char* f_gets (char*, int, FIL*);					/* Get a string from the file */
+#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)
+#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)
+#ifndef EOF
+#define EOF -1
+#endif
+#endif
+
+
+
+/*--------------------------------------------------------------*/
+/* User defined functions                                       */
+
+/* Real time clock */
+#if !_FS_READONLY
+DWORD get_fattime (void);	/* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */
+							/* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */
+#endif
+
+/* Unicode - OEM code conversion */
+#if _USE_LFN
+WCHAR ff_convert (WCHAR, UINT);
+WCHAR ff_wtoupper (WCHAR);
+#endif
+
+/* Sync functions */
+#if _FS_REENTRANT
+BOOL ff_cre_syncobj(BYTE, _SYNC_t*);
+BOOL ff_del_syncobj(_SYNC_t);
+BOOL ff_req_grant(_SYNC_t);
+void ff_rel_grant(_SYNC_t);
+#endif
+
+
+
+/*--------------------------------------------------------------*/
+/* Flags and offset address                                     */
+
+
+/* File access control and file status flags (FIL.flag) */
+
+#define	FA_READ			0x01
+#define	FA_OPEN_EXISTING	0x00
+#if _FS_READONLY == 0
+#define	FA_WRITE		0x02
+#define	FA_CREATE_NEW		0x04
+#define	FA_CREATE_ALWAYS	0x08
+#define	FA_OPEN_ALWAYS		0x10
+#define FA__WRITTEN		0x20
+#define FA__DIRTY		0x40
+#endif
+#define FA__ERROR		0x80
+
+
+/* FAT sub type (FATFS.fs_type) */
+
+#define FS_FAT12	1
+#define FS_FAT16	2
+#define FS_FAT32	3
+
+
+/* File attribute bits for directory entry */
+
+#define	AM_RDO	0x01	/* Read only */
+#define	AM_HID	0x02	/* Hidden */
+#define	AM_SYS	0x04	/* System */
+#define	AM_VOL	0x08	/* Volume label */
+#define AM_LFN	0x0F	/* LFN entry */
+#define AM_DIR	0x10	/* Directory */
+#define AM_ARC	0x20	/* Archive */
+#define AM_MASK	0x3F	/* Mask of defined bits */
+
+
+/* FatFs refers the members in the FAT structures with byte offset instead
+/ of structure member because there are incompatibility of the packing option
+/ between various compilers. */
+
+#define BS_jmpBoot			0
+#define BS_OEMName			3
+#define BPB_BytsPerSec		11
+#define BPB_SecPerClus		13
+#define BPB_RsvdSecCnt		14
+#define BPB_NumFATs			16
+#define BPB_RootEntCnt		17
+#define BPB_TotSec16		19
+#define BPB_Media			21
+#define BPB_FATSz16			22
+#define BPB_SecPerTrk		24
+#define BPB_NumHeads		26
+#define BPB_HiddSec			28
+#define BPB_TotSec32		32
+#define BS_55AA				510
+
+#define BS_DrvNum			36
+#define BS_BootSig			38
+#define BS_VolID			39
+#define BS_VolLab			43
+#define BS_FilSysType		54
+
+#define BPB_FATSz32			36
+#define BPB_ExtFlags		40
+#define BPB_FSVer			42
+#define BPB_RootClus		44
+#define BPB_FSInfo			48
+#define BPB_BkBootSec		50
+#define BS_DrvNum32			64
+#define BS_BootSig32		66
+#define BS_VolID32			67
+#define BS_VolLab32			71
+#define BS_FilSysType32		82
+
+#define	FSI_LeadSig			0
+#define	FSI_StrucSig		484
+#define	FSI_Free_Count		488
+#define	FSI_Nxt_Free		492
+
+#define MBR_Table			446
+
+#define	DIR_Name			0
+#define	DIR_Attr			11
+#define	DIR_NTres			12
+#define	DIR_CrtTime			14
+#define	DIR_CrtDate			16
+#define	DIR_FstClusHI		20
+#define	DIR_WrtTime			22
+#define	DIR_WrtDate			24
+#define	DIR_FstClusLO		26
+#define	DIR_FileSize		28
+#define	LDIR_Ord			0
+#define	LDIR_Attr			11
+#define	LDIR_Type			12
+#define	LDIR_Chksum			13
+#define	LDIR_FstClusLO		26
+
+
+
+/*--------------------------------*/
+/* Multi-byte word access macros  */
+
+#if _WORD_ACCESS == 1	/* Enable word access to the FAT structure */
+#define	LD_WORD(ptr)		(WORD)(*(WORD*)(BYTE*)(ptr))
+#define	LD_DWORD(ptr)		(DWORD)(*(DWORD*)(BYTE*)(ptr))
+#define	ST_WORD(ptr,val)	*(WORD*)(BYTE*)(ptr)=(WORD)(val)
+#define	ST_DWORD(ptr,val)	*(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
+#else					/* Use byte-by-byte access to the FAT structure */
+#define	LD_WORD(ptr)		(WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
+#define	LD_DWORD(ptr)		(DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr))
+#define	ST_WORD(ptr,val)	*(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8)
+#define	ST_DWORD(ptr,val)	*(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24)
+#endif
+
+#ifdef __cplusplus
+}
+#endif 
+
+
+#endif /* _FATFS */
diff --git a/reform2-lpc-fw/src/drivers/storage/fatfs/ffconf.h b/reform2-lpc-fw/src/drivers/storage/fatfs/ffconf.h
new file mode 100644
index 0000000000000000000000000000000000000000..265933fefc79d1234456e50499cc8cc9e3c8428d
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/storage/fatfs/ffconf.h
@@ -0,0 +1,175 @@
+/*---------------------------------------------------------------------------/
+/  FatFs - FAT file system module configuration file  R0.07e  (C)ChaN, 2009
+/----------------------------------------------------------------------------/
+/
+/ CAUTION! Do not forget to make clean the project after any changes to
+/ the configuration options.
+/
+/----------------------------------------------------------------------------*/
+#ifndef _FFCONFIG
+#define _FFCONFIG 0x007E
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+/*---------------------------------------------------------------------------/
+/ Function and Buffer Configurations
+/----------------------------------------------------------------------------*/
+
+#define        _FS_TINY        1                /* 0 or 1 */
+/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
+/  object instead of the sector buffer in the individual file object for file
+/  data transfer. This reduces memory consumption 512 bytes each file object. */
+
+
+#define _FS_READONLY        CFG_SDCARD_READONLY // 0        /* 0 or 1 */
+/* Setting _FS_READONLY to 1 defines read only configuration. This removes
+/  writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
+/  f_truncate and useless f_getfree. */
+
+
+#define _FS_MINIMIZE        0        /* 0, 1, 2 or 3 */
+/* The _FS_MINIMIZE option defines minimization level to remove some functions.
+/
+/   0: Full function.
+/   1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
+/      are removed.
+/   2: f_opendir and f_readdir are removed in addition to level 1.
+/   3: f_lseek is removed in addition to level 2. */
+
+
+#define        _USE_STRFUNC        0        /* 0, 1 or 2 */
+/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
+
+
+#define        _USE_MKFS        0                /* 0 or 1 */
+/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
+
+
+#define        _USE_FORWARD        0        /* 0 or 1 */
+/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
+
+
+
+/*---------------------------------------------------------------------------/
+/ Locale and Namespace Configurations
+/----------------------------------------------------------------------------*/
+
+#define _CODE_PAGE        858
+/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
+/  Incorrect setting of the code page can cause a file open failure.
+/
+/   932  - Japanese Shift-JIS (DBCS, OEM, Windows)
+/   936  - Simplified Chinese GBK (DBCS, OEM, Windows)
+/   949  - Korean (DBCS, OEM, Windows)
+/   950  - Traditional Chinese Big5 (DBCS, OEM, Windows)
+/   1250 - Central Europe (Windows)
+/   1251 - Cyrillic (Windows)
+/   1252 - Latin 1 (Windows)
+/   1253 - Greek (Windows)
+/   1254 - Turkish (Windows)
+/   1255 - Hebrew (Windows)
+/   1256 - Arabic (Windows)
+/   1257 - Baltic (Windows)
+/   1258 - Vietnam (OEM, Windows)
+/   437  - U.S. (OEM)
+/   720  - Arabic (OEM)
+/   737  - Greek (OEM)
+/   775  - Baltic (OEM)
+/   850  - Multilingual Latin 1 (OEM)
+/   858  - Multilingual Latin 1 + Euro (OEM)
+/   852  - Latin 2 (OEM)
+/   855  - Cyrillic (OEM)
+/   866  - Russian (OEM)
+/   857  - Turkish (OEM)
+/   862  - Hebrew (OEM)
+/   874  - Thai (OEM, Windows)
+/        1    - ASCII only (Valid for non LFN cfg.)
+*/
+
+
+#define        _USE_LFN        0                /* 0, 1 or 2 */
+#define        _MAX_LFN        255              /* Maximum LFN length to handle (12 to 255) */
+/* The _USE_LFN option switches the LFN support.
+/
+/   0: Disable LFN. _MAX_LFN and _LFN_UNICODE have no effect.
+/   1: Enable LFN with static working buffer on the bss. NOT REENTRANT.
+/   2: Enable LFN with dynamic working buffer on the STACK.
+/
+/  The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN,
+/  two Unicode handling functions ff_convert() and ff_wtoupper() must be added
+/  to the project. */
+
+
+#define        _LFN_UNICODE        0        /* 0 or 1 */
+/* To switch the character code set on FatFs API to Unicode,
+/  enable LFN feature and set _LFN_UNICODE to 1.
+*/
+
+
+#define _FS_RPATH        0                /* 0 or 1 */
+/* When _FS_RPATH is set to 1, relative path feature is enabled and f_chdir,
+/  f_chdrive function are available.
+/  Note that output of the f_readdir fnction is affected by this option. */
+
+
+
+/*---------------------------------------------------------------------------/
+/ Physical Drive Configurations
+/----------------------------------------------------------------------------*/
+
+#define _DRIVES                1
+/* Number of volumes (logical drives) to be used. */
+
+
+#define        _MAX_SS                512                /* 512, 1024, 2048 or 4096 */
+/* Maximum sector size to be handled.
+/  Always set 512 for memory card and hard disk but a larger value may be
+/  required for floppy disk (512/1024) and optical disk (512/2048).
+/  When _MAX_SS is larger than 512, GET_SECTOR_SIZE command must be implememted
+/  to the disk_ioctl function. */
+
+
+#define        _MULTI_PARTITION        0        /* 0 or 1 */
+/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical
+/ drive number and can mount only first primaly partition. When it is set to 1,
+/ each volume is tied to the partitions listed in Drives[]. */
+
+
+
+/*---------------------------------------------------------------------------/
+/ System Configurations
+/----------------------------------------------------------------------------*/
+
+#define _WORD_ACCESS        0        /* 0 or 1 */
+/* The _WORD_ACCESS option defines which access method is used to the word
+/  data on the FAT volume.
+/
+/   0: Byte-by-byte access. Always compatible with all platforms.
+/   1: Word access. Do not choose this unless following condition is met.
+/
+/  When the byte order on the memory is big-endian or address miss-aligned
+/  word access results incorrect behavior, the _WORD_ACCESS must be set to 0.
+/  If it is not the case, the value can also be set to 1 to improve the
+/  performance and code size. */
+
+
+#define _FS_REENTRANT        0                /* 0 or 1 */
+#define _FS_TIMEOUT                1000        /* Timeout period in unit of time ticks */
+#define        _SYNC_t                        HANDLE        /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
+/* The _FS_REENTRANT option switches the reentrancy of the FatFs module.
+/
+/   0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect.
+/   1: Enable reentrancy. Also user provided synchronization handlers,
+/      ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj
+/      function must be added to the project. */
+
+#ifdef __cplusplus
+}
+#endif 
+
+
+#endif /* _FFCONFIG */
diff --git a/reform2-lpc-fw/src/drivers/storage/fatfs/integer.h b/reform2-lpc-fw/src/drivers/storage/fatfs/integer.h
new file mode 100644
index 0000000000000000000000000000000000000000..39b68d413c0d325566a3ea6f7c78b5dc3a12288c
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/storage/fatfs/integer.h
@@ -0,0 +1,43 @@
+/*-------------------------------------------*/
+/* Integer type definitions for FatFs module */
+/*-------------------------------------------*/
+
+#ifndef _INTEGER
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if 0
+#include <windows.h>
+#else
+
+/* These types must be 16-bit, 32-bit or larger integer */
+typedef int				INT;
+typedef unsigned int	UINT;
+
+/* These types must be 8-bit integer */
+typedef signed char		CHAR;
+typedef unsigned char	UCHAR;
+typedef unsigned char	BYTE;
+
+/* These types must be 16-bit integer */
+typedef short			SHORT;
+typedef unsigned short	USHORT;
+typedef unsigned short	WORD;
+typedef unsigned short	WCHAR;
+
+/* These types must be 32-bit integer */
+typedef long			LONG;
+typedef unsigned long	ULONG;
+typedef unsigned long	DWORD;
+
+#endif
+
+#define _INTEGER
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/storage/fatfs/mmc.c b/reform2-lpc-fw/src/drivers/storage/fatfs/mmc.c
new file mode 100644
index 0000000000000000000000000000000000000000..08cc7ac219fcbb71f88289a7d88bc413fd53d2a1
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/storage/fatfs/mmc.c
@@ -0,0 +1,654 @@
+/*-----------------------------------------------------------------------*/
+/* MMCv3/SDv1/SDv2 (in SPI mode) control module  (C)ChaN, 2007           */
+/*-----------------------------------------------------------------------*/
+/* Only rcvr_spi(), xmit_spi(), disk_timerproc() and some macros         */
+/* are platform dependent.                                               */
+/*-----------------------------------------------------------------------*/
+
+#include "projectconfig.h"
+
+#ifdef CFG_SDCARD
+
+#include "diskio.h"
+#include "core/gpio/gpio.h"
+#if CFG_SDCARD_SPIPORT == 0
+  #include "core/ssp0/ssp0.h"
+#elif CFG_SDCARD_SPIPORT == 1
+  #include "core/ssp1/ssp1.h"
+#endif
+#include "core/delay/delay.h"
+
+/* Definitions for MMC/SDC command */
+#define CMD0        (0x40+0)         /* GO_IDLE_STATE */
+#define CMD1        (0x40+1)         /* SEND_OP_COND (MMC) */
+#define ACMD41      (0xC0+41)        /* SEND_OP_COND (SDC) */
+#define CMD8        (0x40+8)         /* SEND_IF_COND */
+#define CMD9        (0x40+9)         /* SEND_CSD */
+#define CMD10       (0x40+10)        /* SEND_CID */
+#define CMD12       (0x40+12)        /* STOP_TRANSMISSION */
+#define ACMD13      (0xC0+13)        /* SD_STATUS (SDC) */
+#define CMD16       (0x40+16)        /* SET_BLOCKLEN */
+#define CMD17       (0x40+17)        /* READ_SINGLE_BLOCK */
+#define CMD18       (0x40+18)        /* READ_MULTIPLE_BLOCK */
+#define CMD23       (0x40+23)        /* SET_BLOCK_COUNT (MMC) */
+#define ACMD23      (0xC0+23)        /* SET_WR_BLK_ERASE_COUNT (SDC) */
+#define CMD24       (0x40+24)        /* WRITE_BLOCK */
+#define CMD25       (0x40+25)        /* WRITE_MULTIPLE_BLOCK */
+#define CMD55       (0x40+55)        /* APP_CMD */
+#define CMD58       (0x40+58)        /* READ_OCR */
+
+/* Port Controls  (Platform dependent) */
+#define CS_LOW()    do { LPC_GPIO->CLR[CFG_SDCARD_SSELPORT] = (1 << CFG_SDCARD_SSELPIN); } while(0)
+#define CS_HIGH()   do { LPC_GPIO->SET[CFG_SDCARD_SSELPORT] = (1 << CFG_SDCARD_SSELPIN); } while(0)
+
+#define FDELAY(ms) delay(ms)     // Assumes delay = 1ms, ugly
+
+/*--------------------------------------------------------------------------
+
+   Module Private Functions
+
+---------------------------------------------------------------------------*/
+
+static volatile
+DSTATUS Stat = STA_NOINIT;        /* Disk status */
+
+static volatile
+BYTE Timer1, Timer2;        /* 100Hz decrement timer */
+
+static
+BYTE CardType;                        /* Card type flags */
+
+/*-----------------------------------------------------------------------*/
+/* Transmit a byte to MMC via SPI  (Platform dependent)                  */
+/*-----------------------------------------------------------------------*/
+
+//#define xmit_spi(dat) (SSPSend((uint8_t*)&(dat), 1))
+static void xmit_spi(BYTE dat)
+{
+    #if CFG_SDCARD_SPIPORT == 0
+      ssp0Send((uint8_t*) &dat, 1);
+    #elif CFG_SDCARD_SPIPORT == 1
+      ssp1Send((uint8_t*) &dat, 1);
+    #endif
+}
+
+
+/*-----------------------------------------------------------------------*/
+/* Receive a byte from MMC via SPI  (Platform dependent)                 */
+/*-----------------------------------------------------------------------*/
+
+static
+BYTE rcvr_spi (void)
+{
+    BYTE data = 0;
+
+    #if CFG_SDCARD_SPIPORT == 0
+      ssp0Receive(&data, 1);
+    #elif CFG_SDCARD_SPIPORT == 1
+      ssp1Receive(&data, 1);
+    #endif
+
+    return data;
+}
+
+/* Alternative macro to receive data fast */
+
+#if (CFG_SDCARD_SPIPORT == 0)
+  #define rcvr_spi_m(dst) \
+    do { \
+        ssp0Receive((uint8_t*)(dst), 1); \
+    } while(0)
+#elif (CFG_SDCARD_SPIPORT == 1)
+  #define rcvr_spi_m(dst) \
+    do { \
+        ssp1Receive((uint8_t*)(dst), 1); \
+    } while(0)
+#endif
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Wait for card ready                                                   */
+/*-----------------------------------------------------------------------*/
+
+static
+BYTE wait_ready (void)
+{
+        BYTE res;
+
+
+        Timer2 = 50;        /* Wait for ready in timeout of 500ms */
+        rcvr_spi();
+        do
+                res = rcvr_spi();
+        while ((res != 0xFF) && Timer2);
+
+        return res;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Deselect the card and release SPI bus                                 */
+/*-----------------------------------------------------------------------*/
+
+static
+void deselect (void)
+{
+        CS_HIGH();
+        rcvr_spi();
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Select the card and wait ready                                        */
+/*-----------------------------------------------------------------------*/
+
+static
+BOOL select (void)        /* TRUE:Successful, FALSE:Timeout */
+{
+        CS_LOW();
+        if (wait_ready() != 0xFF) {
+                deselect();
+                return FALSE;
+        }
+        return TRUE;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Power Control  (Platform dependent)                                   */
+/*-----------------------------------------------------------------------*/
+/* When the target system does not support socket power control, there   */
+/* is nothing to do in these functions and chk_power always returns 1.   */
+
+static
+void power_on (void)
+{
+  LPC_GPIO->CLR[CFG_SDCARD_ENBLPORT] = (1 << CFG_SDCARD_ENBLPIN);
+}
+
+static
+void power_off (void)
+{
+  LPC_GPIO->SET[CFG_SDCARD_ENBLPORT] = (1 << CFG_SDCARD_ENBLPIN);
+}
+
+static
+int chk_power(void)                /* Socket power state: 0=off, 1=on */
+{
+  return GPIOGetPinValue(CFG_SDCARD_ENBLPORT, CFG_SDCARD_ENBLPIN) ? 0 : 1;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Receive a data packet from MMC                                        */
+/*-----------------------------------------------------------------------*/
+
+static
+BOOL rcvr_datablock (
+        BYTE *buff,                        /* Data buffer to store received data */
+        UINT btr                        /* Byte count (must be multiple of 4) */
+)
+{
+        BYTE token;
+
+
+        Timer1 = 20;
+        do {                                                        /* Wait for data packet in timeout of 200ms */
+                token = rcvr_spi();
+        } while ((token == 0xFF) && Timer1);
+        if(token != 0xFE) return FALSE;        /* If not valid data token, retutn with error */
+
+        do {                                                        /* Receive the data block into buffer */
+                rcvr_spi_m(buff++);
+                rcvr_spi_m(buff++);
+                rcvr_spi_m(buff++);
+                rcvr_spi_m(buff++);
+        } while (btr -= 4);
+        rcvr_spi();                                                /* Discard CRC */
+        rcvr_spi();
+
+        return TRUE;                                        /* Return with success */
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Send a data packet to MMC                                             */
+/*-----------------------------------------------------------------------*/
+
+#if _READONLY == 0
+static
+BOOL xmit_datablock (
+        const BYTE *buff,        /* 512 byte data block to be transmitted */
+        BYTE token                        /* Data/Stop token */
+)
+{
+        BYTE resp, wc;
+
+
+        if (wait_ready() != 0xFF) return FALSE;
+
+        xmit_spi(token);                                        /* Xmit data token */
+        if (token != 0xFD) {        /* Is data token */
+                wc = 0;
+                do {                                                        /* Xmit the 512 byte data block to MMC */
+                        xmit_spi(*buff++);
+                        xmit_spi(*buff++);
+                } while (--wc);
+                xmit_spi(0xFF);                                        /* CRC (Dummy) */
+                xmit_spi(0xFF);
+                resp = rcvr_spi();                                /* Reveive data response */
+                if ((resp & 0x1F) != 0x05)                /* If not accepted, return with error */
+                        return FALSE;
+        }
+
+        return TRUE;
+}
+#endif /* _READONLY */
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Send a command packet to MMC                                          */
+/*-----------------------------------------------------------------------*/
+
+static
+BYTE send_cmd (
+        BYTE cmd,                /* Command byte */
+        DWORD arg                /* Argument */
+)
+{
+        BYTE n, res;
+
+
+        if (cmd & 0x80) {        /* ACMD<n> is the command sequense of CMD55-CMD<n> */
+                cmd &= 0x7F;
+                res = send_cmd(CMD55, 0);
+                if (res > 1) return res;
+        }
+
+        /* Select the card and wait for ready */
+        deselect();
+        if (!select()) return 0xFF;
+
+        /* Send command packet */
+        xmit_spi(cmd);                                                /* Start + Command index */
+        xmit_spi((BYTE)(arg >> 24));                /* Argument[31..24] */
+        xmit_spi((BYTE)(arg >> 16));                /* Argument[23..16] */
+        xmit_spi((BYTE)(arg >> 8));                        /* Argument[15..8] */
+        xmit_spi((BYTE)arg);                                /* Argument[7..0] */
+        n = 0x01;                                                        /* Dummy CRC + Stop */
+        if (cmd == CMD0) n = 0x95;                        /* Valid CRC for CMD0(0) */
+        if (cmd == CMD8) n = 0x87;                        /* Valid CRC for CMD8(0x1AA) */
+        xmit_spi(n);
+
+        /* Receive command response */
+        if (cmd == CMD12) rcvr_spi();                /* Skip a stuff byte when stop reading */
+        n = 10;                                                                /* Wait for a valid response in timeout of 10 attempts */
+        do
+                res = rcvr_spi();
+        while ((res & 0x80) && --n);
+
+        return res;                        /* Return with the response value */
+}
+
+
+
+/*--------------------------------------------------------------------------
+
+   Public Functions
+
+---------------------------------------------------------------------------*/
+
+
+/*-----------------------------------------------------------------------*/
+/* Initialize Disk Drive                                                 */
+/*-----------------------------------------------------------------------*/
+
+DSTATUS disk_initialize (
+        BYTE drv                /* Physical drive nmuber (0) */
+)
+{
+        BYTE n, cmd, ty, ocr[4];
+
+        // Init SSP (clock low between frames, transition on leading edge)
+        #if CFG_SDCARD_SPIPORT == 0
+          ssp0Init();
+        #elif CFG_SDCARD_SPIPORT == 1
+          ssp1Init();
+        #endif
+
+        LPC_GPIO->DIR[CFG_SDCARD_ENBLPORT] |= (1 << CFG_SDCARD_ENBLPORT);
+        LPC_GPIO->DIR[CFG_SDCARD_SSELPORT] |= (1 << CFG_SDCARD_SSELPORT);
+        LPC_GPIO->DIR[CFG_SDCARD_CDPORT]   &= ~(1 << CFG_SDCARD_CDPIN);
+
+        // Wait 20ms for card detect to stabilise
+        delay(20);
+
+        if (drv) return STA_NOINIT;                        /* Supports only single drive */
+        if (Stat & STA_NODISK) return Stat;        /* No card in the socket */
+
+        power_on();                                                        /* Force socket power on */
+        #if CFG_SDCARD_SPIPORT == 0
+          ssp0ClockSlow();
+        #elif CFG_SDCARD_SPIPORT == 1
+          ssp1ClockSlow();
+        #endif
+        for (n = 100; n; n--) rcvr_spi();        /* 80 dummy clocks */
+
+        ty = 0;
+        if (send_cmd(CMD0, 0) == 1) {                        /* Enter Idle state */
+                Timer1 = 100;                                                /* Initialization timeout of 1000 msec */
+                if (send_cmd(CMD8, 0x1AA) == 1) {        /* SDHC */
+                        for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();                /* Get trailing return value of R7 resp */
+                        if (ocr[2] == 0x01 && ocr[3] == 0xAA) {                                /* The card can work at vdd range of 2.7-3.6V */
+                                while (Timer1 && send_cmd(ACMD41, 1UL << 30));        /* Wait for leaving idle state (ACMD41 with HCS bit) */
+                                if (Timer1 && send_cmd(CMD58, 0) == 0) {                /* Check CCS bit in the OCR */
+                                        for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();
+                                        ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;        /* SDv2 */
+                                }
+                        }
+                } else {                                                        /* SDSC or MMC */
+                        if (send_cmd(ACMD41, 0) <= 1)        {
+                                ty = CT_SD1; cmd = ACMD41;        /* SDv1 */
+                        } else {
+                                ty = CT_MMC; cmd = CMD1;        /* MMCv3 */
+                        }
+                        while (Timer1 && send_cmd(cmd, 0));                        /* Wait for leaving idle state */
+                        if (!Timer1 || send_cmd(CMD16, 512) != 0)        /* Set R/W block length to 512 */
+                                ty = 0;
+                }
+        }
+        CardType = ty;
+        deselect();
+
+        if (ty) {                        /* Initialization succeded */
+                Stat &= ~STA_NOINIT;                /* Clear STA_NOINIT */
+                #if CFG_SDCARD_SPIPORT == 0
+                  ssp0ClockFast();
+                #elif CFG_SDCARD_SPIPORT == 1
+                  ssp1ClockFast();
+                #endif
+        } else {                        /* Initialization failed */
+                power_off();
+        }
+
+        return Stat;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Get Disk Status                                                       */
+/*-----------------------------------------------------------------------*/
+
+DSTATUS disk_status (
+        BYTE drv                /* Physical drive nmuber (0) */
+)
+{
+        if (drv) return STA_NOINIT;                /* Supports only single drive */
+        return Stat;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read Sector(s)                                                        */
+/*-----------------------------------------------------------------------*/
+
+DRESULT disk_read (
+        BYTE drv,                        /* Physical drive nmuber (0) */
+        BYTE *buff,                        /* Pointer to the data buffer to store read data */
+        DWORD sector,                /* Start sector number (LBA) */
+        BYTE count                        /* Sector count (1..255) */
+)
+{
+        if (drv || !count) return RES_PARERR;
+        if (Stat & STA_NOINIT) return RES_NOTRDY;
+
+        if (!(CardType & CT_BLOCK)) sector *= 512;        /* Convert to byte address if needed */
+
+        if (count == 1) {        /* Single block read */
+                if ((send_cmd(CMD17, sector) == 0)        /* READ_SINGLE_BLOCK */
+                        && rcvr_datablock(buff, 512))
+                        count = 0;
+        }
+        else {                                /* Multiple block read */
+                if (send_cmd(CMD18, sector) == 0) {        /* READ_MULTIPLE_BLOCK */
+                        do {
+                                if (!rcvr_datablock(buff, 512)) break;
+                                buff += 512;
+                        } while (--count);
+                        send_cmd(CMD12, 0);                                /* STOP_TRANSMISSION */
+                }
+        }
+        deselect();
+
+        return count ? RES_ERROR : RES_OK;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Write Sector(s)                                                       */
+/*-----------------------------------------------------------------------*/
+
+#if _READONLY == 0
+DRESULT disk_write (
+        BYTE drv,                        /* Physical drive nmuber (0) */
+        const BYTE *buff,        /* Pointer to the data to be written */
+        DWORD sector,                /* Start sector number (LBA) */
+        BYTE count                        /* Sector count (1..255) */
+)
+{
+        if (drv || !count) return RES_PARERR;
+        if (Stat & STA_NOINIT) return RES_NOTRDY;
+        if (Stat & STA_PROTECT) return RES_WRPRT;
+
+        if (!(CardType & CT_BLOCK)) sector *= 512;        /* Convert to byte address if needed */
+
+        if (count == 1) {        /* Single block write */
+                if ((send_cmd(CMD24, sector) == 0)        /* WRITE_BLOCK */
+                        && xmit_datablock(buff, 0xFE))
+                        count = 0;
+        }
+        else {                                /* Multiple block write */
+                if (CardType & CT_SDC) send_cmd(ACMD23, count);
+                if (send_cmd(CMD25, sector) == 0) {        /* WRITE_MULTIPLE_BLOCK */
+                        do {
+                                if (!xmit_datablock(buff, 0xFC)) break;
+                                buff += 512;
+                        } while (--count);
+                        if (!xmit_datablock(0, 0xFD))        /* STOP_TRAN token */
+                                count = 1;
+                }
+        }
+        deselect();
+
+        return count ? RES_ERROR : RES_OK;
+}
+#endif /* _READONLY == 0 */
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Miscellaneous Functions                                               */
+/*-----------------------------------------------------------------------*/
+
+#if _USE_IOCTL != 0
+DRESULT disk_ioctl (
+        BYTE drv,                /* Physical drive nmuber (0) */
+        BYTE ctrl,                /* Control code */
+        void *buff                /* Buffer to send/receive control data */
+)
+{
+        DRESULT res;
+        BYTE n, csd[16], *ptr = buff;
+        WORD csize;
+
+
+        if (drv) return RES_PARERR;
+
+        res = RES_ERROR;
+
+        if (ctrl == CTRL_POWER) {
+                switch (*ptr) {
+                case 0:                /* Sub control code == 0 (POWER_OFF) */
+                        if (chk_power())
+                                power_off();                /* Power off */
+                        res = RES_OK;
+                        break;
+                case 1:                /* Sub control code == 1 (POWER_ON) */
+                        power_on();                                /* Power on */
+                        res = RES_OK;
+                        break;
+                case 2:                /* Sub control code == 2 (POWER_GET) */
+                        *(ptr+1) = (BYTE)chk_power();
+                        res = RES_OK;
+                        break;
+                default :
+                        res = RES_PARERR;
+                }
+        }
+        else {
+                if (Stat & STA_NOINIT) return RES_NOTRDY;
+
+                switch (ctrl) {
+                case CTRL_SYNC :                /* Make sure that no pending write process. Do not remove this or written sector might not left updated. */
+                        if (select()) {
+                                res = RES_OK;
+                                deselect();
+                        }
+                        break;
+
+                case GET_SECTOR_COUNT :        /* Get number of sectors on the disk (DWORD) */
+                        if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
+                                if ((csd[0] >> 6) == 1) {        /* SDC ver 2.00 */
+                                        csize = csd[9] + ((WORD)csd[8] << 8) + 1;
+                                        *(DWORD*)buff = (DWORD)csize << 10;
+                                } else {                                        /* SDC ver 1.XX or MMC*/
+                                        n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
+                                        csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
+                                        *(DWORD*)buff = (DWORD)csize << (n - 9);
+                                }
+                                res = RES_OK;
+                        }
+                        break;
+
+                case GET_SECTOR_SIZE :        /* Get R/W sector size (WORD) */
+                        *(WORD*)buff = 512;
+                        res = RES_OK;
+                        break;
+
+                case GET_BLOCK_SIZE :        /* Get erase block size in unit of sector (DWORD) */
+                        if (CardType & CT_SD2) {        /* SDC ver 2.00 */
+                                if (send_cmd(ACMD13, 0) == 0) {        /* Read SD status */
+                                        rcvr_spi();
+                                        if (rcvr_datablock(csd, 16)) {                                /* Read partial block */
+                                                for (n = 64 - 16; n; n--) rcvr_spi();        /* Purge trailing data */
+                                                *(DWORD*)buff = 16UL << (csd[10] >> 4);
+                                                res = RES_OK;
+                                        }
+                                }
+                        } else {                                        /* SDC ver 1.XX or MMC */
+                                if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {        /* Read CSD */
+                                        if (CardType & CT_SD1) {        /* SDC ver 1.XX */
+                                                *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
+                                        } else {                                        /* MMC */
+                                                *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
+                                        }
+                                        res = RES_OK;
+                                }
+                        }
+                        break;
+
+                case MMC_GET_TYPE :                /* Get card type flags (1 byte) */
+                        *ptr = CardType;
+                        res = RES_OK;
+                        break;
+
+                case MMC_GET_CSD :                /* Receive CSD as a data block (16 bytes) */
+                        if (send_cmd(CMD9, 0) == 0                /* READ_CSD */
+                                && rcvr_datablock(ptr, 16))
+                                res = RES_OK;
+                        break;
+
+                case MMC_GET_CID :                /* Receive CID as a data block (16 bytes) */
+                        if (send_cmd(CMD10, 0) == 0                /* READ_CID */
+                                && rcvr_datablock(ptr, 16))
+                                res = RES_OK;
+                        break;
+
+                case MMC_GET_OCR :                /* Receive OCR as an R3 resp (4 bytes) */
+                        if (send_cmd(CMD58, 0) == 0) {        /* READ_OCR */
+                                for (n = 4; n; n--) *ptr++ = rcvr_spi();
+                                res = RES_OK;
+                        }
+                        break;
+
+                case MMC_GET_SDSTAT :        /* Receive SD statsu as a data block (64 bytes) */
+                        if (send_cmd(ACMD13, 0) == 0) {        /* SD_STATUS */
+                                rcvr_spi();
+                                if (rcvr_datablock(ptr, 64))
+                                        res = RES_OK;
+                        }
+                        break;
+
+                default:
+                        res = RES_PARERR;
+                }
+
+                deselect();
+        }
+
+        return res;
+}
+#endif /* _USE_IOCTL != 0 */
+
+
+/*-----------------------------------------------------------------------*/
+/* Device Timer Interrupt Procedure  (Platform dependent)                */
+/*-----------------------------------------------------------------------*/
+/* This function must be called in period of 10ms                        */
+/* Called in delay.c                                                     */
+
+void disk_timerproc (void)
+{
+  static BYTE pv;
+  BYTE n;
+  BYTE s;
+
+  n = Timer1;                                              /* 100Hz decrement timer */
+  if (n) Timer1 = --n;
+  n = Timer2;
+  if (n) Timer2 = --n;
+
+  n = pv;
+  pv = 0;
+  /* Sample card detect pin */
+  pv = GPIOGetPinValue(CFG_SDCARD_CDPORT, CFG_SDCARD_CDPIN);
+
+  /* Have contacts stabled? */
+  if (n == pv)
+  {
+    s = Stat;
+
+    /* write protect NOT supported */
+
+    /* check card detect */
+    if (!pv)                            /* (Socket empty) */
+      s |= (STA_NODISK | STA_NOINIT);
+    else                            /* (Card inserted) */
+      s &= ~STA_NODISK;
+
+    Stat = s;
+  }
+}
+
+#endif /* CFG_SDCARD */
diff --git a/reform2-lpc-fw/src/drivers/storage/logger.c b/reform2-lpc-fw/src/drivers/storage/logger.c
new file mode 100644
index 0000000000000000000000000000000000000000..844cf61d6dcde34bf27b1d1d49d892b8aea15b1d
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/storage/logger.c
@@ -0,0 +1,246 @@
+/**************************************************************************/
+/*!
+    @file     logger.c
+    @brief    Logs data to a file
+    @author   K. Townsend (microBuilder.eu)
+
+    @section Example
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#include <string.h>
+#include "logger.h"
+
+#define LOGGER_LOCALFILE (0) /* Create a file on the HD via the J-Link */
+#define LOGGER_FATFSFILE (1) /* Store a file on the SD card via FatFS  */
+
+// Write local files using crossworks debug library (CW Debug only)
+#if LOGGER_LOCALFILE
+  #ifdef __CROSSWORKS_ARM
+    #include <cross_studio_io.h>
+    DEBUG_FILE * loggerLocalFile;
+  #endif
+#endif
+
+// Write files to SD using FatFS
+#if defined CFG_SDCARD && LOGGER_FATFSFILE
+  #include "drivers/storage/fatfs/diskio.h"
+  #include "drivers/storage/fatfs/ff.h"
+  static FATFS Fatfs[1];
+  static FIL loggerSDFile;
+#endif
+
+char * loggerFName;
+static bool loggerInitialised = FALSE;
+
+/**************************************************************************/
+/*!
+    @brief Initialises a new text file for data logging
+
+    @param  filename  Full path and filename for the log file
+    @param  action    LOGGER_FILEACTION_APPEND to create a file if it
+                      doesn't already exist or append to an existing file,
+                      or LOGGER_FILEACTION_ALWAYSCREATE to always create
+                      a new file, overwriting any previously existing file
+                      with the same name.
+
+    @note   Possible errors are:
+
+            - ERROR_FATFS_NODISK
+            - ERROR_FATFS_INITFAILED
+            - ERROR_FATFS_FAILEDTOMOUNTDRIVE
+            - ERROR_FATFS_UNABLETOCREATEFILE
+            - ERROR_NONE
+
+    @code
+
+    err_t error;
+    error = loggerInit("/folder/datalog.csv", LOGGER_FILEACTION_APPEND);
+
+    if (!error)
+    {
+      // Start logging data with loggerWrite() ...
+    }
+
+    // Make sure we close the file to commit any unwritten data!
+    loggerClose();
+
+    @endcode
+*/
+/**************************************************************************/
+err_t loggerInit(char *filename, logger_fileaction_t action)
+{
+  loggerFName = filename;
+
+  #if LOGGER_LOCALFILE
+    #ifdef __CROSSWORKS_ARM
+      switch (action)
+      {
+        case (LOGGER_FILEACTION_ALWAYSCREATE):
+          // Always create a new file
+          loggerLocalFile = debug_fopen(loggerFName, "wt");
+          break;
+        default:
+          // Append data to existing files
+          loggerLocalFile = debug_fopen(loggerFName, "at");
+          break;
+      }
+    #endif
+  #endif
+
+  #if defined CFG_SDCARD && LOGGER_FATFSFILE
+    DSTATUS stat = disk_status(0);
+
+    // Make sure an SD card is present
+    if (stat & STA_NODISK)
+    {
+      return ERROR_FATFS_NODISK;
+    }
+
+    // Check if the SD card has already been initialised
+    if (stat & STA_NOINIT)
+    {
+      // Try to initialise it here
+      if(disk_initialize(0) & (STA_NOINIT | STA_NODISK))
+      {
+        return ERROR_FATFS_INITFAILED;
+      }
+    }
+
+    // SD card successfully initialised
+    if (stat == 0)
+    {
+      BYTE res;
+      // Try to mount the fat file system
+      res = f_mount(0, &Fatfs[0]);
+      if (res != FR_OK)
+      {
+        return ERROR_FATFS_FAILEDTOMOUNTDRIVE;
+      }
+      if (res == FR_OK)
+      {
+        switch (action)
+        {
+          case (LOGGER_FILEACTION_ALWAYSCREATE):
+            // Create a file (overwriting any existing file!)
+            if(f_open(&loggerSDFile, loggerFName, FA_READ | FA_WRITE | FA_CREATE_ALWAYS)!=FR_OK)
+            {
+              return ERROR_FATFS_UNABLETOCREATEFILE;
+            }
+            break;
+          default:
+            // Append to an existing file is present, otherwise create one
+            if(f_open(&loggerSDFile, loggerFName, FA_READ | FA_WRITE | FA_OPEN_ALWAYS)!=FR_OK)
+            {
+              return ERROR_FATFS_UNABLETOCREATEFILE;
+            }
+            // Move to end of the file if we are appending data
+            f_lseek(&loggerSDFile, (&loggerSDFile)->fsize);
+            break;
+        }
+      }
+    }
+  #endif
+
+  loggerInitialised = TRUE;
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief Appends the supplied buffer to the log file created in
+           loggerInit()
+*/
+/**************************************************************************/
+err_t loggerWrite(const uint8_t * buffer, uint32_t len)
+{
+  if (!loggerInitialised)
+  {
+    return ERROR_DEVICENOTINITIALISED;
+  }
+
+  #if LOGGER_LOCALFILE
+    #ifdef __CROSSWORKS_ARM
+      int written;
+      // Open file for text append
+      written = debug_fwrite(buffer, len, 1, loggerLocalFile);
+      if (written != len)
+      {
+        return ERROR_FATFS_WRITEFAILED;
+      }
+    #endif
+  #endif
+
+  #if defined CFG_SDCARD && LOGGER_FATFSFILE
+    BYTE res;
+    unsigned int bytesWritten;
+    DSTATUS stat = disk_status(0);
+
+    // Make sure the SD card is still present
+    if(stat & STA_NODISK)
+    {
+      return ERROR_FATFS_NODISK;
+    }
+
+    // Write the data to the log file
+    res = f_write(&loggerSDFile, buffer, len, &bytesWritten);
+    if (res != FR_OK)
+    {
+      return ERROR_FATFS_WRITEFAILED;
+    }
+  #endif
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief Writes an uncommitted data and closes the file
+*/
+/**************************************************************************/
+err_t loggerClose(void)
+{
+  #if LOGGER_LOCALFILE
+    #ifdef __CROSSWORKS_ARM
+      debug_fclose(loggerLocalFile);
+    #endif
+  #endif
+
+  #if defined CFG_SDCARD && LOGGER_FATFSFILE
+    f_sync(&loggerSDFile);    // Sync any uncommitted data
+    f_close(&loggerSDFile);   // Close the file
+    f_mount(0, 0);            // Unmount the file system
+  #endif
+
+  return ERROR_NONE;
+}
diff --git a/reform2-lpc-fw/src/drivers/storage/logger.h b/reform2-lpc-fw/src/drivers/storage/logger.h
new file mode 100644
index 0000000000000000000000000000000000000000..e9e6bbf5ed0632386fb715fa652c7d152bd8c54b
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/storage/logger.h
@@ -0,0 +1,51 @@
+/**************************************************************************/
+/*!
+    @file     logger.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef __LOGGER_H__
+#define __LOGGER_H__
+
+#include "projectconfig.h"
+
+typedef enum
+{
+  LOGGER_FILEACTION_APPEND       = 0, /**< Creates a new file if it doesn't exist or appends to an existing file */
+  LOGGER_FILEACTION_ALWAYSCREATE = 1  /**< Always creates a new file, overwriting any older existing file        */
+} logger_fileaction_t;
+
+err_t loggerInit(char *filename, logger_fileaction_t action);
+err_t loggerWrite(const uint8_t * buffer, uint32_t len);
+err_t loggerClose(void);
+
+#endif
diff --git a/reform2-lpc-fw/src/drivers/timespan.c b/reform2-lpc-fw/src/drivers/timespan.c
new file mode 100644
index 0000000000000000000000000000000000000000..c32bb21b922be09690e442a85ae3598d160aefd3
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/timespan.c
@@ -0,0 +1,315 @@
+/**************************************************************************/
+/*!
+    @file     timespan.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @note Timespan uses nanoseconds internally, with int64_t as the
+          native type, giving +/-292 years range
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <string.h>
+#include "timespan.h"
+
+/**************************************************************************/
+/*!
+    @brief   Create a new timespan_t based on the specified number of
+            nanoseconds/ticks
+
+    @param   ticks [in]  Number of nanosecond 'ticks' in the timespan_t
+    @param   timespan    Pointer to the timespan_t object to manipulate
+
+    @return  An err_t if an error occurred, or ERROR_NONE if everything
+             executed properly and the timespan was created
+ */
+/**************************************************************************/
+err_t timespanCreate(int64_t ticks, timespan_t *timespan)
+{
+  if (timespan == NULL)
+  {
+    return ERROR_INVALIDPARAMETER;
+  }
+
+  memcpy(timespan, 0, sizeof(timespan_t));
+
+  timespan->days = (ticks / TIMESPAN_NANOSPERDAY);
+  timespan->hours = (ticks / TIMESPAN_NANOSPERHOUR) % 24;
+  timespan->minutes = (ticks / TIMESPAN_NANOSPERMINUTE) % 60;
+  timespan->seconds = (ticks / TIMESPAN_NANOSPERSECOND) % 60;
+  timespan->milliseconds = (ticks / TIMESPAN_NANOSPERMILLISECOND) % 1000;
+  timespan->microseconds = (ticks / TIMESPAN_NANOSPERMICROSECOND) % 1000;
+  timespan->nanoseconds = (ticks % 1000);
+  timespan->__ticks = ticks;
+
+  return ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief   Create a timespan_t by explicitly supplying the
+             individual parameters
+
+    @param   timespan    Pointer to the timespan_t object to manipulate
+
+    @return  An err_t if an error occurred, or ERROR_NONE if everything
+             executed properly and the timespan was created
+ */
+/**************************************************************************/
+err_t timespanCreateExplicit(int32_t days, int32_t hours, int32_t minutes,
+  int32_t seconds, int32_t milliseconds, int32_t microseconds,
+  int32_t nanoseconds, timespan_t *timespan)
+{
+  int64_t ticks;
+
+  if (timespan == NULL)
+  {
+    return ERROR_INVALIDPARAMETER;
+  }
+
+  /* Check individual parameters */
+  if((days > TIMESPAN_MAXDAYS) || (days < TIMESPAN_MINDAYS)) return ERROR_TIMESPAN_OUTOFRANGE;
+  if((hours > 23) || (hours < -23)) return ERROR_INVALIDPARAMETER;
+  if((minutes > 59) || (minutes < -59)) return ERROR_INVALIDPARAMETER;
+  if((seconds > 59) || (seconds < -59)) return ERROR_INVALIDPARAMETER;
+  if((milliseconds > 999) || (milliseconds < -999)) return ERROR_INVALIDPARAMETER;
+  if((microseconds > 999) || (microseconds < -999)) return ERROR_INVALIDPARAMETER;
+  if((nanoseconds > 999) || (nanoseconds < -999)) return ERROR_INVALIDPARAMETER;
+
+  /* Calculate total ticks minus days for int64_t overflow check */
+  ticks = hours * TIMESPAN_NANOSPERHOUR +
+          minutes * TIMESPAN_NANOSPERMINUTE +
+          seconds * TIMESPAN_NANOSPERSECOND +
+          milliseconds * TIMESPAN_NANOSPERMILLISECOND +
+          microseconds * TIMESPAN_NANOSPERMICROSECOND +
+          nanoseconds;
+
+  /* Min/max timespan is +/-106751 days, 23 hours, 47 minutes and 16.854775807 seconds */
+  if ((days == TIMESPAN_MAXDAYS ) || (days == TIMESPAN_MINDAYS))
+  {
+    if (((days == TIMESPAN_MAXDAYS) && (ticks > 85636854775807)) ||
+        ((days == TIMESPAN_MINDAYS) && (ticks < -85636854775807)))
+    {
+      return ERROR_TIMESPAN_OUTOFRANGE;
+    }
+  }
+
+  /* Add days now that we're sure we're within int64_t limits */
+  ticks += days * TIMESPAN_NANOSPERDAY;
+
+  /* Create the timespan based on calculated ticks */
+  return timespanCreate(ticks, timespan);
+}
+
+/**************************************************************************/
+/*!
+    @brief   Subtracts t1 from t2 and assigns the difference (positive or
+             negative) to timespan
+
+    @param   t1 [in]     Pointer to timestamp_t 1
+    @param   t2 [in]     Pointer to timestamp_t 2
+    @param   timespan    Pointer to the timespan_t object to store the
+                         resulting difference in
+
+    @return  An err_t if an error occurred, or ERROR_NONE if everything
+             executed properly and the timespan was created
+ */
+/**************************************************************************/
+err_t timespanDifference(timespan_t *t1, timespan_t *t2, timespan_t *timespan)
+{
+  if ((t1 == NULL) || (t2 == NULL) || (timespan == NULL))
+  {
+    return ERROR_INVALIDPARAMETER;
+  }
+
+  return timespanCreate(t2->__ticks - t1->__ticks, timespan);
+}
+
+/**************************************************************************/
+/*!
+    @brief   Adds the 'val' timespan_t to 'timespan'
+
+    @param   val [in]    Pointer to timestamp_t to add to timespan
+    @param   timespan    Pointer to the timespan_t object that 'val' will
+                         be added to
+
+    @return  An err_t if an error occurred, or ERROR_NONE if everything
+             executed properly and the timespan was updated
+ */
+/**************************************************************************/
+err_t timespanAdd(timespan_t *val, timespan_t *timespan)
+{
+  int64_t ticks;
+
+  if ((val == NULL) || (timespan == NULL))
+  {
+    return ERROR_INVALIDPARAMETER;
+  }
+
+  if (val->__ticks < 0)
+  {
+    /* Val is negative ... will we underflow in the negative dir? */
+    if (timespan->__ticks < 0)
+    {
+      /* We can only underflow if timespan is also negative */
+      if (val->__ticks < (TIMESPAN_MINNANOSECONDS - timespan->__ticks))
+      {
+        /* ToDo: We could also just set an underflow flag and add the
+           digit together anyway?  Knowing that we've underflowed it's
+           easy to determine the number of nanoseconds anyway since the
+           underflow effects are predictable. */
+        return ERROR_TIMESPAN_OUTOFRANGE;
+      }
+    }
+  }
+  else
+  {
+    /* Val is positive ... will we overflow in the positive dir? */
+    if (val->__ticks > (TIMESPAN_MAXNANOSECONDS - timespan->__ticks))
+    {
+      /* ToDo: We could also just set an overflow flag and add the
+         digit together anyway?  Knowing that we've overflowed it's
+         easy to determine the number of nanoseconds anyway since the
+         overflow effects are predictable. */
+      return ERROR_TIMESPAN_OUTOFRANGE;
+    }
+  }
+
+  /* Add the two timespans together */
+  ticks = val->__ticks + timespan->__ticks;
+
+  return timespanCreate(ticks, timespan);
+}
+
+/**************************************************************************/
+/*!
+    @brief   Subtracts the 'val' timespan_t from 'timespan'
+
+    @param   val [in]    Pointer to timestamp_t to subtract from timespan
+    @param   timespan    Pointer to the timespan_t object that 'val' will
+                         be subtracted from
+
+    @return  An err_t if an error occurred, or ERROR_NONE if everything
+             executed properly and the timespan was updated
+ */
+/**************************************************************************/
+err_t timespanSubtract(timespan_t *val, timespan_t *timespan)
+{
+  timespan_t inv;
+  err_t error;
+
+  /* Create a new timespan with an inverted val->__ticks */
+  error = timespanCreate(val->__ticks * -1, &inv);
+  if (error)
+  {
+    return error;
+  }
+
+  /* Reuse the add function */
+  return timespanAdd(&inv, timespan);
+}
+
+/* ToDo: All of the functions calling each other below is going to
+   seriously bloat the stack with all of those pushes and pops ...
+   redo the ToXXX functions to avoid a half-dozen branches */
+
+/**************************************************************************/
+/*!
+    Returns the total number of whole hours in the specified timespan
+ */
+/**************************************************************************/
+int32_t timespanToHours(timespan_t *timespan)
+{
+  if (timespan->days == 0)
+  {
+    return timespan->hours;
+  }
+
+  return timespan->hours + (timespan->days * 24);
+}
+
+/**************************************************************************/
+/*!
+    Returns the total number of whole minutes in the specified timespan
+ */
+/**************************************************************************/
+int32_t timespanToMinutes(timespan_t *timespan)
+{
+  return (timespanToHours(timespan) * 60) + timespan->minutes;
+}
+
+/**************************************************************************/
+/*!
+    Returns the total number of whole seconds in the specified timespan
+ */
+/**************************************************************************/
+int64_t timespanToSeconds(timespan_t *timespan)
+{
+  return ((int64_t)timespanToMinutes(timespan) * 60) + timespan->seconds;
+}
+
+/**************************************************************************/
+/*!
+    Returns the total number of whole milliseconds in the specified timespan
+ */
+/**************************************************************************/
+int64_t timespanToMilliseconds(timespan_t *timespan)
+{
+  return ((int64_t)timespanToSeconds(timespan) * 1000) + timespan->milliseconds;
+}
+
+/**************************************************************************/
+/*!
+    Returns the total number of whole microseconds in the specified timespan
+ */
+/**************************************************************************/
+int64_t timespanToMicroseconds(timespan_t *timespan)
+{
+  return ((int64_t)timespanToMilliseconds(timespan) * 1000) + timespan->microseconds;
+}
+
+/**************************************************************************/
+/*!
+    Converts the specified number of core clock ticks to timespan
+    ticks (nanosecods)
+
+    @param   clockTicks [in] The number of system clock ticks to convert
+                             to timespan ticks (nanoseconds)
+ */
+/**************************************************************************/
+int64_t timespanSystemClockToTicks(int32_t clockTicks)
+{
+  uint32_t nsPerTick;
+
+  /* Get fixed point value for ns per core clock tick */
+  nsPerTick = 1000000 / (SystemCoreClock / 1000000);
+
+  return ((int64_t)clockTicks * (int64_t)nsPerTick) / 1000LL;
+}
diff --git a/reform2-lpc-fw/src/drivers/timespan.h b/reform2-lpc-fw/src/drivers/timespan.h
new file mode 100644
index 0000000000000000000000000000000000000000..20ab85e379b7610ee346a045a11e5d1222d82ca4
--- /dev/null
+++ b/reform2-lpc-fw/src/drivers/timespan.h
@@ -0,0 +1,75 @@
+/**************************************************************************/
+/*!
+    @file     timespan.h
+    @author   K. Townsend (microBuilder.eu)
+    @license  BSD (see license.txt)
+*/
+/**************************************************************************/
+#ifndef _TIMESPAN_H_
+#define _TIMESPAN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "projectconfig.h"
+
+#define TIMESPAN_NANOSPERMICROSECOND        (1000LL)
+#define TIMESPAN_NANOSPERMILLISECOND        (TIMESPAN_NANOSPERMICROSECOND * 1000LL) /* 1,000,000          */
+#define TIMESPAN_NANOSPERSECOND             (TIMESPAN_NANOSPERMILLISECOND * 1000LL) /* 1,000,000,000      */
+#define TIMESPAN_NANOSPERMINUTE             (TIMESPAN_NANOSPERSECOND * 60LL)        /* 60,000,000,000     */
+#define TIMESPAN_NANOSPERHOUR               (TIMESPAN_NANOSPERMINUTE * 60LL)        /* 3,600,000,000,000  */
+#define TIMESPAN_NANOSPERDAY                (TIMESPAN_NANOSPERHOUR * 24LL)          /* 86,400,000,000,000 */
+
+#define TIMESPAN_MAXNANOSECONDS             9223372036854775807LL
+#define TIMESPAN_MINNANOSECONDS             -9223372036854775807LL
+#define TIMESPAN_MAXMICROSECONDS            (TIMESPAN_MAXNANOSECONDS / TIMESPAN_NANOSPERMICROSECOND)
+#define TIMESPAN_MINMICROSECONDS            (TIMESPAN_MINNANOSECONDS / TIMESPAN_NANOSPERMICROSECOND)
+#define TIMESPAN_MAXMILLISECONDS            (TIMESPAN_MAXNANOSECONDS / TIMESPAN_NANOSPERMILLISECOND)
+#define TIMESPAN_MINMILLISECONDS            (TIMESPAN_MINNANOSECONDS / TIMESPAN_NANOSPERMILLISECOND)
+#define TIMESPAN_MAXSECONDS                 (TIMESPAN_MAXNANOSECONDS / TIMESPAN_NANOSPERSECOND)
+#define TIMESPAN_MINSECONDS                 (TIMESPAN_MINNANOSECONDS / TIMESPAN_NANOSPERSECOND)
+#define TIMESPAN_MAXMINUTES                 (TIMESPAN_MAXNANOSECONDS / TIMESPAN_NANOSPERMINUTE)
+#define TIMESPAN_MINMINUTES                 (TIMESPAN_MINNANOSECONDS / TIMESPAN_NANOSPERMINUTE)
+#define TIMESPAN_MAXHOURS                   (TIMESPAN_MAXNANOSECONDS / TIMESPAN_NANOSPERHOUR)
+#define TIMESPAN_MINHOURS                   (TIMESPAN_MINNANOSECONDS / TIMESPAN_NANOSPERHOUR)
+#define TIMESPAN_MAXDAYS                    (TIMESPAN_MAXNANOSECONDS / TIMESPAN_NANOSPERDAY)
+#define TIMESPAN_MINDAYS                    (TIMESPAN_MINNANOSECONDS / TIMESPAN_NANOSPERDAY)
+
+/**************************************************************************/
+/*!
+ * @brief     Timespan structure
+ * @warning:  To ensure that this structure always contains a valid
+ *            timespan, do not assign field values directly. Please
+ *            call timespanCreate functions instead.
+ */
+/**************************************************************************/
+typedef struct
+{
+  int32_t days;           /**< Number of days */
+  int32_t hours;          /**< Number of hours (+/-0..23) */
+  int32_t minutes;        /**< Number of minutes (+/-0..59) */
+  int32_t seconds;        /**< Number of seconds (+/-0..59) */
+  int32_t milliseconds;   /**< Number of milliseconds (+/-0..999) */
+  int32_t microseconds;   /**< Number of microseconds (+/-0..999) */
+  int32_t nanoseconds;    /**< Number of nanoseconds (+/-0..999) */
+  int64_t __ticks;        /**< Total nanoseconds (used to track time internally) */
+} timespan_t;
+
+err_t timespanCreate(int64_t ticks, timespan_t *timespan);
+err_t timespanCreateExplicit(int32_t days, int32_t hours, int32_t minutes, int32_t seconds, int32_t milliseconds, int32_t microseconds, int32_t nanoseconds, timespan_t *timespan);
+err_t timespanDifference(timespan_t *t1, timespan_t *t2, timespan_t *timespan);
+err_t timespanAdd(timespan_t *val, timespan_t *timespan);
+err_t timespanSubtract(timespan_t *val, timespan_t *timespan);
+int32_t timespanToHours(timespan_t *timespan);
+int32_t timespanToMinutes(timespan_t *timespan);
+int64_t timespanToSeconds(timespan_t *timespan);
+int64_t timespanToMilliseconds(timespan_t *timespan);
+int64_t timespanToMicroseconds(timespan_t *timespan);
+int64_t timespanSystemClockToTicks(int32_t clockTicks);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/errors.h b/reform2-lpc-fw/src/errors.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ca97c99682fbb9c57f7bc9672cd562261767659
--- /dev/null
+++ b/reform2-lpc-fw/src/errors.h
@@ -0,0 +1,198 @@
+/**************************************************************************/
+/*!
+    @defgroup Errors Error Handling
+
+    @brief    System wide error codes and error-handling
+
+    @details
+
+    In order to improve the stability of the system the code base uses a
+    global error type that any critical function returns upon completion.
+
+    Functions that execute properly return ERROR_NONE, which equals '0' so
+    that we can perform a simple check like 'if(error) { ... }'.
+*/
+/**************************************************************************/
+
+/**************************************************************************/
+/*!
+    @file     errors.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @ingroup  Errors
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _ERRORS_H_
+#define _ERRORS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**************************************************************************/
+/*!
+    Common error messages used across the system
+*/
+/**************************************************************************/
+typedef enum
+{
+  /*=======================================================================
+    GENERIC ERRORS                                         0x0000 .. 0x00FF
+    -----------------------------------------------------------------------
+    These error codes can be used anywhere in the system
+    -----------------------------------------------------------------------*/
+    ERROR_NONE                                  = 0x0,  /**< Indicates no error occurred */
+    ERROR_OPERATIONTIMEDOUT                     = 0x1,  /**< Operation timed out before completion */
+    ERROR_ADDRESSOUTOFRANGE                     = 0x2,  /**< The supplied address is out of range */
+    ERROR_BUFFEROVERFLOW                        = 0x3,  /**< The proposed action will cause a buffer overflow */
+    ERROR_INVALIDPARAMETER                      = 0x4,  /**< An invalid parameter value was provided */
+    ERROR_DEVICENOTINITIALISED                  = 0x5,  /**< Attempting to execute a function on an uninitialised peripheral */
+    ERROR_UNEXPECTEDVALUE                       = 0x6,  /**< An unexpected value was found inside a function */
+  /*=======================================================================*/
+
+
+  /*=======================================================================
+    I2C ERRORS                                             0x0100 .. 0x010F
+    -----------------------------------------------------------------------
+    Errors related to the I2C bus
+    -----------------------------------------------------------------------*/
+    ERROR_I2C_DEVICENOTFOUND                    = 0x101,  /**< Device didn't ACK after an I2C transfer */
+    ERROR_I2C_NOACK                             = 0x102,  /**< No ACK signal received during an I2C transfer */
+    ERROR_I2C_TIMEOUT                           = 0x103,  /**< Device timed out waiting for response (missing pullups?) */
+  /*=======================================================================*/
+
+
+  /*=======================================================================
+    CHIBI ERRORS                                           0x0110 .. 0x011F
+    -----------------------------------------------------------------------
+    Errors relating the Chibi/802.15.4 wireless communication
+    -----------------------------------------------------------------------*/
+    ERROR_CHIBI_NOACK                           = 0x111,  /**< No ACK from destination node (bad address or offline?) */
+    ERROR_CHIBI_CHANACCESSFAILURE               = 0x112,  /**< Channel access failure */
+    ERROR_CHIBI_PAYLOADOVERFLOW                 = 0x113,  /**< Payload exceeds buffer size */
+  /*=======================================================================*/
+
+
+  /*=======================================================================
+    SIMPLE BINARY PROTOCOL ERRORS                          0x0120 .. 0x013F
+    -----------------------------------------------------------------------
+    Errors relating to the simple binary protocol (/src//protocol)
+    -----------------------------------------------------------------------*/
+    ERROR_PROT_INVALIDMSGTYPE                   = 0x121,  /**< Unexpected msg type encountered */
+    ERROR_PROT_INVALIDCOMMANDID                 = 0x122,  /**< Unknown or out of range command ID */
+    ERROR_PROT_INVALIDPAYLOAD                   = 0x123,  /**< Message payload has a problem (invalid len, etc.) */
+  /*=======================================================================*/
+
+
+  /*=======================================================================
+    RTC ERRORS                                             0x0140 .. 0x014F
+    -----------------------------------------------------------------------
+    Real time clock (RTC) errors
+    -----------------------------------------------------------------------*/
+    ERROR_RTC_OUTOFEPOCHRANGE                   = 0x141,  /**< RTC time must be kept in epoch range */
+  /*=======================================================================*/
+
+
+  /*=======================================================================
+    TIMESPAN ERRORS                                        0x0150 .. 0x015F
+    -----------------------------------------------------------------------
+    Errors relating to the timespan.c helper class
+    -----------------------------------------------------------------------*/
+    ERROR_TIMESPAN_OUTOFRANGE                   = 0x151,  /**< timespan_t must be kept within int64_t nanosecond range */
+  /*=======================================================================*/
+
+
+  /*=======================================================================
+    FATFS ERRORS                                           0x0160 .. 0x016F
+    -----------------------------------------------------------------------
+    These error codes can be used anywhere in the system
+    -----------------------------------------------------------------------*/
+    ERROR_FATFS_NODISK                          = 0x161,  /**< No SD card present (based on polling the CD pin) */
+    ERROR_FATFS_INITFAILED                      = 0x162,  /**< Failed trying to initialise FatFS */
+    ERROR_FATFS_FAILEDTOMOUNTDRIVE              = 0x163,  /**< Failed trying to mount the drive (not FAT formatted?) */
+    ERROR_FATFS_UNABLETOCREATEFILE              = 0x164,  /**< Failed trying to create a file on the SD card */
+    ERROR_FATFS_UNABLETOOPENFILE                = 0x165,  /**< Failed trying to open the specified file */
+    ERROR_FATFS_WRITEFAILED                     = 0x166,  /**< Failed trying to write to the SD card */
+  /*=======================================================================*/
+
+
+  /*=======================================================================
+    USB ERRORS                                             0x0200 .. 0x02FF
+    -----------------------------------------------------------------------
+    USB error codes
+    TODO: Harmonise LPC codes with error IDs here!
+    -----------------------------------------------------------------------*/
+
+  /*=======================================================================*/
+
+
+  /*=======================================================================
+    CC3000 ERRORS                                          0x0400 .. 0x04FF
+    -----------------------------------------------------------------------
+    Errors relating to the CC3000 Wifi module and wifi communication
+    -----------------------------------------------------------------------*/
+    ERROR_CC3000_CONNECT_TIMEOUT                = 0x401,  /**< Timed out waiting for a connection or DHCP */
+    ERROR_CC3000_SMARTCONFIG_SET_PREFIX         = 0x411,  /**< Smart config failed calling 'wlan_smart_config_set_prefix' */
+    ERROR_CC3000_SMARTCONFIG_START              = 0x412,  /**< Smart config failed calling 'wlan_smart_config_start' */
+    ERROR_CC3000_SMARTCONFIG_PROCESS            = 0x413,  /**< Smart config failed called 'wlan_smart_config_process' */
+    ERROR_CC3000_NVMEM_READ                     = 0x421,  /**< Failed reading from NVMEM */
+    ERROR_CC3000_NVMEM_WRITE                    = 0x422,  /**< Failed writing to NVMEM */
+    ERROR_CC3000_NVMEM_CREATE_ENTRY             = 0x423,  /**< Failed creating an NVMEM entry via 'nvmem_create_entry' */
+    ERROR_CC3000_NVMEM_SET_MAC_ADDRESS          = 0x424,  /**< Failed creating an NVMEM entry via 'netapp_config_mac_adrress' */
+    ERROR_CC3000_WLAN_EVENT_MASK                = 0x431,  /**< Failed calling 'wlan_set_event_mask' */
+    ERROR_CC3000_WLAN_SET_CONNECT_POLICY        = 0x432,  /**< Failed calling 'wlan_ioctl_set_connection_policy' */
+    ERROR_CC3000_WLAN_DEL_CONNECT_PROFILE       = 0x433,  /**< Failed calling 'wlan_ioctl_del_profile' */
+    ERROR_CC3000_WLAN_DISCONNECT                = 0x434,  /**< Failed calling 'wlan_disconnect' */
+    ERROR_CC3000_WLAN_CONNECT                   = 0x435,  /**< Failed calling 'wlan_connect' */
+    ERROR_CC3000_WLAN_SET_SCAN_PARAM            = 0x436,  /**< Failed calling 'wlan_ioctl_set_scan_params' */
+    ERROR_CC3000_WLAN_GET_SCAN_RESULT           = 0x437,  /**< Failed calling 'wlan_ioctl_get_scan_results' */
+    ERROR_CC3000_NETAPP_MACADDRESS_CONFIG       = 0x441,  /**< Failed calling 'netapp_config_mac_adrress' */
+    ERROR_CC3000_NETAPP_GETHOSTBYNAMEFAILED     = 0x442,  /**< Failed calling 'gethostbyname' */
+    ERROR_CC3000_NETAPP_IPCONFIG                = 0x443,  /**< Failed calling 'netapp_ipconfig' */
+    ERROR_CC3000_NETAPP_PING                    = 0x444,  /**< Failed calling 'netapp_ping_send' */
+    ERROR_CC3000_NETAPP_PING_MISSINGEVENT       = 0x445,  /**< No ping response was received in the async event handler */
+    ERROR_CC3000_SOCKET_CREATE                  = 0x451,  /**< Error creating a socket */
+    ERROR_CC3000_SOCKET_BIND                    = 0x452,  /**< Failed calling 'bind' for socket */
+    ERROR_CC3000_SOCKET_LISTEN                  = 0x453,  /**< Failed calling 'listen' for socket */
+    ERROR_CC3000_SOCKET_CLOSE                   = 0x454,  /**< Failed calling 'closesocket' */
+    ERROR_CC3000_SOCKET_RECEIVE                 = 0x455,  /**< Socket receive error */
+    ERROR_CC3000_SOCKET_SEND                    = 0x456,  /**< Failed calling 'send' for socket */
+    ERROR_CC3000_SOCKET_SEND_LENMISMATCH        = 0x457,  /**< Length mismatch during 'send' for socket (data len != send len) */
+    ERROR_CC3000_SOCKET_GETHOSTBYNAME           = 0x458,  /**< Failed calling 'gethostbyname' */
+  /*=======================================================================*/
+} err_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/fixed.h b/reform2-lpc-fw/src/fixed.h
new file mode 100644
index 0000000000000000000000000000000000000000..9e170d6dd26eec1434998f16ef26268d083fba61
--- /dev/null
+++ b/reform2-lpc-fw/src/fixed.h
@@ -0,0 +1,65 @@
+/**************************************************************************/
+/*!
+    @file     fixed.h
+*/
+/**************************************************************************/
+#ifndef _FIXED_H_
+#define _FIXED_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Fixed point math functions
+ * Source: http://forums.arm.com/index.php?/topic/14281-arm-fixed-point-vs-floating-point-cortex-m-3/ */
+
+/* Example code
+ *
+ * fixed_t a, b, c, d, add, sub, mul, div;
+ *
+ * a = fixed_make(1.0f);
+ * b = fixed_make(2.0f);
+ * c = fixed_make(3.0f);
+ * d = fixed_make(-2023.621f);
+ *
+ * printf("a=%f, b=%f, c=%f, d=%f\n",
+ *        fixed_float(a),
+ *        fixed_float(b),
+ *        fixed_float(c),
+ *        fixed_float(d));
+ *
+ * add = fixed_add(d, b);
+ * sub = fixed_sub(a, c);
+ * mul = fixed_mul(d, c);
+ * div = fixed_div(a, c);
+ *
+ * printf("d+b=%f, a-c=%f, d*c=%f, a/c=%f\n",
+ *        fixed_float(add),
+ *        fixed_float(sub),
+ *        fixed_float(mul),
+ *        fixed_float(div)); */
+
+typedef int32_t fixed_t;
+
+/* Adjust fixed_FRAC to set range
+ *
+ * fixed_FRAC=1  (Q31.1)  : min = -1.07374e+09, max =  1.07374e+09, step =  0.5
+ * fixed_FRAC=8  (Q24.8)  : min = -8.38861e+06, max =  8.38861e+06, step =  0.00390625
+ * fixed_FRAC=16 (Q16.16) : min = -32768,       max =  32768,       step =  1.52588e-05
+ * fixed_FRAC=24 (Q8.24)  : min = -128,         max =  128,         step =  5.96046e-08
+ * fixed_FRAC=31 (Q1.31)  : min =  1,           max = -1,           step = -4.65661e-10
+ */
+#define fixed_FRAC 16
+
+#define fixed_float(a) (a / (float)(1LL<<fixed_FRAC))
+#define fixed_make(a)  ((fixed_t)(a * (1LL<<fixed_FRAC)))
+#define fixed_add(a,b) (a + b)
+#define fixed_sub(a,b) (a - b)
+#define fixed_mul(a,b) ((fixed_t)(((int64_t)a * b) >> fixed_FRAC))
+#define fixed_div(a,b) ((fixed_t)(((int64_t)a << fixed_FRAC) / b))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/localisation/README.md b/reform2-lpc-fw/src/localisation/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..5476e2930db1d8c24f1eb8a2cce4babf0baab7b1
--- /dev/null
+++ b/reform2-lpc-fw/src/localisation/README.md
@@ -0,0 +1,118 @@
+# Localisation Support #
+
+While this feature is very much in development, a basic effort has been made to support some form of localisation in the code base.  
+
+Particularly in a European context, it's essential to be able to offer your products or projects in multiple languages, but localisation needs to be taken into account at the earliest part of the development cycle or it can be both error prone and time consuming to force it onto the system later.
+
+The current solution of a key-based lookup table isn't entirely satisfactory or robust, but as a basic starting point it will hopefully develop into something a bit more mature in future releases. 
+
+## How Does it Work? ##
+
+There are two enums defined in **localisation.h**:
+
+- **culture_t**: Defines the cultures supported by the system, for example **CULTURE\_EN** or **CULTURE\_FR**
+
+- **localisedTextKeys_t**: Defines the 'keys' that are used when looking up specific values
+
+Based on these two enums, there is also a simple macro defined in localisation.h named **STRING**, which provides a localised string from the current culture based on the supplied localisedTextKeys_t entry.
+
+If you execute the following code:
+
+```
+printf("%s %s", STRING(LOCALISATION_TEXT_No_ACK_received), CFG_PRINTF_NEWLINE);
+```
+
+You should get something similar to the following output (depending on the culture you've selected):
+
+```
+No ACK received
+```
+
+## Selecting a Culture ##
+
+To change the current culture, you simply need to call the **localisation\_SetCulture(culture\_t culture)** function with the appropriate culture code (as defined in culture\_t above):
+
+```
+localisation_SetCulture(CULTURE_FR);
+```
+
+The default culture is set in localisation.c via **\_localisation\_currentCulture**. To change the default culture, simply change the value assigned to this variable:
+
+```
+/* Set the default culture/language */
+static volatile culture_t _localisation_currentCulture = CULTURE_FR;
+```
+
+## Adding Strings to the Localisation Database ##
+
+There are two steps involved in adding new strings to the localisation database.
+
+**Step One: Create a new localisedTextKeys_t entry in localisation.h**
+
+Add a new key to the localisedTextKeys_t enum in localisation.h with a unique name, keeping in mind that the C standard (see 5.2.4.1) only guarantees 63 characters for unique names.
+
+**Step Two: Add entries for the new key in the appropriate 'locale\_culture.dat' file**
+
+Next open all of the locale_xx.dat files used by the system and add a new entry for your key, following the example below (for the locale_en.dat file):
+
+```
+LOCALE_EN ( LOCALISATION_TEXT_No_ACK_received, "NO ACK received" ),
+```
+
+'LOCALE\_EN' should be replaced with the appropriate macro for that specific culture and data file.
+
+> **NOTE**: Be sure to place your new value just before the **LOCALISATION\_FINAL** entry, since that value is used to indicate the end of the lookup table and calculate it's total size.
+
+## Adding a New Language/Culture##
+
+To add a new language or culture to the system, there are four main steps that you need to follow:
+
+**Step One: Add a new culture_t entry in localisation.h**
+
+You need to add a new, unique entry in the culture_t enum in **localisation.h** to enable you to distinguish this culture from any other cultures existing in your firmware.  Simply add a new value in the same style as the existing entries:
+
+```
+/* Supported languages/cultures */
+typedef enum
+{
+  CULTURE_EN,
+  CULTURE_FR,
+  CULTURE_COUNT
+} culture_t;
+```
+
+> **NOTE**: The new culture code must be placed before the **CULTURE_COUNT** value, since this value is used to determine how many cultures are present in the system.
+
+**Step Two: Define a macro for this culture in localisation.c**
+
+Based on the culture code that you defined above, open the **localisation.c** file and create a new macro at the top of the file in the following format:
+
+```
+#define LOCALE_EN(key, en) [CULTURE_EN][key]=en
+#define LOCALE_FR(key, fr) [CULTURE_FR][key]=fr
+```
+
+This macro will be used to associate entries in the localisation data file we will create in step three below.
+
+**Step Three: Create a new localisation data file**
+
+Next you need to create a locale_xx.dat file that implements all the of localisation keys in localisedTextKeys_t.
+
+For convenience sake, you can simply copy and rename an existing file in one language, and then change all of the LOCALE_xx references to the macro name that you added in step two above before translating the text.
+
+> **WARNING**: Unicode characters are the default on most modern text editors, but most small embedded systems still use 8-bit ANSI encoding, and you should convert any files you edit to ANSI encoding before saving them.  Free tools such as Notepad++ are capable of doing this while preserving any supported accent or special characters.
+
+**Step Four: Reference the localisation data file in localisation.c**
+
+Once this file has been created, you need to add it to the data file list in **localisation.c** in the following format:
+
+```
+/* Make sure the language data files are in same order as culture_t! */
+const char* localised_strings[CULTURE_COUNT][LOCALISATION_FINAL+1] =
+{
+  #include "localisation/locale_en.dat"
+  #include "localisation/locale_fr.dat"
+};
+```
+
+Rebuild your code base and the new localised values should be available in your system!
diff --git a/reform2-lpc-fw/src/localisation/locale_en.dat b/reform2-lpc-fw/src/localisation/locale_en.dat
new file mode 100644
index 0000000000000000000000000000000000000000..0dfcc0d536c534acb8a16956b8258d54ef8b1809
--- /dev/null
+++ b/reform2-lpc-fw/src/localisation/locale_en.dat
@@ -0,0 +1,98 @@
+LOCALE_EN ( LOCALISATION_SYMBOL_MHZ,                                 "MHz" ),
+LOCALE_EN ( LOCALISATION_SYMBOL_SECONDS,                             "s" ),
+LOCALE_EN ( LOCALISATION_SYMBOL_KILOBYTES,                           "KB" ),
+LOCALE_EN ( LOCALISATION_DATETIME_JANUARY_FULL,                      "January" ),
+LOCALE_EN ( LOCALISATION_DATETIME_FEBRUARY_FULL,                     "February" ),
+LOCALE_EN ( LOCALISATION_DATETIME_MARCH_FULL,                        "March" ),
+LOCALE_EN ( LOCALISATION_DATETIME_APRIL_FULL,                        "April" ),
+LOCALE_EN ( LOCALISATION_DATETIME_MAY_FULL,                          "May" ),
+LOCALE_EN ( LOCALISATION_DATETIME_JUNE_FULL,                         "June" ),
+LOCALE_EN ( LOCALISATION_DATETIME_JULY_FULL,                         "July" ),
+LOCALE_EN ( LOCALISATION_DATETIME_AUGUST_FULL,                       "August" ),
+LOCALE_EN ( LOCALISATION_DATETIME_SEPTEMBER_FULL,                    "September" ),
+LOCALE_EN ( LOCALISATION_DATETIME_OCTOBER_FULL,                      "October" ),
+LOCALE_EN ( LOCALISATION_DATETIME_NOVEMBER_FULL,                     "November" ),
+LOCALE_EN ( LOCALISATION_DATETIME_DECEMBER_FULL,                     "December" ),
+LOCALE_EN ( LOCALISATION_DATETIME_JANUARY_SHORT,                     "Jan" ),
+LOCALE_EN ( LOCALISATION_DATETIME_FEBRUARY_SHORT,                    "Feb" ),
+LOCALE_EN ( LOCALISATION_DATETIME_MARCH_SHORT,                       "Mar" ),
+LOCALE_EN ( LOCALISATION_DATETIME_APRIL_SHORT,                       "Apr" ),
+LOCALE_EN ( LOCALISATION_DATETIME_MAY_SHORT,                         "May" ),
+LOCALE_EN ( LOCALISATION_DATETIME_JUNE_SHORT,                        "Jun" ),
+LOCALE_EN ( LOCALISATION_DATETIME_JULY_SHORT,                        "Jul" ),
+LOCALE_EN ( LOCALISATION_DATETIME_AUGUST_SHORT,                      "Aug" ),
+LOCALE_EN ( LOCALISATION_DATETIME_SEPTEMBER_SHORT,                   "Sep" ),
+LOCALE_EN ( LOCALISATION_DATETIME_OCTOBER_SHORT,                     "Oct" ),
+LOCALE_EN ( LOCALISATION_DATETIME_NOVEMBER_SHORT,                    "Nov" ),
+LOCALE_EN ( LOCALISATION_DATETIME_DECEMBER_SHORT,                    "Dec" ),
+LOCALE_EN ( LOCALISATION_TEXT_This_command_has_no_parameters,        "This command has no parameters" ),
+LOCALE_EN ( LOCALISATION_TEXT_SD_init_failed,                        "SD init failed" ),
+LOCALE_EN ( LOCALISATION_TEXT_No_SD_card,                            "No SD card" ),
+LOCALE_EN ( LOCALISATION_TEXT_Failed_to_mount_partition,             "Failed to mount partition" ),
+LOCALE_EN ( LOCALISATION_TEXT_Failed_to_open,                        "Failed to open" ),
+LOCALE_EN ( LOCALISATION_TEXT_Contents_of,                           "Contents of" ),
+LOCALE_EN ( LOCALISATION_TEXT_Filename,                              "Filename" ),
+LOCALE_EN ( LOCALISATION_TEXT_Size,                                  "Size" ),
+LOCALE_EN ( LOCALISATION_TEXT_Bytes,                                 "Bytes" ),
+LOCALE_EN ( LOCALISATION_TEXT_bytes,                                 "bytes" ),
+LOCALE_EN ( LOCALISATION_TEXT_Folder_Size_COLON_SPACE,               "Folder Size: " ),
+LOCALE_EN ( LOCALISATION_TEXT_Disk_Size_COLON_SPACE,                 "Disk Size: " ),
+LOCALE_EN ( LOCALISATION_TEXT_Space_Available_COLON_SPACE,           "Space Available: " ),
+LOCALE_EN ( LOCALISATION_TEXT_Firmware,                              "Firmware" ),
+LOCALE_EN ( LOCALISATION_TEXT_MCU,                                   "MCU" ),
+LOCALE_EN ( LOCALISATION_TEXT_Language,                              "Language" ),
+LOCALE_EN ( LOCALISATION_TEXT_System_Clock,                          "System Clock" ),
+LOCALE_EN ( LOCALISATION_TEXT_System_Uptime,                         "System Uptime" ),
+LOCALE_EN ( LOCALISATION_TEXT_RF_Transceiver,                        "RF Transceiver" ),
+LOCALE_EN ( LOCALISATION_TEXT_RF_Receive_Mode,                       "RF Receive Mode" ),
+LOCALE_EN ( LOCALISATION_TEXT_Normal,                                "Normal" ),
+LOCALE_EN ( LOCALISATION_TEXT_Promiscuous,                           "Promiscuous" ),
+LOCALE_EN ( LOCALISATION_TEST_802154_PAN_ID,                         "802.15.4 PAN ID" ),
+LOCALE_EN ( LOCALISATION_TEXT_802154_Node_Address,                   "802.15.4 Node Address" ),
+LOCALE_EN ( LOCALISATION_TEXT_802154_Channel,                        "802.15.4 Channel" ),
+LOCALE_EN ( LOCALISATION_TEXT_CLI_Max_Command_Size,                  "CLI Max Command Size" ),
+LOCALE_EN ( LOCALISATION_TEXT_CLI_IRQ_Enabled,                       "CLI IRQ Enabled" ),
+LOCALE_EN ( LOCALISATION_TEXT_CLI_IRQ_Location,                      "CLI IRQ Location" ),
+LOCALE_EN ( LOCALISATION_TEXT_True,                                  "True" ),
+LOCALE_EN ( LOCALISATION_TEXT_False,                                 "False" ),
+LOCALE_EN ( LOCALISATION_TEXT_UART_Baud_Rate,                        "UART Baud Rate" ),
+LOCALE_EN ( LOCALISATION_TEXT_SD_Card_Present,                       "SD Card Present" ),
+LOCALE_EN ( LOCALISATION_TEXT_FAT_File_System,                       "FAT File System" ),
+LOCALE_EN ( LOCALISATION_TEXT_Read_Only,                             "Read Only" ),
+LOCALE_EN ( LOCALISATION_TEXT_Read_FORWARDSLASH_Write,               "Read/Write" ),
+LOCALE_EN ( LOCALISATION_TEXT_LCD_Width,                             "LCD Width" ),
+LOCALE_EN ( LOCALISATION_TEXT_LCD_Height,                            "LCD Height" ),
+LOCALE_EN ( LOCALISATION_TEXT_LCD_Controller_ID,                     "LCD Controller ID" ),
+LOCALE_EN ( LOCALISATION_TEXT_LCD_Small_Fonts,                       "LCD Small Fonts" ),
+LOCALE_EN ( LOCALISATION_TEXT_LCD_AA_Fonts,                          "LCD AA Fonts" ),
+LOCALE_EN ( LOCALISATION_TEXT_Touch_Screen,                          "Touch Screen" ),
+LOCALE_EN ( LOCALISATION_TEXT_Touch_Screen_Threshold,                "Touch Screen Threshold" ),
+LOCALE_EN ( LOCALISATION_TEXT_LED_Location,                          "LED Location" ),
+LOCALE_EN ( LOCALISATION_TEXT_Too_few_arguments,                     "Too few arguments" ),
+LOCALE_EN ( LOCALISATION_TEXT_Expected,                              "Expected" ),
+LOCALE_EN ( LOCALISATION_TEXT_for_more_information,                  "for more information" ),
+LOCALE_EN ( LOCALISATION_TEXT_Too_many_arguments,                    "Too many arguments" ),
+LOCALE_EN ( LOCALISATION_TEXT_Maximum,                               "Maximum" ),
+LOCALE_EN ( LOCALISATION_TEXT_Command_Not_Recognized,                "Command Not Recognised" ),
+LOCALE_EN ( LOCALISATION_TEXT_Type_QUESTION_for_a_list_of,           "Type '?' for a list of all available commands" ),
+LOCALE_EN ( LOCALISATION_TEXT_Command,                               "Command" ),
+LOCALE_EN ( LOCALISATION_TEXT_Description,                           "Description" ),
+LOCALE_EN ( LOCALISATION_TEXT_Command_parameters_can_be_seen,        "Command parameters can be seen by entering: <command-name> ?" ),
+LOCALE_EN ( LOCALISATION_TEXT_Scanning_I2C_bus_for_devices,          "Scanning I2C bus for devices" ),
+LOCALE_EN ( LOCALISATION_TEXT_All_addresses_are_in_7bit_L1,          "All addresses are in 7-bit format and are not" ),
+LOCALE_EN ( LOCALISATION_TEXT_All_addresses_are_in_7bit_L2,          "shifted to include the read bit." ),
+LOCALE_EN ( LOCALISATION_TEXT_No_response_on_the_I2C_bus,            "No response on the I2C bus. Check address/connections" ),
+LOCALE_EN ( LOCALISATION_TEXT_Malformed_Number,                      "Malformed number. Must be decimal number or hex value preceeded by '0x'" ),
+LOCALE_EN ( LOCALISATION_TEXT_Error,                                 "Error" ),
+LOCALE_EN ( LOCALISATION_TEXT_Invalid_I2C_Address,                   "ADDR must be between 0x03 and 0x78" ),
+LOCALE_EN ( LOCALISATION_TEXT_len_must_be_less_than_equal,           "'len' must be <=" ),
+LOCALE_EN ( LOCALISATION_TEXT_No_ACK_received,                       "No ACK received" ),
+LOCALE_EN ( LOCALISATION_TEXT_Timeout,                               "Timeout"  ),
+LOCALE_EN ( LOCALISATION_TEXT_Unknown_Error,                         "Unknown Error" ),
+LOCALE_EN ( LOCALISATION_TEXT_Too_large_for_I2C_buffer,              "Too large for I2C buffer" ),
+LOCALE_EN ( LOCALISATION_TEXT_Invalid_argument,                      "Invalid argument" ),
+LOCALE_EN ( LOCALISATION_TEXT_OK,                                    "OK" ),
+LOCALE_EN ( LOCALISATION_TEXT_EEPROM_Size_COLON_SPACE,               "EEPROM Size: " ),
+LOCALE_EN ( LOCALISATION_TEXT_Serial_Number,                         "Serial Number" ),
+LOCALE_EN ( LOCALISATION_TEXT_Code_Base_COLON_SPACE,                 "Code Base: " ),
+LOCALE_EN ( LOCALISATION_FINAL,                                      NULL ),
diff --git a/reform2-lpc-fw/src/localisation/locale_fr.dat b/reform2-lpc-fw/src/localisation/locale_fr.dat
new file mode 100644
index 0000000000000000000000000000000000000000..d689ffab970d107e728f10a18a988488bb82d61b
--- /dev/null
+++ b/reform2-lpc-fw/src/localisation/locale_fr.dat
@@ -0,0 +1,98 @@
+LOCALE_FR ( LOCALISATION_SYMBOL_MHZ,                                 "MHz" ),                                    // MHz
+LOCALE_FR ( LOCALISATION_SYMBOL_SECONDS,                             "s" ),                                      // s
+LOCALE_FR ( LOCALISATION_SYMBOL_KILOBYTES,                           "Ko" ),                                     // KB
+LOCALE_FR ( LOCALISATION_DATETIME_JANUARY_FULL,                      "janvier" ),
+LOCALE_FR ( LOCALISATION_DATETIME_FEBRUARY_FULL,                     "f�vrier" ),
+LOCALE_FR ( LOCALISATION_DATETIME_MARCH_FULL,                        "mars" ),
+LOCALE_FR ( LOCALISATION_DATETIME_APRIL_FULL,                        "avril" ),
+LOCALE_FR ( LOCALISATION_DATETIME_MAY_FULL,                          "mai" ),
+LOCALE_FR ( LOCALISATION_DATETIME_JUNE_FULL,                         "juin" ),
+LOCALE_FR ( LOCALISATION_DATETIME_JULY_FULL,                         "juillet" ),
+LOCALE_FR ( LOCALISATION_DATETIME_AUGUST_FULL,                       "ao�t" ),
+LOCALE_FR ( LOCALISATION_DATETIME_SEPTEMBER_FULL,                    "septembre" ),
+LOCALE_FR ( LOCALISATION_DATETIME_OCTOBER_FULL,                      "octobre" ),
+LOCALE_FR ( LOCALISATION_DATETIME_NOVEMBER_FULL,                     "novembre" ),
+LOCALE_FR ( LOCALISATION_DATETIME_DECEMBER_FULL,                     "d�cembre" ),
+LOCALE_FR ( LOCALISATION_DATETIME_JANUARY_SHORT,                     "jan" ),
+LOCALE_FR ( LOCALISATION_DATETIME_FEBRUARY_SHORT,                    "f�v" ),
+LOCALE_FR ( LOCALISATION_DATETIME_MARCH_SHORT,                       "mar" ),
+LOCALE_FR ( LOCALISATION_DATETIME_APRIL_SHORT,                       "avr" ),
+LOCALE_FR ( LOCALISATION_DATETIME_MAY_SHORT,                         "mai" ),
+LOCALE_FR ( LOCALISATION_DATETIME_JUNE_SHORT,                        "jun" ),
+LOCALE_FR ( LOCALISATION_DATETIME_JULY_SHORT,                        "jul" ),
+LOCALE_FR ( LOCALISATION_DATETIME_AUGUST_SHORT,                      "aou" ),
+LOCALE_FR ( LOCALISATION_DATETIME_SEPTEMBER_SHORT,                   "sep" ),
+LOCALE_FR ( LOCALISATION_DATETIME_OCTOBER_SHORT,                     "oct" ),
+LOCALE_FR ( LOCALISATION_DATETIME_NOVEMBER_SHORT,                    "nov" ),
+LOCALE_FR ( LOCALISATION_DATETIME_DECEMBER_SHORT,                    "d�c" ),
+LOCALE_FR ( LOCALISATION_TEXT_This_command_has_no_parameters,        "Cette commande n'a pas de param�tres" ),   // This command has no parameters
+LOCALE_FR ( LOCALISATION_TEXT_SD_init_failed,                        "Initialisation a �chou�" ),                // SD init failed
+LOCALE_FR ( LOCALISATION_TEXT_No_SD_card,                            "Carte SD non trouv�" ),                    // No SD card
+LOCALE_FR ( LOCALISATION_TEXT_Failed_to_mount_partition,             "Impossible de monter la partition" ),      // Failed to mount partition
+LOCALE_FR ( LOCALISATION_TEXT_Failed_to_open,                        "Impossible d'ouvrir" ),                    // Failed to open
+LOCALE_FR ( LOCALISATION_TEXT_Contents_of,                           "contenu de" ),                             // Contents of
+LOCALE_FR ( LOCALISATION_TEXT_Filename,                              "Nom du fichier" ),                         // Filename
+LOCALE_FR ( LOCALISATION_TEXT_Size,                                  "Taille" ),                                 // Size
+LOCALE_FR ( LOCALISATION_TEXT_Bytes,                                 "octets" ),                                 // Bytes
+LOCALE_FR ( LOCALISATION_TEXT_bytes,                                 "octets" ),                                 // bytes
+LOCALE_FR ( LOCALISATION_TEXT_Folder_Size_COLON_SPACE,               "Taille du dossier : " ),                   // Folder size:
+LOCALE_FR ( LOCALISATION_TEXT_Disk_Size_COLON_SPACE,                 "Taille du disque : " ),                    // Disk size:
+LOCALE_FR ( LOCALISATION_TEXT_Space_Available_COLON_SPACE,           "Espace disponible : " ),                   // Space available:
+LOCALE_FR ( LOCALISATION_TEXT_Firmware,                              "Firmware" ),                               // Firmware
+LOCALE_FR ( LOCALISATION_TEXT_MCU,                                   "MCU" ),                                    // MCU
+LOCALE_FR ( LOCALISATION_TEXT_Language,                              "Langue" ),                                 // Language
+LOCALE_FR ( LOCALISATION_TEXT_System_Clock,                          "Fr�quence du processeur" ),                // System Clock
+LOCALE_FR ( LOCALISATION_TEXT_System_Uptime,                         "Le temps de mise en route" ),              // System Uptime
+LOCALE_FR ( LOCALISATION_TEXT_RF_Transceiver,                        "Radio: Emetteur-r�cepteur" ),              // RF Transceiver
+LOCALE_FR ( LOCALISATION_TEXT_RF_Receive_Mode,                       "Radio: Mode de r�ception" ),               // RF Receive Mode
+LOCALE_FR ( LOCALISATION_TEXT_Normal,                                "Normal" ),                                 // Normal
+LOCALE_FR ( LOCALISATION_TEXT_Promiscuous,                           "Promiscuous" ),                            // Promiscuous
+LOCALE_FR ( LOCALISATION_TEST_802154_PAN_ID,                         "802.15.4: PAN ID" ),                       // 802.15.4 PAN ID
+LOCALE_FR ( LOCALISATION_TEXT_802154_Node_Address,                   "802.15.4: Adresse noeud" ),                // 802.15.4 Node Address
+LOCALE_FR ( LOCALISATION_TEXT_802154_Channel,                        "802.15.4: Canal" ),                        // 802.15.4 Channel
+LOCALE_FR ( LOCALISATION_TEXT_CLI_Max_Command_Size,                  "CLI: Commande maximum" ),                  // CLI Maximum Command Size
+LOCALE_FR ( LOCALISATION_TEXT_CLI_IRQ_Enabled,                       "CLI: IRQ activ�" ),                        // CLI IRQ Enabled
+LOCALE_FR ( LOCALISATION_TEXT_CLI_IRQ_Location,                      "CLI: Emplacement IRQ" ),                   // CLI IRQ Location
+LOCALE_FR ( LOCALISATION_TEXT_True,                                  "Vrai" ),                                   // True
+LOCALE_FR ( LOCALISATION_TEXT_False,                                 "Faux" ),                                   // False
+LOCALE_FR ( LOCALISATION_TEXT_UART_Baud_Rate,                        "Vitesse UART" ),                           // UART Baud Rate
+LOCALE_FR ( LOCALISATION_TEXT_SD_Card_Present,                       "Carte SD trouv�" ),                        // SD Card Present
+LOCALE_FR ( LOCALISATION_TEXT_FAT_File_System,                       "Syst�me de fichiers" ),                    // FAT File System
+LOCALE_FR ( LOCALISATION_TEXT_Read_Only,                             "Lecture seule" ),                          // Read Only
+LOCALE_FR ( LOCALISATION_TEXT_Read_FORWARDSLASH_Write,               "Lecture / Ecriture" ),                     // Read/Write
+LOCALE_FR ( LOCALISATION_TEXT_LCD_Width,                             "Largeur LCD" ),                            // LCD Width
+LOCALE_FR ( LOCALISATION_TEXT_LCD_Height,                            "Hauteur LCD" ),                            // LCD Height
+LOCALE_FR ( LOCALISATION_TEXT_LCD_Controller_ID,                     "ID Contr�leur LCD" ),                      // LCD Controller ID
+LOCALE_FR ( LOCALISATION_TEXT_LCD_Small_Fonts,                       "Polices petites" ),                        // LCD Small Fonts
+LOCALE_FR ( LOCALISATION_TEXT_LCD_AA_Fonts,                          "Polices anti-alias�es" ),                  // LCD AA Fonts
+LOCALE_FR ( LOCALISATION_TEXT_Touch_Screen,                          "Ecran tactile" ),                          // Touch Screen
+LOCALE_FR ( LOCALISATION_TEXT_Touch_Screen_Threshold,                "Seuil de l'�cran tactile" ),               // Touch Screen Threshold
+LOCALE_FR ( LOCALISATION_TEXT_LED_Location,                          "Emplacement LED" ),                        // LED Location
+LOCALE_FR ( LOCALISATION_TEXT_Too_few_arguments,                     "Pas assez de param�tres" ),                // Too few arguments
+LOCALE_FR ( LOCALISATION_TEXT_Expected,                              "Attendu" ),                                // Expected
+LOCALE_FR ( LOCALISATION_TEXT_for_more_information,                  "pour plus d'informations" ),               // for more information
+LOCALE_FR ( LOCALISATION_TEXT_Too_many_arguments,                    "Trop de param�tres" ),                     // Too many arguments
+LOCALE_FR ( LOCALISATION_TEXT_Maximum,                               "Maximum" ),                                // Maximum
+LOCALE_FR ( LOCALISATION_TEXT_Command_Not_Recognized,                "Commande non reconnue" ),                  // Command Not Recognised
+LOCALE_FR ( LOCALISATION_TEXT_Type_QUESTION_for_a_list_of,           "Tapez '?' pour une liste de toutes les commandes disponibles" ),         // Type '?' for a list of all available commands
+LOCALE_FR ( LOCALISATION_TEXT_Command,                               "Commande" ),                               // Command
+LOCALE_FR ( LOCALISATION_TEXT_Description,                           "Description" ),                            // Description
+LOCALE_FR ( LOCALISATION_TEXT_Command_parameters_can_be_seen,        "Les param�tres de commande peuvent �tre vu en entrant: <commande> ?" ),  // Command parameters can be seen by entering: <command-name> ?
+LOCALE_FR ( LOCALISATION_TEXT_Scanning_I2C_bus_for_devices,          "Recherche sur le bus I2C pour les appareils" ),                          // Scanning I2C bus for devices
+LOCALE_FR ( LOCALISATION_TEXT_All_addresses_are_in_7bit_L1,          "Toutes les adresses sont dans le format 7-bit et ne" ),                  // All addresses are in 7-bit format and are not
+LOCALE_FR ( LOCALISATION_TEXT_All_addresses_are_in_7bit_L2,          "sont pas d�cal� d'inclure le bit de lecture." ),                         // shifted to include the read bit.
+LOCALE_FR ( LOCALISATION_TEXT_No_response_on_the_I2C_bus,            "Aucune r�ponse sur le bus I2C. V�rifiez l'adresse / connexions" ),       // No response on the I2C bus. Check address/connections
+LOCALE_FR ( LOCALISATION_TEXT_Malformed_Number,                      "Num�ro malform�." ),                       // Malformed number. Must be decimal number or hex value preceeded by '0x'
+LOCALE_FR ( LOCALISATION_TEXT_Error,                                 "Erreur" ),                                 // Error
+LOCALE_FR ( LOCALISATION_TEXT_Invalid_I2C_Address,                   "ADDR must be between 0x03 and 0x78" ),
+LOCALE_FR ( LOCALISATION_TEXT_len_must_be_less_than_equal,           "'len' must be <=" ),
+LOCALE_FR ( LOCALISATION_TEXT_No_ACK_received,                       "No ACK received" ),
+LOCALE_FR ( LOCALISATION_TEXT_Timeout,                               "Timeout"  ),
+LOCALE_FR ( LOCALISATION_TEXT_Unknown_Error,                         "Unknown Error" ),
+LOCALE_FR ( LOCALISATION_TEXT_Too_large_for_I2C_buffer,              "Too large for I2C buffer" ),
+LOCALE_FR ( LOCALISATION_TEXT_Invalid_argument,                      "Invalid argument" ),
+LOCALE_FR ( LOCALISATION_TEXT_OK,                                    "OK" ),
+LOCALE_FR ( LOCALISATION_TEXT_EEPROM_Size_COLON_SPACE,               "Taille du EEPROM : " ),
+LOCALE_FR ( LOCALISATION_TEXT_Serial_Number,                         "Serial Number" ),
+LOCALE_FR ( LOCALISATION_TEXT_Code_Base_COLON_SPACE,                 "Code Base: " ),
+LOCALE_FR ( LOCALISATION_FINAL,                                      NULL ),
diff --git a/reform2-lpc-fw/src/localisation/localisation.c b/reform2-lpc-fw/src/localisation/localisation.c
new file mode 100644
index 0000000000000000000000000000000000000000..132876d4fea36a1782204d7b6b59e869c27ac457
--- /dev/null
+++ b/reform2-lpc-fw/src/localisation/localisation.c
@@ -0,0 +1,76 @@
+/**************************************************************************/
+/*!
+    @file     localisation.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section DESCRIPTION
+
+    Common, board-specific files for the AT86RF2xx wireless boards
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+#include "localisation.h"
+
+#define LOCALE_EN(key, en) [CULTURE_EN][key]=en
+#define LOCALE_FR(key, fr) [CULTURE_FR][key]=fr
+
+/* Set the default culture/language */
+static volatile culture_t _localisation_currentCulture = CULTURE_EN;
+
+/* Make sure the language data files are in same order as culture_t! */
+const char* localised_strings[CULTURE_COUNT][LOCALISATION_FINAL+1] =
+{
+  #include "localisation/locale_en.dat"
+  #include "localisation/locale_fr.dat"
+};
+
+/**************************************************************************/
+/*!
+    @brief Returns the localised string corresponding to the specified
+           'key' value.
+*/
+/**************************************************************************/
+char* localisation_GetString(localisedTextKeys_t key)
+{
+  return (char*)localised_strings[_localisation_currentCulture][key];
+}
+
+/**************************************************************************/
+/*!
+    @brief Sets the current language, which will determine which lookup
+           table is used when retrieving text, etc.
+*/
+/**************************************************************************/
+void localisation_SetCulture(culture_t culture)
+{
+  _localisation_currentCulture = culture;
+}
diff --git a/reform2-lpc-fw/src/localisation/localisation.h b/reform2-lpc-fw/src/localisation/localisation.h
new file mode 100644
index 0000000000000000000000000000000000000000..26de33ae6298d9f25ed620c69740bcb6ad906181
--- /dev/null
+++ b/reform2-lpc-fw/src/localisation/localisation.h
@@ -0,0 +1,180 @@
+/**************************************************************************/
+/*!
+    @defgroup Localisation Localisation
+
+    @brief    Basic localisation system to provide localised strings and
+                  values.
+*/
+/**************************************************************************/
+
+/**************************************************************************/
+/*!
+    @file     localisation.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @ingroup  Localisation
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _LOCALISATION_H_
+#define _LOCALISATION_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Supported languages/cultures */
+typedef enum
+{
+  CULTURE_EN,
+  CULTURE_FR,
+  CULTURE_COUNT
+} culture_t;
+
+/* Localised text index keys
+
+   Note: The C standard (5.2.4.1) only guarantees 63 characters for names
+   These names break the cardinal rule of constants in all caps, but it
+   seems better to indicate case-intent in the constant to avoid issues
+   with localization later                                                */
+typedef enum
+{
+  LOCALISATION_SYMBOL_MHZ,                                   // "MHz"
+  LOCALISATION_SYMBOL_SECONDS,                               // "s"
+  LOCALISATION_SYMBOL_KILOBYTES,                             // "KB"
+  LOCALISATION_DATETIME_JANUARY_FULL,                        // "January"
+  LOCALISATION_DATETIME_FEBRUARY_FULL,                       // "February"
+  LOCALISATION_DATETIME_MARCH_FULL,                          // "March"
+  LOCALISATION_DATETIME_APRIL_FULL,                          // "April"
+  LOCALISATION_DATETIME_MAY_FULL,                            // "May"
+  LOCALISATION_DATETIME_JUNE_FULL,                           // "June"
+  LOCALISATION_DATETIME_JULY_FULL,                           // "July"
+  LOCALISATION_DATETIME_AUGUST_FULL,                         // "August"
+  LOCALISATION_DATETIME_SEPTEMBER_FULL,                      // "September"
+  LOCALISATION_DATETIME_OCTOBER_FULL,                        // "October"
+  LOCALISATION_DATETIME_NOVEMBER_FULL,                       // "November"
+  LOCALISATION_DATETIME_DECEMBER_FULL,                       // "December"
+  LOCALISATION_DATETIME_JANUARY_SHORT,                       // "Jan"
+  LOCALISATION_DATETIME_FEBRUARY_SHORT,                      // "Feb"
+  LOCALISATION_DATETIME_MARCH_SHORT,                         // "Mar"
+  LOCALISATION_DATETIME_APRIL_SHORT,                         // "Apr"
+  LOCALISATION_DATETIME_MAY_SHORT,                           // "May"
+  LOCALISATION_DATETIME_JUNE_SHORT,                          // "Jun"
+  LOCALISATION_DATETIME_JULY_SHORT,                          // "Jul"
+  LOCALISATION_DATETIME_AUGUST_SHORT,                        // "Aug"
+  LOCALISATION_DATETIME_SEPTEMBER_SHORT,                     // "Sep"
+  LOCALISATION_DATETIME_OCTOBER_SHORT,                       // "Oct"
+  LOCALISATION_DATETIME_NOVEMBER_SHORT,                      // "Nov"
+  LOCALISATION_DATETIME_DECEMBER_SHORT,                      // "Dec"
+  LOCALISATION_TEXT_This_command_has_no_parameters,          // "This command has no parameters"
+  LOCALISATION_TEXT_SD_init_failed,                          // "SD init failed"
+  LOCALISATION_TEXT_No_SD_card,                              // "No SD card"
+  LOCALISATION_TEXT_Failed_to_mount_partition,               // "Failed to mount partition"
+  LOCALISATION_TEXT_Failed_to_open,                          // "Failed to open"
+  LOCALISATION_TEXT_Contents_of,                             // "Contents of"
+  LOCALISATION_TEXT_Filename,                                // "Filename"
+  LOCALISATION_TEXT_Size,                                    // "Size"
+  LOCALISATION_TEXT_Bytes,                                   // "Bytes"
+  LOCALISATION_TEXT_bytes,                                   // "bytes"
+  LOCALISATION_TEXT_Folder_Size_COLON_SPACE,                 // "Folder Size: "
+  LOCALISATION_TEXT_Disk_Size_COLON_SPACE,                   // "Disk Size: "
+  LOCALISATION_TEXT_Space_Available_COLON_SPACE,             // "Space Available: "
+  LOCALISATION_TEXT_Firmware,                                // "Firmware"
+  LOCALISATION_TEXT_MCU,                                     // "MCU"
+  LOCALISATION_TEXT_Language,                                // "Language"
+  LOCALISATION_TEXT_System_Clock,                            // "System Clock"
+  LOCALISATION_TEXT_System_Uptime,                           // "System Uptime"
+  LOCALISATION_TEXT_RF_Transceiver,                          // "RF Transceiver"
+  LOCALISATION_TEXT_RF_Receive_Mode,                         // "RF Receive Mode"
+  LOCALISATION_TEXT_Normal,                                  // "Normal"
+  LOCALISATION_TEXT_Promiscuous,                             // "Promiscuous"
+  LOCALISATION_TEST_802154_PAN_ID,                           // "802.15.4 PAN ID"
+  LOCALISATION_TEXT_802154_Node_Address,                     // "802.15.4 Node Address"
+  LOCALISATION_TEXT_802154_Channel,                          // "802.15.4 Channel"
+  LOCALISATION_TEXT_CLI_Max_Command_Size,                    // "CLI Max Command Size"
+  LOCALISATION_TEXT_CLI_IRQ_Enabled,                         // "CLI IRQ Enabled"
+  LOCALISATION_TEXT_CLI_IRQ_Location,                        // "CLI IRQ Location"
+  LOCALISATION_TEXT_True,                                    // "True"
+  LOCALISATION_TEXT_False,                                   // "False"
+  LOCALISATION_TEXT_UART_Baud_Rate,                          // "UART Baud Rate"
+  LOCALISATION_TEXT_SD_Card_Present,                         // "SD Card Present"
+  LOCALISATION_TEXT_FAT_File_System,                         // "FAT File System"
+  LOCALISATION_TEXT_Read_Only,                               // "Read Only"
+  LOCALISATION_TEXT_Read_FORWARDSLASH_Write,                 // "Read/Write"
+  LOCALISATION_TEXT_LCD_Width,                               // "LCD Width"
+  LOCALISATION_TEXT_LCD_Height,                              // "LCD Height"
+  LOCALISATION_TEXT_LCD_Controller_ID,                       // "LCD Controller ID"
+  LOCALISATION_TEXT_LCD_Small_Fonts,                         // "LCD Small Fonts"
+  LOCALISATION_TEXT_LCD_AA_Fonts,                            // "LCD AA Fonts"
+  LOCALISATION_TEXT_Touch_Screen,                            // "Touch Screen"
+  LOCALISATION_TEXT_Touch_Screen_Threshold,                  // "Touch Screen Threshold"
+  LOCALISATION_TEXT_LED_Location,                            // "LED Location"
+  LOCALISATION_TEXT_Too_few_arguments,                       // "Too few arguments"
+  LOCALISATION_TEXT_Expected,                                // "Expected"
+  LOCALISATION_TEXT_for_more_information,                    // "for more information"
+  LOCALISATION_TEXT_Too_many_arguments,                      // "Too many arguments"
+  LOCALISATION_TEXT_Maximum,                                 // "Maximum"
+  LOCALISATION_TEXT_Command_Not_Recognized,                  // "Command Not Recognized"
+  LOCALISATION_TEXT_Type_QUESTION_for_a_list_of,             // "Type '?' for a list of all available commands"
+  LOCALISATION_TEXT_Command,                                 // "Command"
+  LOCALISATION_TEXT_Description,                             // "Description"
+  LOCALISATION_TEXT_Command_parameters_can_be_seen,          // "Command parameters can be seen by entering: <command-name> ?"
+  LOCALISATION_TEXT_Scanning_I2C_bus_for_devices,            // "Scanning I2C bus for devices"
+  LOCALISATION_TEXT_All_addresses_are_in_7bit_L1,            // "All addresses are in 7-bit format and are not"
+  LOCALISATION_TEXT_All_addresses_are_in_7bit_L2,            // "shifted to include the read bit."
+  LOCALISATION_TEXT_No_response_on_the_I2C_bus,              // "No response on the I2C bus. Check address/connections"
+  LOCALISATION_TEXT_Malformed_Number,                        // "Malformed number. Must be decimal number or hex value preceeded by '0x'"
+  LOCALISATION_TEXT_Error,                                   // "Error"
+  LOCALISATION_TEXT_Invalid_I2C_Address,                     // "ADDR must be between 0x03 and 0x78"
+  LOCALISATION_TEXT_len_must_be_less_than_equal,             // "'len' must be <="
+  LOCALISATION_TEXT_No_ACK_received,                         // "No ACK received"
+  LOCALISATION_TEXT_Timeout,                                 // "Timeout"
+  LOCALISATION_TEXT_Unknown_Error,                           // "Unknown Error"
+  LOCALISATION_TEXT_Too_large_for_I2C_buffer,                // "Too large for I2C buffer"
+  LOCALISATION_TEXT_Invalid_argument,                        // "Invalid argument"
+  LOCALISATION_TEXT_OK,                                      // "OK"
+  LOCALISATION_TEXT_EEPROM_Size_COLON_SPACE,                 // "EEPROM Size: "
+  LOCALISATION_TEXT_Serial_Number,                           // "Serial Number: "
+  LOCALISATION_TEXT_Code_Base_COLON_SPACE,                   // "Code Base: "
+  LOCALISATION_FINAL
+} localisedTextKeys_t;
+
+char* localisation_GetString ( localisedTextKeys_t key );
+void  localisation_SetCulture ( culture_t culture );
+
+// Macros to make localisation a bit cleaner looking in code
+#define STRING(key)    localisation_GetString(key)
+
+#ifdef __cplusplus
+}
+#endif 
+
+#endif
diff --git a/reform2-lpc-fw/src/log.h b/reform2-lpc-fw/src/log.h
new file mode 100644
index 0000000000000000000000000000000000000000..2ae43b79342b3a8db499970862cc71a1332d1eb4
--- /dev/null
+++ b/reform2-lpc-fw/src/log.h
@@ -0,0 +1,114 @@
+/**************************************************************************/
+/*!
+    @file     log.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Various LOG macros to simplify data logging when debugging.
+    @ingroup  Errors
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _LOG_H_
+#define _LOG_H_
+
+#include "projectconfig.h"
+
+// #define LOG_ENABLE
+
+/*! Compiler specific macro returning a string containing the current line number */
+#define LOG_LINE __LINE__
+/*! Compiler specific macro returning a string containing the current function */
+#define LOG_FUNC __func__
+
+#ifdef LOG_ENABLE
+  #define LOG_PRINTF(...)      printf(__VA_ARGS__)
+#else
+  #define LOG_PRINTF(...)
+#endif
+
+#define LOG_MESSAGE "Log: %s: line %d: "
+
+/**************************************************************************/
+/*!
+    @brief  Inserts the specified number of tabs in the data log
+*/
+/**************************************************************************/
+#define LOG_TAB(n) \
+  do{\
+    for(uint32_t run=0; run<(n); run++)\
+      LOG_PRINTF("\t");\
+  } while(0)
+
+/**************************************************************************/
+/*!
+    @brief  Logs the specified message, including the function name an
+            the line where the function is present
+
+    @param  format  The entire 'printf' parameter set, including optional
+                    parameters if values like %s, %d are used.
+
+    @code
+    LOG("HID In report" CFG_PRINTF_NEWLINE
+        "\tStatus   = %d - %s" CFG_PRINTF_NEWLINE
+        "\tCount    = %d" CFG_PRINTF_NEWLINE
+        "\tSequence = %d",
+        in_report->Status, REPORT_STATUS_STR(in_report->Status), in_report->Count, in_report->Sequence);
+    LOG_TAB(1);
+    LOG_ARR(in_report->ReadData, 15, "%08X");
+    @endcode
+*/
+/**************************************************************************/
+#define LOG(format, ...) LOG_PRINTF(LOG_MESSAGE format "%s", LOG_FUNC, LOG_LINE, __VA_ARGS__, CFG_PRINTF_NEWLINE);
+
+/**************************************************************************/
+/*!
+    @brief  Sends the array contents to the data log
+
+    @param  array   Pointer the the array in memory
+    @param  size    Length of the array
+    @param  format  Format to use when displaying each array item via printf
+                    (ex. "%02X ", "%d", "0x%08X", etc.)
+
+    @code
+    LOG_ARR(in_report->ReadData, 15, "%08X");
+    @endcode
+*/
+/**************************************************************************/
+#define LOG_ARR(array, size, format) \
+  do{\
+    for(uint32_t run=0; run<(size); run++)\
+      LOG_PRINTF(format " ", (array)[run]);\
+    LOG_PRINTF(CFG_PRINTF_NEWLINE);\
+  } while(0)
+
+#define LOG_STR(str) LOG("%s", str)
+
+#endif
diff --git a/reform2-lpc-fw/src/printf-retarget.c b/reform2-lpc-fw/src/printf-retarget.c
new file mode 100644
index 0000000000000000000000000000000000000000..1a5c5d91f204cc957a36646e4d60e942f0b67eb3
--- /dev/null
+++ b/reform2-lpc-fw/src/printf-retarget.c
@@ -0,0 +1,129 @@
+/**************************************************************************/
+/*!
+    @file     printf-retarget.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <stdarg.h>
+
+#include "projectconfig.h"
+
+#ifdef __CROSSWORKS_ARM
+  #if defined(CFG_PRINTF_DEBUG) || defined(CFG_PRINTF_USBCDC)
+    #include <cross_studio_io.h>
+  #endif
+#endif
+
+#ifdef CFG_USB
+  #include "core/usb/usbd.h"
+#endif
+
+#ifdef CFG_PRINTF_UART
+  #include "core/uart/uart.h"
+#endif
+
+/**************************************************************************/
+/*!
+    @brief  Sends a single byte to a pre-determined peripheral (UART, etc.).
+
+    @param  c
+            Byte value to send
+*/
+/**************************************************************************/
+void __putchar(const char c)
+{
+  #if defined(CFG_USB) && defined(CFG_PRINTF_USBCDC)
+    if (usb_isConfigured())
+    {
+      while(usb_cdc_isConnected() && !usb_cdc_putc(c) ) // blocking
+      {
+        ASM("nop");
+      }
+    }
+  #endif
+
+  #ifdef CFG_PRINTF_UART
+    uartSendByte(c);
+  #endif
+
+  /* Handle PRINTF_DEBUG redirection for Crossworks for ARM */
+  #ifdef __CROSSWORKS_ARM
+    #ifdef CFG_PRINTF_DEBUG
+      #if defined CFG_MCU_FAMILY_LPC13UXX
+        /* On the M3 we can check if a debugger is connected */
+        if ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk)==CoreDebug_DHCSR_C_DEBUGEN_Msk)
+        {
+          debug_putchar(c);
+        }
+      #else
+        /* On the M0 the processor doesn't have access to CoreDebug, so this
+         * will cause problems if no debugger is connected! */
+        debug_putchar(c);
+      #endif
+    #endif
+  #endif
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sends a string to a pre-determined peripheral (UART, etc.).
+            This function is called by core/libc/stdio.c
+
+    @param  c
+            Byte value to send
+*/
+/**************************************************************************/
+int puts(const char * str)
+{
+  while(*str) __putchar(*str++);
+
+  return 0;
+}
+
+#ifdef __CC_ARM // keil
+
+struct __FILE {
+  uint32_t handle;
+};
+
+int fputc(int ch, FILE *f)
+{
+  __putchar(ch);
+  return ch;
+}
+
+void _ttywrch(int ch)
+{
+  __putchar(ch);
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/projectconfig.h b/reform2-lpc-fw/src/projectconfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..d4508b9497e7c0a9b5922ea2228ca172e904ba7a
--- /dev/null
+++ b/reform2-lpc-fw/src/projectconfig.h
@@ -0,0 +1,129 @@
+/**************************************************************************/
+/*!
+    @file     projectconfig.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @brief    Indicates which board should be used during the build process
+    @ingroup  Board/HW Abstration Layer
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, 2013 K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _PROJECTCONFIG_H_
+#define _PROJECTCONFIG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ========================================================================
+    ABOUT THIS FILE
+    -----------------------------------------------------------------------
+    This file contains global config settings that apply to any board
+    or project.
+
+    Any board-specific config settings should be placed in individual
+    config files in the 'boards/' sub-directory, and the settings will be
+    includes in any file via 'projectconfig.h'.
+   ========================================================================*/
+
+#include "sysdefs.h"
+#include "errors.h"
+#include "asserts.h"
+#include "binary.h"
+#include "localisation/localisation.h"
+
+/*=========================================================================
+    CODE BASE VERSION SETTINGS
+
+    Please do not modify this version number.  To set a version number
+    for your project or firmware, change the values in your 'boards/'
+    config file.
+    -----------------------------------------------------------------------*/
+    #define CFG_CODEBASE_VERSION_MAJOR      (0)
+    #define CFG_CODEBASE_VERSION_MINOR      (9)
+    #define CFG_CODEBASE_VERSION_REVISION   (1)
+/*=========================================================================*/
+
+
+/*=========================================================================
+    BOARD SELECTION
+
+    Because several boards use this code library with sometimes slightly
+    different pin configuration, you will need to specify which board you
+    are using by enabling one of the following definitions. The code base
+    will then try to configure itself accordingly for that board.
+
+    GNU Toolchain
+    -------------
+    If you are using make, the target board is specified in the makefile
+
+    Crossworks for ARM
+    ------------------
+    The board is selected as an additional defined in the solution
+    properties window, in the 'Common' group under 'Preprocessor Options >
+    Preprocessor Definitions'
+
+    LPCXpresso/Red Suite
+    --------------------
+    Each board has it's own 'Build Configuration', which can be accessed
+    by right-clicking on your project, and selecting the 'Build
+    Configurations > Set Active ... > BUILD_CONFIG' menu
+
+    Keil uVision
+    ------------
+    Select a board via the project 'Options' dialogue box, in the C/C++
+    tab, entering an appropriate value in the 'Define' textbox
+
+    -----------------------------------------------------------------------*/
+    #if defined(CFG_BRD_LPCXPRESSO_LPC1347)
+      #include "boards/lpcxpresso1347/board_lpcxpresso1347.h"
+    #elif defined(CFG_BRD_RF1GHZNODE)
+       #include "boards/rf1ghznode/board_rf1ghznode.h"
+    #elif defined(CFG_BRD_RF1GHZUSB)
+      #include "boards/rf1ghzusb/board_rf1ghzusb.h"
+    #elif defined (CFG_BRD_LPCNFC)
+      #include "boards/lpcnfc/board_lpcnfc.h"
+    #elif defined (CFG_BRD_LPCSTEPPER)
+      #include "boards/lpcstepper/board_lpcstepper.h"
+    #elif defined (CFG_BRD_SIMULATOR)
+      #include "boards/simulator/board_simulator.h"
+    #elif defined (CFG_BRD_REFORM2)
+      #include "boards/reform2/board_reform2.h"
+    #else
+      #error "No CFG_BRD_* has been defined"
+    #endif
+/*=========================================================================*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/protocol/commands/protocol_cmd_led.c b/reform2-lpc-fw/src/protocol/commands/protocol_cmd_led.c
new file mode 100644
index 0000000000000000000000000000000000000000..52921210b52abde3a4453921def32da29cdb926e
--- /dev/null
+++ b/reform2-lpc-fw/src/protocol/commands/protocol_cmd_led.c
@@ -0,0 +1,59 @@
+/**************************************************************************/
+/*!
+    @file     protocol_cmd_help.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_PROTOCOL
+
+#include "boards/board.h"
+#include "../protocol.h"
+
+// turn on  10 01 00 01 01
+// turn off 10 01 00 01 00
+/**************************************************************************/
+/*!
+    Enables or disables the on board LEDs via boardLED()
+*/
+/**************************************************************************/
+err_t protcmd_led(uint8_t length, uint8_t const payload[], protMsgResponse_t* mess_response)
+{
+  ASSERT( 1 == length, ERROR_INVALIDPARAMETER);
+
+  boardLED(payload[0] ? CFG_LED_ON : CFG_LED_OFF);
+
+  return ERROR_NONE;
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/protocol/commands/protocol_cmd_sysinfo.c b/reform2-lpc-fw/src/protocol/commands/protocol_cmd_sysinfo.c
new file mode 100644
index 0000000000000000000000000000000000000000..ba5404a94da45e4b9d98d175d7343d3fefa13a87
--- /dev/null
+++ b/reform2-lpc-fw/src/protocol/commands/protocol_cmd_sysinfo.c
@@ -0,0 +1,197 @@
+/**************************************************************************/
+/*!
+    @file     protocol_cmd_sysinfo.c
+    @author   K. Townsend (microBuilder.eu)
+
+    This command can be used to read system information based on a pre-
+    defined key value. For example, sending the SYSINFO command with
+    PROT_CMD_SYSINFO_KEY_EEPROMSIZE (0x0006) for the key will return the
+    size of the onboard/onchip EEPROM if any is present.
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include "projectconfig.h"
+
+#ifdef CFG_PROTOCOL
+
+#include <stdio.h>
+#include <string.h>
+#include "boards/board.h"
+#include "../protocol.h"
+#include "protocol_cmd_sysinfo.h"
+#include "core/iap/iap.h"
+
+/**************************************************************************/
+/*!
+    Returns system information for this board based on a 16-bit key
+*/
+/**************************************************************************/
+err_t protcmd_sysinfo(uint8_t length, uint8_t const payload[], protMsgResponse_t* mess_response)
+{
+  uint16_t key = payload[1] << 8 | payload[0];
+
+  /* Make sure we have a valid key */
+  ASSERT( key > PROT_CMD_SYSINFO_KEY_FIRST, ERROR_INVALIDPARAMETER);
+  ASSERT( key < PROT_CMD_SYSINFO_KEY_LAST, ERROR_INVALIDPARAMETER);
+
+  switch(key)
+  {
+    case (PROT_CMD_SYSINFO_KEY_CODEBASE_VERSION):
+    /* ====================================================================
+        PROT_CMD_SYSINFO_KEY_CODEBASE_VERSION                   KEY: 0x0001
+        -------------------------------------------------------------------
+        Returns the parent code base version ID (see projectconfig.h)
+
+        PAYLOAD:  [02 00]
+                  Optional Args       None
+        RESPONSE: Payload Length      3
+                  mess_response[4]    Major version number
+                  mess_response[5]    Minor version number
+                  mess_response[6]    Revision number
+       ====================================================================*/
+      ASSERT(length == 2, ERROR_PROT_INVALIDPAYLOAD);
+      mess_response->length = 3;
+      mess_response->payload[0] = (uint8_t)CFG_CODEBASE_VERSION_MAJOR & 0xFF;
+      mess_response->payload[1] = (uint8_t)CFG_CODEBASE_VERSION_MINOR & 0xFF;
+      mess_response->payload[2] = (uint8_t)CFG_CODEBASE_VERSION_REVISION & 0xFF;
+      break;
+
+    case (PROT_CMD_SYSINFO_KEY_FIRMWARE_VERSION):
+    /* ====================================================================
+        PROT_CMD_SYSINFO_KEY_FIRMWARE_VERSION                   Key: 0x0002
+        -------------------------------------------------------------------
+        Returns the board-specific firmware version (defined in board_*.h)
+
+        PAYLOAD:  [02 00]
+                  Optional Args       None
+        RESPONSE: Payload Length      3
+                  mess_response[4]    Major version number
+                  mess_response[5]    Minor version number
+                  mess_response[6]    Revision number
+       ====================================================================*/
+      ASSERT(length == 2, ERROR_PROT_INVALIDPAYLOAD);
+      mess_response->length = 3;
+      mess_response->payload[0] = (uint8_t)CFG_FIRMWARE_VERSION_MAJOR & 0xFF;
+      mess_response->payload[1] = (uint8_t)CFG_FIRMWARE_VERSION_MINOR & 0xFF;
+      mess_response->payload[2] = (uint8_t)CFG_FIRMWARE_VERSION_REVISION & 0xFF;
+      break;
+
+    case (PROT_CMD_SYSINFO_KEY_MCU_STRING):
+    /* ====================================================================
+        PROT_CMD_SYSINFO_KEY_MCU_STRING                         Key: 0x0003
+        -------------------------------------------------------------------
+        Returns a string describing the MCU used on the board
+
+        PAYLOAD:  [03 00]
+                  Optional Args       None
+        RESPONSE: Payload Length      variable (0..60 bytes)
+                  mess_response[4]    Start of MCU string
+       ====================================================================*/
+      ASSERT(length == 2, ERROR_PROT_INVALIDPAYLOAD);
+      #ifdef CFG_MCU_LPC11U24FBD48_401
+        mess_response->length = (uint8_t)strlen("LPC11U24FBD48/401");
+        memcpy(&mess_response->payload[0], "LPC11U24FBD48/401", strlen("LPC11U24FBD48/401"));
+      #endif
+      #ifdef CFG_MCU_LPC11U37FBD48_401
+        mess_response->length = (uint8_t)strlen("LPC11U37FBD48/401");
+        memcpy(&mess_response->payload[0], "LPC11U37FBD48/401", strlen("LPC11U37FBD48/401"));
+      #endif
+      #ifdef CFG_MCU_LPC1347FBD48
+        mess_response->length = (uint8_t)strlen("LPC1347FBD48/401");
+        memcpy(&mess_response->payload[0], "LPC1347FBD48/401", strlen("LPC1347FBD48/401"));
+      #endif
+      break;
+
+    case (PROT_CMD_SYSINFO_KEY_SERIAL_NUMBER):
+    /* ====================================================================
+        PROT_CMD_SYSINFO_KEY_SERIAL_NUMBER                      Key: 0x0004
+        -------------------------------------------------------------------
+        Returns the uniaue four word serial number of the LPC chip
+
+        PAYLOAD:  [04 00]
+                  Optional Args       None
+        RESPONSE: Payload Length      16 bytes
+                  mess_response[4]    ID 3 (uint32_t)
+                  mess_response[8]    ID 2 (uint32_t)
+                  mess_response[12]   ID 1 (uint32_t)
+                  mess_response[16]   ID 0 (uint32_t)
+       ====================================================================*/
+      ASSERT(length == 2, ERROR_PROT_INVALIDPAYLOAD);
+      mess_response->length = 16;
+      uint32_t uid[4];
+      iapReadUID(uid);
+      memcpy(&mess_response->payload[0], uid, 16);
+      break;
+
+    case (PROT_CMD_SYSINFO_KEY_CLOCKSPEED):
+    /* ====================================================================
+        PROT_CMD_SYSINFO_KEY_CLOCKSPEED                         Key: 0x0005
+        -------------------------------------------------------------------
+        Returns the core clock speed in Hz
+
+        PAYLOAD:  [05 00]
+                  Optional Args       None
+        RESPONSE: Payload Length      4 bytes
+                  mess_response[4]    Clock speed in Hz (uint32_t)
+       ====================================================================*/
+      ASSERT(length == 2, ERROR_PROT_INVALIDPAYLOAD);
+      mess_response->length = 4;
+      uint32_t speed = (uint32_t)SystemCoreClock;
+      memcpy(&mess_response->payload[4], &speed, sizeof(uint32_t));
+      break;
+
+    case (PROT_CMD_SYSINFO_KEY_EEPROMSIZE):
+    /* ====================================================================
+        PROT_CMD_SYSINFO_KEY_EEPROMSIZE                         Key: 0x0006
+        -------------------------------------------------------------------
+        Returns the size of the on-board or on-chip EEPROM, or 0 if no
+        EEPROM is available
+
+        PAYLOAD:  [06 00]
+                  Optional Args       None
+        RESPONSE: Payload Length      4 bytes
+                  mess_response[4]    EEPROM size in bytes (uint32_t)
+
+       ====================================================================*/
+      ASSERT(length == 2, ERROR_PROT_INVALIDPAYLOAD);
+      mess_response->length = 4;
+      uint32_t eepromSize = (uint32_t)CFG_EEPROM_SIZE;
+      memcpy(&mess_response->payload[0], &eepromSize, sizeof(uint32_t));
+      break;
+
+    default:
+      return ERROR_INVALIDPARAMETER;
+  }
+
+  return ERROR_NONE;
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/protocol/commands/protocol_cmd_sysinfo.h b/reform2-lpc-fw/src/protocol/commands/protocol_cmd_sysinfo.h
new file mode 100644
index 0000000000000000000000000000000000000000..8bfea7efb6f4510b19d3f442dc0c6e17e3fdef8f
--- /dev/null
+++ b/reform2-lpc-fw/src/protocol/commands/protocol_cmd_sysinfo.h
@@ -0,0 +1,67 @@
+/**************************************************************************/
+/*!
+    @file     protocol_cmd_sysinfo.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+
+#ifndef __PROTOCOL_CMD_SYSINFO_H__
+#define __PROTOCOL_CMD_SYSINFO_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**************************************************************************/
+/*!
+    SYSINFO Keys (indicates what specific system information we want)
+*/
+/**************************************************************************/
+typedef enum
+{
+  PROT_CMD_SYSINFO_KEY_FIRST                = 0x0000,
+  PROT_CMD_SYSINFO_KEY_CODEBASE_VERSION     = 0x0001,   /**< Code base version (3*U8) */
+  PROT_CMD_SYSINFO_KEY_FIRMWARE_VERSION     = 0x0002,   /**< Firmware version (3*U8) */
+  PROT_CMD_SYSINFO_KEY_MCU_STRING           = 0x0003,   /**< MCU model (string) */
+  PROT_CMD_SYSINFO_KEY_SERIAL_NUMBER        = 0x0004,   /**< Unique on-chip serial number (4*U32) */
+  PROT_CMD_SYSINFO_KEY_CLOCKSPEED           = 0x0005,   /**< Core clock speed in Hz (U32) */
+  PROT_CMD_SYSINFO_KEY_EEPROMSIZE           = 0x0006,   /**< EEPROM size in bytes (U32) */
+  PROT_CMD_SYSINFO_KEY_LAST
+} prot_cmd_sysinfo_key_t;
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* __PROTOCOL_CMD_LED_H__ */
+
+/** @} */
diff --git a/reform2-lpc-fw/src/protocol/prot_cmdtable.h b/reform2-lpc-fw/src/protocol/prot_cmdtable.h
new file mode 100644
index 0000000000000000000000000000000000000000..3fd69fb335ef98201db72d832dcbf9b99c7ece4a
--- /dev/null
+++ b/reform2-lpc-fw/src/protocol/prot_cmdtable.h
@@ -0,0 +1,73 @@
+/**************************************************************************/
+/*!
+    @file     prot_cmdtable.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+
+#ifndef _PROT_CMDTABLE_H_
+#define _PROT_CMDTABLE_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**************************************************************************/
+/*!
+    This enumeration is used to make sure that each command has a unique
+    ID, and is used to create the command lookup table enum further down
+*/
+/**************************************************************************/
+typedef enum {
+  PROT_CMDTYPE_LED      = 0x0001, /**< Enables/disables the on board LED */
+  PROT_CMDTYPE_SYSINFO  = 0x0002, /**< Gets system properties */
+  PROT_CMDTYPE_COUNT              /**< Total number of commands */
+} protCmdType_t;
+
+/**************************************************************************/
+/*
+    The command lookup table is constructed based on this macro containing
+    the command ID (as defined in protCmdType_t) and the actual callback
+    function to associate with it (in the format defined by protCmdFunc_t)
+*/
+/**************************************************************************/
+#define PROTOCOL_COMMAND_TABLE(ENTRY)            \
+    ENTRY(PROT_CMDTYPE_LED, protcmd_led)         \
+    ENTRY(PROT_CMDTYPE_SYSINFO, protcmd_sysinfo) \
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _PROT_CMDTABLE_H_ */
+
+/** @} */
diff --git a/reform2-lpc-fw/src/protocol/protocol.c b/reform2-lpc-fw/src/protocol/protocol.c
new file mode 100644
index 0000000000000000000000000000000000000000..7695b56b9bbe6603b23729977acbfb97cc989ab4
--- /dev/null
+++ b/reform2-lpc-fw/src/protocol/protocol.c
@@ -0,0 +1,436 @@
+/**************************************************************************/
+/*!
+    @file     protocol.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+
+/*  SIMPLE BINARY PROTOCOL DESCRIPTION
+    ==================================
+
+    This simple messaging protocol can be used to send and receive binary
+    messages using any binary serial bus (USB HID, USB Bulk, SPI, I2C,
+    Wireless, etc.).
+
+    The protocol is designed to be flexible and extensible, with the only
+    requirement being that individual messages are 64 bytes or smaller,
+    and that the first byte of every message is a one byte (U8) identifier
+    that indicates the format for the rest of the payload (if there is one).
+
+    IMPLEMENTATION NOTES
+    ====================
+
+    The protocol implementation must be transport mechanism agnostic, and
+    should be able to function with any binary serial bus. The original
+    design goal is a protocol that can function via USB HID, SPI Slave,
+    and I2C Slave modes, but any similar protocol should be able to be
+    added to the implementation (wireless transfers, etc.).
+
+    ENDIANNESS
+    ==========
+
+    All values larger than 8-bits are expected to be little endian, such
+    as the command IDs, and the payload contents.  Any deviation from
+    this rule should be clearly documented.
+
+    MESSAGE TYPES
+    =============
+
+    Each message is preceded by an 8-bit message identifier that indicates
+    the format and content of the rest of the message:
+
+    |-----------------------+---------+--------------------------------------|
+    | Message Type          | ID (U8) | Meaning                              |
+    |-----------------------+---------+--------------------------------------|
+    | Command               | 0x10    |                                      |
+    | Response              | 0x20    |                                      |
+    | Alert                 | 0x40    |                                      |
+    | Error                 | 0x80    |                                      |
+    |-----------------------+---------+--------------------------------------|
+
+    COMMAND MESSAGES
+    ================
+
+    Command messages (Message Type = 0x10) have the following structure:
+
+    |-------------------+----------+-----------------------------------------|
+    | Name              | Type     | Meaning                                 |
+    |-------------------+----------+-----------------------------------------|
+    | Message Type      | U8       | Always '0x10'                           |
+    | Command ID        | U16      | Unique command identifier               |
+    | Payload Length    | U8       | Payload length (0..60)                  |
+    | Payload           | ...      | Optional command payload (params, etc.) |
+    |-------------------+----------+-----------------------------------------|
+
+    'Command ID' (bytes 1-2) and 'Payload Length' (byte 3) are mandatory in
+    any command message.  The message payload is optional, and will be ignored
+    if Payload Length is set to '0' bytes.  When a message payload is present,
+    it's length can be anywhere from 1..60 bytes, to stay within the 64 byte
+    maximum message length.
+
+    The contents of the payload is user defined, and can change for each
+    command. Any payload error checking should be done by the individual
+    command handler.
+
+    A sample command message would be:
+
+    Byte   0    1  2    3    4
+          [10] [34 12] [01] [FF]
+
+    - The first byte is the Message Type (0x10), which identifies this as a
+      command message.
+    - The second and third bytes are 0x1234 (34 12 in little-endian notation),
+      which is the unique command ID that will be parsed to the command lookup
+      function, and redirected to an appropriate command handler function.
+    - The fourth byte indicates that we have a message payload of 1 byte
+    - The fifth bytes is the 1 byte payload: 0xFF
+
+    RESPONSE MESSAGES
+    =================
+
+    Responses messages (Message Type = 0x20) are generated in response to an
+    incoming command, and have the following structure:
+
+    |-------------------+----------+-----------------------------------------|
+    | Name              | Type     | Meaning                                 |
+    |-------------------+----------+-----------------------------------------|
+    | Message Type      | U8       | Always '0x20'                           |
+    | Command ID        | U16      | Command ID of the command this message  |
+    |                   |          | is a response to, to correlate          |
+    |                   |          | Responses and commands                  |
+    | Payload Length    | U8       | Payload length (0..60)                  |
+    | Payload           | ...      | Optional response payload               |
+    |-------------------+----------+-----------------------------------------|
+
+    By including the 'Command ID' that this response message is related to,
+    the recipient can more easily correlate responses and commands.  This is
+    useful in situations where multiple commands are sent, and some commands
+    may take a longer period of time to execute than subsequent commands with
+    a different command ID.
+
+    Response message can only be generates in response to a command message,
+    so the Command ID should always be present.
+
+    If more precise command/response correlation is required, a custom
+    protocol can be developped, where a unique message identifier is included
+    in the payload of each command/response, but this is beyond the scope of
+    this high-level protocol.
+
+    A sample response message would be:
+
+    Byte   0    1  2    3    4
+          [20] [34 12] [01] [FF]
+
+    - The first byte is the Message Type (0x20), which identifies this as a
+      response message.
+    - The second and third bytes are 0x1234, which is the unique command ID
+      that this response is related to.
+    - The fourth byte indicates that we have a message payload of 1 byte
+    - The fifth byte is the 1 byte payload: 0xFF
+
+    ALERT MESSAGES
+    ==============
+
+    Alert messages (Message Type = 0x40) are sent whenever an alert condition
+    is present on the system (low battery, etc.), and have the following
+    structure:
+
+    |-------------------+----------+-----------------------------------------|
+    | Name              | Type     | Meaning                                 |
+    |-------------------+----------+-----------------------------------------|
+    | Message Type      | U8       | Always '0x40'                           |
+    | Alert ID          | U16      | Unique ID for the alert condition       |
+    | Payload Length    | U8       | Payload length (0..60)                  |
+    | Payload           | ...      | Optional response payload               |
+    |-------------------+----------+-----------------------------------------|
+
+    A sample alert message would be:
+
+    Byte   0    1  2    3    4    5    6    7
+          [40] [34 12] [04] [42] [07] [00] [10]
+
+    - The first byte is the Message Type (0x40), which identifies this as an
+      alert message.
+    - The second and third bytes are 0x1234, which is the unique alert ID.
+    - The fourth byte indicates that we have a message payload of 4 byte
+    - The last four bytes are the actual payload: '0x10000742' in this case,
+      assuming we were transmitting a 32-bit value in little-endian format.
+
+    ERROR MESSAGES
+    ==============
+
+    Error messages (Message Type = 0x80) are returned whenever an error
+    condition is present on the system, and have the following structure:
+
+    |-------------------+----------+-----------------------------------------|
+    | Name              | Type     | Meaning                                 |
+    |-------------------+----------+-----------------------------------------|
+    | Message Type      | U8       | Always '0x80'                           |
+    | Error ID          | U16      | Unique ID for the error condition       |
+    |-------------------+----------+-----------------------------------------|
+
+    Whenever an error condition is present and the system needs to be alerted
+    (such as a failed request, an attempt to access a non-existing resource,
+    etc.) the system can return a specific error message with an appropriate
+    Error ID.
+
+    A sample error message would be:
+
+    Byte   0    1  2
+          [80] [00 01]
+
+    - The first byte is the Message Type (0x80), which identifies this is an
+      error message.
+    - The second and third bytes are 0x0100 (00 01 in little-endian notation),
+      which is the error code corresponding to PROT_ERROR_INVALID_PARAM.
+
+*/
+
+#include "projectconfig.h"
+
+#ifdef CFG_PROTOCOL
+
+#include "protocol.h"
+#include "core/fifo/fifo.h"
+
+/* Callback functions to let us know when new data arrives via USB, etc. */
+#if defined(CFG_PROTOCOL_VIA_HID)
+  #define command_received_isr  usb_hid_generic_recv_isr
+  #define command_send          usb_hid_generic_send
+#elif defined(CFG_PROTOCOL_VIA_BULK)
+  #define command_received_isr  usb_custom_received_isr
+  #define command_send          usb_custom_send
+#endif
+
+#define U16_HIGH_U8(u16)  ((uint8_t) (((u16) >> 8) & 0x00FF))
+#define U16_LOW_U8(u16)   ((uint8_t) ((u16) & 0x00FF))
+
+/**************************************************************************/
+/*!
+    @brief      The standard function prototype for protocol commands (all
+                commnands need to implement the same signature)
+
+    @param[in]  Payload length (normally max 64 bytes)
+
+    @param[in]  Payload contents
+
+    @param[out] Response message, already filled with msg type and cmd id
+
+    @returns    Error code if there is an error, otherwise ERROR_NONE
+*/
+/**************************************************************************/
+typedef err_t (* const protCmdFunc_t)(uint8_t, uint8_t const [], protMsgResponse_t*);
+
+/**************************************************************************/
+/*
+    Expands the function to have the standard function signature
+*/
+/**************************************************************************/
+#define CMD_PROTOTYPE_EXPAND(command, function) \
+  err_t function(uint8_t length, uint8_t const payload[], protMsgResponse_t* mess_response);\
+
+PROTOCOL_COMMAND_TABLE(CMD_PROTOTYPE_EXPAND);
+
+/**************************************************************************/
+/*
+    Expands the command/function combination to something that we can
+    insert into the command lookup table (functions are expanded to have
+    the full function signature)
+*/
+/**************************************************************************/
+#define CMD_LOOKUP_EXPAND(command, function)\
+  [command] = function,\
+
+/**************************************************************************/
+/*!
+    The command lookup table implementation, which is based on the
+    commmands and implementation functions defined in prot_cmdtable.h.
+
+    The actual command/function pairs are broken off into a separate
+    header file so that you can more easily change the support command
+    list from project to project without changing the underlying
+    protocol code and files.
+*/
+/**************************************************************************/
+static protCmdFunc_t protocol_cmd_tbl[] =
+{
+  PROTOCOL_COMMAND_TABLE(CMD_LOOKUP_EXPAND)
+};
+
+/* FIFO buffer for incoming commands (Note: 64 bytes per command) */
+#define CMD_FIFO_DEPTH 4
+
+#if defined CFG_MCU_FAMILY_LPC11UXX
+  FIFO_DEF(ff_prot_cmd, CMD_FIFO_DEPTH, protMsgCommand_t, true , USB_IRQn);
+#elif defined CFG_MCU_FAMILY_LPC13UXX
+  FIFO_DEF(ff_prot_cmd, CMD_FIFO_DEPTH, protMsgCommand_t, true , USB_IRQ_IRQn);
+#else
+  #error __FILE__ No MCU defined
+#endif
+
+/**************************************************************************/
+/*!
+    @brief      Initialises the simple binary protocol (FIFO init, etc.)
+*/
+/**************************************************************************/
+void prot_init(void)
+{
+  fifo_clear(&ff_prot_cmd);
+}
+
+/**************************************************************************/
+/*!
+    @brief      Checks if there are any commands for the simple binary
+                protocol to process in the FIFO, and hands them off to the
+                command parser if anything was found
+
+    @code
+
+    // Note: Assumes CFG_PROTOCOL is defined in the board config file!
+
+    prot_init();
+
+    // Commands will be added to the protocol FIFO as they arrive via
+    // the command_received_isr callback further down in this file
+
+    while(1)
+    {
+      // Constantly check for incoming messages (this can of course be
+      // handled more efficiently depending on your requirements)
+      prot_task(NULL);
+    }
+
+    @endcode
+*/
+/**************************************************************************/
+void prot_task(void * p_para)
+{
+  if ( !fifo_isEmpty(&ff_prot_cmd) )
+  {
+    /* If we get here, it means a command was received */
+    protMsgCommand_t  message_cmd     = { 0 };
+    protMsgResponse_t message_reponse = { 0 };
+    uint16_t          command_id;
+    err_t           error;
+
+    /* COMMAND PHASE */
+    fifo_read(&ff_prot_cmd, &message_cmd);
+
+    /* Command_id is at an odd address ... directly using the value in *
+     * message_cmd can lead to alignment issues on the M0              */
+    command_id = (message_cmd.cmd_id_high << 8) + message_cmd.cmd_id_low;
+
+    /* Make sure we have a command with a valid ID */
+    if ( !(PROT_MSGTYPE_COMMAND == message_cmd.msg_type) )
+    {
+      error = ERROR_PROT_INVALIDMSGTYPE;
+    }
+    else if ( !(0 < command_id && command_id < PROT_CMDTYPE_COUNT) )
+    {
+      error = ERROR_PROT_INVALIDCOMMANDID;
+    }
+    else if (message_cmd.length > (PROT_MAX_MSG_SIZE-4))
+    {
+      error = ERROR_INVALIDPARAMETER;
+    }
+    else
+    {
+      /* Keep track of the command ID for the response message */
+      message_reponse.msg_type    = PROT_MSGTYPE_RESPONSE;
+      message_reponse.cmd_id_high = message_cmd.cmd_id_high;
+      message_reponse.cmd_id_low  = message_cmd.cmd_id_low;
+
+      /* Invoke 'cmd_received' callback before executing command */
+      if (prot_cmd_received_cb)
+      {
+        prot_cmd_received_cb(&message_cmd);
+      }
+
+      /* Fire the appropriate handler based on the command ID */
+      error = protocol_cmd_tbl[command_id] ( message_cmd.length, message_cmd.payload, &message_reponse );
+    }
+
+    /* RESPONSE PHASE */
+
+    // TODO:  Make sure the usb command is ready to send
+    // in case there are a bunch of cmds queued in FIFO
+
+    if (error == ERROR_NONE)
+    {
+      /* Invoke the 'cmd_executed' callback */
+      if (prot_cmd_executed_cb)
+      {
+        prot_cmd_executed_cb(&message_reponse);
+      }
+
+      /* Send the response message (cmd successfully executed) */
+      command_send( (uint8_t*) &message_reponse, sizeof(protMsgResponse_t));
+    }
+    else
+    {
+      /* Something went wrong ... parse the error ID */
+      protMsgError_t message_error =
+      {
+        .msg_type      = PROT_MSGTYPE_ERROR,
+      };
+      message_error.error_id_high = U16_HIGH_U8(error);
+      message_error.error_id_low  = U16_LOW_U8 (error);
+
+      /* Invoke the 'cmd_error' callback */
+      if (prot_cmd_error_cb)
+      {
+        prot_cmd_error_cb(&message_error);
+      }
+
+      /* Send back a mandatory error message */
+      command_send( (uint8_t*)  &message_error, sizeof(protMsgError_t));
+    }
+  }
+}
+
+/**************************************************************************/
+/*!
+    USB callback for incoming commands (the exact callback function
+    depends on the interface used by the simple binary protocol, and is
+    defined in a macro at the top of this file).
+
+    This callback will write the incoming command into the FIFO for
+    processing by prot_task when there is enough bandwidth to run
+    the command parser.
+*/
+/**************************************************************************/
+void command_received_isr(uint8_t * p_data, uint32_t length)
+{
+  fifo_write(&ff_prot_cmd, p_data);
+}
+
+#endif
diff --git a/reform2-lpc-fw/src/protocol/protocol.h b/reform2-lpc-fw/src/protocol/protocol.h
new file mode 100644
index 0000000000000000000000000000000000000000..75b32a541c4faa4fbb2f4c0d75bd6c5be95f2be9
--- /dev/null
+++ b/reform2-lpc-fw/src/protocol/protocol.h
@@ -0,0 +1,135 @@
+/**************************************************************************/
+/*!
+    @file     protocol.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _PROTOCOL_H_
+#define _PROTOCOL_H_
+
+#include "projectconfig.h"
+#include "prot_cmdtable.h"
+#include "core/usb/usb_hid.h"
+#include "core/usb/usb_custom_class.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Max message length is 64 bytes to align with USB HID, though this may
+   be a bit large for I2C or SPI ... maybe adjust down, but in no case
+   should this be more than 64 bytes                                     */
+#define PROT_MAX_MSG_SIZE     (64)
+
+/**************************************************************************/
+/*!
+    The first byte of every transfer defines the message type
+*/
+/**************************************************************************/
+typedef enum
+{
+  PROT_MSGTYPE_COMMAND          = 0x10,
+  PROT_MSGTYPE_RESPONSE         = 0x20,
+  PROT_MSGTYPE_ALERT            = 0x40,
+  PROT_MSGTYPE_ERROR            = 0x80
+} protMsgType_t;
+
+/**************************************************************************/
+/*!
+    Command message struct
+*/
+/**************************************************************************/
+typedef PRE_PACK struct POST_PACK {
+  uint8_t msg_type;
+  union {
+    uint16_t cmd_id;
+    struct {
+      uint8_t cmd_id_low;     // Little-endian encoding
+      uint8_t cmd_id_high;
+    };
+  };
+  uint8_t length;
+  uint8_t payload[PROT_MAX_MSG_SIZE-4];
+} protMsgCommand_t;
+
+STATIC_ASSERT(sizeof(protMsgCommand_t) == 64);
+
+/**************************************************************************/
+/*!
+    Response message struct
+*/
+/**************************************************************************/
+typedef protMsgCommand_t protMsgResponse_t;
+
+/**************************************************************************/
+/*!
+    Alert message struct
+*/
+/**************************************************************************/
+typedef protMsgCommand_t protMsgAlert_t;
+
+/**************************************************************************/
+/*!
+    Error message struct
+*/
+/**************************************************************************/
+typedef PRE_PACK struct POST_PACK {
+  uint8_t msg_type;
+  union {
+    uint16_t error_id;
+    struct {
+      uint8_t error_id_low;   // Little-endian encoding
+      uint8_t error_id_high;
+    };
+  };
+} protMsgError_t;
+
+STATIC_ASSERT(sizeof(protMsgError_t) == 3);
+
+//--------------------------------------------------------------------+
+// PUBLIC API
+//--------------------------------------------------------------------+
+void prot_task(void * p_para);
+void prot_init(void);
+
+//--------------------------------------------------------------------+
+// Callback API
+//--------------------------------------------------------------------+
+void prot_cmd_received_cb(protMsgCommand_t const * p_mess) __attribute__ ((weak));
+void prot_cmd_executed_cb(protMsgResponse_t const * p_resonse) __attribute__ ((weak));
+void prot_cmd_error_cb(protMsgError_t const * p_error) __attribute__ ((weak));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/src/protocol/protocol.txt b/reform2-lpc-fw/src/protocol/protocol.txt
new file mode 100644
index 0000000000000000000000000000000000000000..aa985dfd773b5467d1d71bb333938a8d8d8f6373
--- /dev/null
+++ b/reform2-lpc-fw/src/protocol/protocol.txt
@@ -0,0 +1,175 @@
+Protocol Description
+--------------------
+
+This simple messaging protocol can be used to send and receive binary messages
+using any binary serial bus (USB HID, USB Bulk, SPI, I2C, Wireless, etc.).
+
+The protocol is designed to be flexible and extensible, with the only
+requirement being that individual messages are 64 bytes or smaller,
+and that the first byte of every message is a one byte (U8) identifier that
+indicates the format for the rest of the payload (if there is one).
+
+Implementation Notes
+--------------------
+
+The protocol implementation must be transport mechanism agnostic, and should
+be able to function with any binary serial bus.  The original design goal is a
+protocol that can function via USB HID, SPI Slave, and I2C Slave modes, but
+any similar protocol should be able to be added to the implementation
+(wireless transfers, etc.).
+
+Endianness
+----------
+
+All values larger than 8-bits are expected to be little endian, such as the 
+command IDs, and the payload contents.  Any deviation from this rule should
+be clearly documentated.
+
+Message Types
+-------------
+
+Each message is preceded by an 8-bit message identifier that indicates
+the format and content of the rest of the message:
+
+|-----------------------+---------+-------------------------------------------|
+| Message Type          | ID (U8) | Meaning                                   |
+|-----------------------+---------+-------------------------------------------|
+| Command               | 0x10    |                                           |
+| Response              | 0x20    |                                           |
+| Alert                 | 0x40    |                                           |
+| Error                 | 0x80    |                                           |
+|-----------------------+---------+-------------------------------------------|
+
+Command Messages
+----------------
+
+Command messages (Message Type = 0x10) have the following structure:
+
+|-------------------+----------+----------------------------------------------|
+| Name              | Type     | Meaning                                      |
+|-------------------+----------+----------------------------------------------|
+| Message Type      | U8       | Always '0x10'                                |
+| Command ID        | U16      | Unique command identifier                    |
+| Payload Length    | U8       | Payload length (0..60)                       |
+| Payload           | ...      | Optional command payload (params, etc.)      |
+|-------------------+----------+----------------------------------------------|
+
+'Command ID' (bytes 1-2) and 'Payload Length' (byte 3) are mandatory in any
+command message.  The message payload is optional, and will be ignored if
+Payload Length is set to '0' bytes.  When a message payload is present, it's
+length can be anywhere from 1..60 bytes, to stay within the 64 byte maximum
+message length.
+
+The contents of the payload is user defined, and can change for each command.
+Any payload error checking should be done by the individual command handler.
+
+A sample command message would be:
+
+Byte   0    1  2    3    4
+      [10] [34 12] [01] [FF]
+ 
+- The first byte is the Message Type (0x10), which identifies this as a
+  command message.
+- The second and third bytes are 0x1234 (34 12 in little-endian notation),
+  which is the unique command ID that will be parsed to the command lookup
+  function, and redirected to an appropriate command handler function.
+- The fourth byte indicates that we have a message payload of 1 byte
+- The fifth bytes is the 1 byte payload: 0xFF
+
+Response Messages
+-----------------
+
+Responses messages (Message Type = 0x20) are generated in response to an
+incoming command, and have the following structure:
+
+|-------------------+----------+----------------------------------------------|
+| Name              | Type     | Meaning                                      |
+|-------------------+----------+----------------------------------------------|
+| Message Type      | U8       | Always '0x20'                                |
+| Command ID        | U16      | Command ID of the command this message is    |
+|                   |          | a response to, to correlate Responses and    |
+|                   |          | commands                                     |
+| Payload Length    | U8       | Payload length (0..60)                       |
+| Payload           | ...      | Optional response payload                    |
+|-------------------+----------+----------------------------------------------|
+
+By including the 'Command ID' that this response message is related to, the
+recipient can more easily correlate responses and commands.  This is useful in
+situations where multiple commands are sent, and some commands may take a
+longer period of time to execute than subsequent commands with a different
+command ID.  
+
+Response message can only be generates in response to a command message, so
+the Command ID should always be present.
+
+If more precise command/response correlation is required, a custom protocol
+can be developped, where a unique message identifier is included in the
+payload of each command/response, but this is beyond the scope of this
+high-level protocol.
+
+A sample response message would be:
+
+Byte   0    1  2    3    4
+      [20] [34 12] [01] [FF]
+ 
+- The first byte is the Message Type (0x20), which identifies this as a
+  response message.
+- The second and third bytes are 0x1234, which is the unique command ID that
+  this response is related to.
+- The fourth byte indicates that we have a message payload of 1 byte
+- The fifth byte is the 1 byte payload: 0xFF
+
+Alert Messages
+--------------
+
+Alert messages (Message Type = 0x40) are sent whenever an alert condition
+is present on the system (low battery, etc.), and have the following structure:
+
+|-------------------+----------+----------------------------------------------|
+| Name              | Type     | Meaning                                      |
+|-------------------+----------+----------------------------------------------|
+| Message Type      | U8       | Always '0x40'                                |
+| Alert ID          | U16      | Unique ID for the alert condition            |
+| Payload Length    | U8       | Payload length (0..60)                       |
+| Payload           | ...      | Optional response payload                    |
+|-------------------+----------+----------------------------------------------|
+
+A sample alert message would be:
+
+Byte   0    1  2    3    4    5    6    7
+      [40] [34 12] [04] [42] [07] [00] [10]
+ 
+- The first byte is the Message Type (0x40), which identifies this as an
+  alert message.
+- The second and third bytes are 0x1234, which is the unique alert ID.
+- The fourth byte indicates that we have a message payload of 4 byte
+- The last four bytes are the actual payload: '0x10000742' in this case,
+  assuming we were transmitting a 32-bit value in little-endian format.
+ 
+Error Messages
+--------------
+
+Error messages (Message Type = 0x80) are returned whenever an error condition
+is present on the system, and have the following structure:
+
+|-------------------+----------+----------------------------------------------|
+| Name              | Type     | Meaning                                      |
+|-------------------+----------+----------------------------------------------|
+| Message Type      | U8       | Always '0x80'                                |
+| Error ID          | U16      | Unique ID for the error condition            |
+|-------------------+----------+----------------------------------------------|
+
+Whenever an error condition is present and the system needs to be alerted (such
+as a failed request, an attempt to access a non-existing resource, etc.) the
+system can return a specific error message with an appropriate Error ID.
+
+A sample error message would be:
+
+Byte   0    1  2
+      [80] [00 01]
+
+- The first byte is the Message Type (0x80), which identifies this is an
+  error message.
+- The second and third bytes are 0x0100 (00 01 in little-endian notation),
+  which is the error code corresponding to PROT_ERROR_INVALID_PARAM.
+  
\ No newline at end of file
diff --git a/reform2-lpc-fw/src/sysdefs.h b/reform2-lpc-fw/src/sysdefs.h
new file mode 100644
index 0000000000000000000000000000000000000000..d7b0d771b77d9577bf6cecbff80630f9e082c81b
--- /dev/null
+++ b/reform2-lpc-fw/src/sysdefs.h
@@ -0,0 +1,103 @@
+/**************************************************************************/
+/*!
+    @file     sysdefs.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, K. Townsend (microBuilder.eu)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef _SYSDEFS_H_
+#define _SYSDEFS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef unsigned char byte_t;
+
+/* Stay compatible with ugly "windows" style for bool */
+#define BOOL bool
+
+#ifndef TRUE
+  #define TRUE true
+#endif
+
+#ifndef FALSE
+  #define FALSE false
+#endif
+
+/* ASM and inline function placeholders */
+#ifndef ASM
+  #define ASM __asm volatile
+#endif
+
+#ifndef INLINE
+  #if __GNUC__ && !__GNUC_STDC_INLINE__
+    #define INLINE extern inline
+  #else
+    #define INLINE inline
+  #endif
+#endif
+
+/* GCC does not inline any functions when not optimizing unless you specify
+   the 'always_inline' attribute for the function */
+#ifndef INLINE_POST
+  #define INLINE_POST __attribute__((always_inline))
+#endif
+
+/* SRAM placement for critical functions depends on the linker script */
+#ifdef __GNUC__
+  #ifdef __CROSSWORKS_ARM
+    #define RAMFUNC __attribute__ ((long_call, section (".fast")))
+  #else
+    /* ToDo: Throws 'ignoring changed section attributes for .data' */
+    // #define RAMFUNC __attribute__ ((long_call, section (".data")))
+    /* Hmm ... not working from the makefile ... need to debug! */
+    /* Leave it blank for now unless we're in Crossworks */
+    #define RAMFUNC
+  #endif
+#else
+  #error "No section defined for RAMFUNC in sysdefs.h"
+#endif
+
+/* NULL placeholder */
+#ifndef NULL
+  #define NULL ((void *) 0)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/reform2-lpc-fw/tools/lpc21isp/.gitignore b/reform2-lpc-fw/tools/lpc21isp/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..85555636acf80c16ba261082465ccd084bad6a8a
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/.gitignore
@@ -0,0 +1,17 @@
+# Object files
+*.o
+
+# Libraries
+*.lib
+*.a
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Executables
+*.exe
+*.out
+*.app
\ No newline at end of file
diff --git a/reform2-lpc-fw/tools/lpc21isp/Makefile b/reform2-lpc-fw/tools/lpc21isp/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..2e7d57660f2dfea646714004a19309055b10988f
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/Makefile
@@ -0,0 +1,33 @@
+all:      lpc21isp
+
+GLOBAL_DEP  = adprog.h lpc21isp.h lpcprog.h lpcterm.h
+CC = gcc
+
+ifneq ($(findstring(freebsd, $(OSTYPE))),)
+CFLAGS+=-D__FREEBSD__
+endif
+
+ifeq ($(OSTYPE),)
+OSTYPE		= $(shell uname)
+endif
+
+ifneq ($(findstring Darwin,$(OSTYPE)),)
+CFLAGS+=-D__APPLE__
+endif
+
+CFLAGS	+= -Wall -static
+
+adprog.o: adprog.c $(GLOBAL_DEP)
+	$(CC) $(CDEBUG) $(CFLAGS) -c -o adprog.o adprog.c
+
+lpcprog.o: lpcprog.c $(GLOBAL_DEP)
+	$(CC) $(CDEBUG) $(CFLAGS) -c -o lpcprog.o lpcprog.c
+
+lpcterm.o: lpcterm.c $(GLOBAL_DEP)
+	$(CC) $(CDEBUG) $(CFLAGS) -c -o lpcterm.o lpcterm.c
+
+lpc21isp: lpc21isp.c adprog.o lpcprog.o lpcterm.o $(GLOBAL_DEP)
+	$(CC) $(CDEBUG) $(CFLAGS) -o lpc21isp.out lpc21isp.c adprog.o lpcprog.o lpcterm.o
+
+clean:
+	$(RM) adprog.o lpcprog.o lpcterm.o lpc21isp.out
diff --git a/reform2-lpc-fw/tools/lpc21isp/Makefile.vc b/reform2-lpc-fw/tools/lpc21isp/Makefile.vc
new file mode 100644
index 0000000000000000000000000000000000000000..0be532b05f4ecdb8ae1a916c776b8571cc94f81a
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/Makefile.vc
@@ -0,0 +1,26 @@
+all:      lpc21isp.exe
+
+GLOBAL_DEP  = lpc21isp.h adprog.h lpcprog.h lpcterm.h
+RM = del
+CC = cl
+
+# CFLAGS = -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS
+CFLAGS =
+
+adprog.obj: adprog.c $(GLOBAL_DEP)
+    $(CC) -c $(CFLAGS) adprog.c
+
+lpcprog.obj: lpcprog.c $(GLOBAL_DEP)
+    $(CC) -c $(CFLAGS) lpcprog.c
+
+lpcterm.obj: lpcterm.c $(GLOBAL_DEP)
+    $(CC) -c $(CFLAGS) lpcterm.c
+
+lpc21isp.obj: lpc21isp.c $(GLOBAL_DEP)
+    $(CC) -c $(CFLAGS) lpc21isp.c
+
+lpc21isp.exe: lpc21isp.obj adprog.obj lpcprog.obj lpcterm.obj
+    $(CC) /Felpc21isp.exe lpc21isp.obj adprog.obj lpcprog.obj lpcterm.obj
+
+clean:
+    $(RM) adprog.obj lpcprog.obj lpcterm.obj lpc21isp.obj lpc21isp.exe vc*.pdb
diff --git a/reform2-lpc-fw/tools/lpc21isp/README b/reform2-lpc-fw/tools/lpc21isp/README
new file mode 100644
index 0000000000000000000000000000000000000000..7f3cf6ffcb392912f3277be6d2b27a0e0b172686
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/README
@@ -0,0 +1,45 @@
+/******************************************************************************
+
+Project:           Portable command line ISP for Philips LPC2000 family
+                   and Analog Devices ADUC70xx
+
+Filename:          README
+
+Compiler:          Microsoft VC 6/7, GCC Cygwin, GCC Linux, GCC ARM ELF
+
+Author:            Martin Maurer (Martin.Maurer@clibb.de)
+
+Copyright:         (c) Martin Maurer 2003-2008, All rights reserved
+Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com
+
+    This file is part of lpc21isp.
+
+    lpc21isp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    any later version.
+
+    lpc21isp is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    and GNU General Public License along with lpc21isp.
+    If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+To compile with microsoft visual studio:
+- Open console. Execute bat file from your installation, e.g.
+  "c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat"
+- Go to directory where you unpacked the source.
+- Run
+  nmake /f Makefile.vc clean all
+
+To compile with gcc (linux, cygwin, ...)
+- Open shell / terminal windows
+- Run (if you want to use make and gcc)
+  make -f Makefile.gnu clean all
+- Run (if you want to use gmake and gcc)
+  gmake -f Makefile.gnu clean all
diff --git a/reform2-lpc-fw/tools/lpc21isp/README.md b/reform2-lpc-fw/tools/lpc21isp/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..dbd26fc9efc9970ae9aa0ab063eba83a1d4655b8
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/README.md
@@ -0,0 +1,22 @@
+lpc21isp
+========
+
+Originally written by Martin Maurer
+Modified by Brad Luyster (BradLuyster@gmail.com) to add support for the LPC1114FN28 processor
+
+Licensure
+---------
+
+lpc21isp is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+any later version.
+
+lpc21isp is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+and GNU General Public License along with lpc21isp.
+If not, see <http://www.gnu.org/licenses/>.
\ No newline at end of file
diff --git a/reform2-lpc-fw/tools/lpc21isp/StdAfx.h b/reform2-lpc-fw/tools/lpc21isp/StdAfx.h
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/reform2-lpc-fw/tools/lpc21isp/adprog.c b/reform2-lpc-fw/tools/lpc21isp/adprog.c
new file mode 100644
index 0000000000000000000000000000000000000000..503cd01127f68bf79f3476190e8f9bec24fd1635
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/adprog.c
@@ -0,0 +1,325 @@
+/******************************************************************************
+
+Project:           Portable command line ISP for NXP LPC1000 / LPC2000 family
+                   and Analog Devices ADUC70xx
+
+Filename:          adprog.c
+
+Compiler:          Microsoft VC 6/7, Microsoft VS2008, Microsoft VS2010,
+                   GCC Cygwin, GCC Linux, GCC ARM ELF
+
+Author:            Martin Maurer (Martin.Maurer@clibb.de)
+
+Copyright:         (c) Martin Maurer 2003-2011, All rights reserved
+Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com
+
+    This file is part of lpc21isp.
+
+    lpc21isp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    any later version.
+
+    lpc21isp is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    and GNU General Public License along with lpc21isp.
+    If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#if defined(_WIN32)
+#if !defined __BORLANDC__
+#include "StdAfx.h"
+#endif
+#endif // defined(_WIN32)
+#include "lpc21isp.h"
+
+#ifdef AD_SUPPORT
+#include "adprog.h"
+
+/***************************** AnalogDevicesSync ************************/
+/**  Attempt to synchronize with an Analog Device ARM micro.  Sends a
+backspace and reads back the microcontrollers response.  Performs
+multiple retries. Exits the program on error, returns to caller in the
+case of success.
+*/
+static void AnalogDevicesSync(ISP_ENVIRONMENT *IspEnvironment)
+{
+    BINARY sync;                        /* Holds sync command.          */
+    AD_SYNC_RESPONSE response;          /* Response from micro.         */
+    int sync_attempts;                  /* Number of retries.           */
+
+    /*  Make sure we don't read garbage later instead of the        */
+    /* response we expect from the micro.                           */
+    ClearSerialPortBuffers(IspEnvironment);
+
+    DebugPrintf(2, "Synchronizing\n"); /* Progress report.             */
+
+    sync = ANALOG_DEVICES_SYNC_CHAR;    /* Build up sync command.       */
+
+    /*  Perform the actual sync attempt.  First send the sync       */
+    /* character, the attempt to read back the response.  For the   */
+    /* AD ARM micro this is a fixed length block.  If response is   */
+    /* received attempt to validate it by comparing the first       */
+    /* characters to those expected.  If the received block does    */
+    /* not validate or is incomplete empty the serial buffer and    */
+    /* retry.                                                       */
+    for (sync_attempts = 0; sync_attempts < 5; sync_attempts++)
+    {
+        SendComPortBlock(IspEnvironment, &sync, 1);
+
+        if (ReceiveComPortBlockComplete(IspEnvironment, &response, sizeof(response),
+            500) == 0)
+        {
+
+            if (memcmp(response.product_id, ANALOG_DEVICES_SYNC_RESPONSE,
+                ANALOG_DEVICES_SYNC_SIZE) == 0)
+            {
+                return;
+            }
+            else
+            {
+                DumpString(3, &response, sizeof(response),
+                    "Unexpected response to sync attempt ");
+            }
+        }
+        else
+        {
+            DebugPrintf(3, "No (or incomplete) answer on sync attempt\n");
+        }
+
+        ClearSerialPortBuffers(IspEnvironment);
+    }
+
+    DebugPrintf(1, "No (or unacceptable) answer on sync attempt\n");
+    exit(4);
+}
+
+typedef struct {
+    char start1;
+    char start2;
+    BINARY bytes;
+    char cmd;
+    BINARY address_h;
+    BINARY address_u;
+    BINARY address_m;
+    BINARY address_l;
+    BINARY data[251];
+} AD_PACKET;
+
+/***************************** AnalogDevicesFormPacket ******************/
+/**  Create an Analog Devices communication packet from the constituent
+elements.
+\param [in] cmd The command being sent, one of 'E' for erase, 'W' for
+write, 'V' for verify or 'R' for run..
+\param [in] no_bytes the number of data bytes to send with the command in
+the packet.
+\param [in] address the address to apply the command to.
+\param [in] data the data to send with the packet, may be null if no_bytes
+is zero.
+\param[out] packet that will be filled.
+*/
+static void AnalogDevicesFormPacket(ISP_ENVIRONMENT *IspEnvironment,
+                                                char cmd, int no_bytes, unsigned int address,
+                                                const void *data, AD_PACKET *packet)
+{
+    BINARY checksum;
+    const BINARY *data_in;
+    int i;
+
+    (void)IspEnvironment; /* never used in this function */
+
+    /*  Some sanity checking on the arguments.  These should only   */
+    /* fail if there is a bug in the caller.                        */
+    /*  Check 1) that the number of data bytes is in an acceptable  */
+    /* range, 2) that we have a non-null pointer if data is being   */
+    /* put in the packet and 3) that we have a non-null pointer to  */
+    /* the packet to be filled. We just exit with an error message  */
+    /* if any of these tests fail.                                  */
+    if ((no_bytes < 0) || (no_bytes > 250))
+    {
+        DebugPrintf(1,
+            "The number of bytes (%d) passed to FormPacket is invalid.\n",
+            no_bytes);
+        exit(-1);
+    }
+    if ((data == 0) && (no_bytes != 0))
+    {
+        DebugPrintf(1,
+            "A null pointer to data paased to FormPacket when data was expected.\n");
+        exit(-1);
+    }
+    if (packet == 0)
+    {
+        DebugPrintf(1,
+            "A null packet pointer was passed to FormPacket.\n");
+        exit(-1);
+    }
+
+    checksum = 0;               /*  Checksum starts at zero.            */
+
+    data_in = (BINARY*) data;             /*  Pointer pun so we can walk through  */
+    /* the data.                            */
+
+    packet->start1 = 0x7;       /*  The start of the packet is constant.*/
+    packet->start2 = 0xE;
+
+    /*  Fill in the rest of the packet and calculate the checksum   */
+    /* as we go.                                                    */
+
+    /* The number of bytes is the number of data bytes + the        */
+    /* address bytes + the command byte.                            */
+    packet->bytes = (BINARY)(no_bytes + 5);
+
+    checksum += packet->bytes;
+
+    /*  The command for the packet being sent.  No error checking   */
+    /* done on this.                                                */
+    packet->cmd = cmd;
+
+    checksum += cmd;
+
+    /*  Now break up the address and place in the proper packet     */
+    /* locations.                                                   */
+    packet->address_l = (BINARY)(address & 0xFF);
+    packet->address_m = (BINARY)((address >> 8) & 0xFF);
+    packet->address_u = (BINARY)((address >> 16) & 0xFF);
+    packet->address_h = (BINARY)((address >> 24) & 0xFF);
+
+    checksum += packet->address_l;
+    checksum += packet->address_m;
+    checksum += packet->address_u;
+    checksum += packet->address_h;
+
+    /*  Copy the data bytes into the packet.  We could use memcpy   */
+    /* but we have to calculate the checksum anyway.                */
+    for (i = 0; i < no_bytes; i++)
+    {
+        packet->data[i] = data_in[i];
+        checksum += data_in[i];
+    }
+
+    /*  Finally, add the checksum to the end of the packet.         */
+    packet->data[i] = (BINARY)-checksum;
+}
+
+/***************************** AnalogDevicesSendPacket ******************/
+/**  Send a previously form Analog Devices communication.  Retry a
+couple of times if needed but fail by exiting the program if no ACK is
+forthcoming.
+\param [in] packet the packet to send.
+*/
+static void AnalogDevicesSendPacket(ISP_ENVIRONMENT *IspEnvironment,
+                                                const AD_PACKET * packet)
+{
+    BINARY response;
+    int retry = 0;
+
+    do {
+        retry++;
+
+        /*  Make sure we don't read garbage later instead of    */
+        /* the response we expect from the micro.               */
+        ClearSerialPortBuffers(IspEnvironment);
+
+        /*  Send the packet, the size is the number of data     */
+        /* bytes in the packet plus 3 bytes worth of header     */
+        /* plus checksum.                                       */
+        SendComPortBlock(IspEnvironment, packet, packet->bytes + 4);
+
+        /*  Receive the response and check, return to caller    */
+        /* if successful.                                       */
+        if (ReceiveComPortBlockComplete(IspEnvironment, &response, 1, 5000) == 0)
+        {
+            if (response == ANALOG_DEVICES_ACK)
+            {
+                DebugPrintf(3, "Packet Sent\n");
+                return;
+            }
+            if (response != ANALOG_DEVICES_NAK)
+            {
+                DebugPrintf(3, "Unexpected response to packet (%x)\n", (int)response);
+            }
+            DebugPrintf(2, "*");
+        }
+    } while (retry < 3);
+
+    DebugPrintf(1, "Send packet failed\n");
+    exit(-1);
+}
+
+/***************************** AnalogDevicesErase ***********************/
+/**  Erase the Analog Devices micro.  We take the simple way out and
+just erase the whole thing.
+*/
+static void AnalogDevicesErase(ISP_ENVIRONMENT *IspEnvironment)
+{
+    BINARY pages;
+    AD_PACKET packet;
+
+    pages = 0;
+    DebugPrintf(2, "Erasing .. ");
+    AnalogDevicesFormPacket(IspEnvironment, 'E', 1, 0, &pages, &packet);
+    AnalogDevicesSendPacket(IspEnvironment, &packet);
+    DebugPrintf(2, "Erased\n");
+}
+
+#define AD_PACKET_SIZE (250)
+
+/***************************** AnalogDevicesWrite ***********************/
+/**  Write the program.
+\param [in] data the program to download to the micro.
+\param [in] address where to start placing the program.
+\param [in] bytes the size of the progrm to download.
+*/
+static void AnalogDevicesWrite(ISP_ENVIRONMENT *IspEnvironment,
+                                         const void *data, long address, size_t bytes)
+{
+    AD_PACKET packet;
+    const BINARY *prog_data;
+
+    DebugPrintf(2, "Writing %d bytes ", bytes);
+    prog_data = (const BINARY*) data;
+    while (bytes > AD_PACKET_SIZE)
+    {
+        AnalogDevicesFormPacket(IspEnvironment, 'W', AD_PACKET_SIZE, address, prog_data, &packet);
+        AnalogDevicesSendPacket(IspEnvironment, &packet);
+        address += AD_PACKET_SIZE;
+        prog_data += AD_PACKET_SIZE;
+        bytes -= AD_PACKET_SIZE;
+        DebugPrintf(2, ".");
+    }
+    if (bytes > 0)
+    {
+        AnalogDevicesFormPacket(IspEnvironment, 'W', bytes, address, prog_data, &packet);
+        AnalogDevicesSendPacket(IspEnvironment, &packet);
+        DebugPrintf(2, ".");
+    }
+}
+
+/***************************** AnalogDevicesDownload ********************/
+/**  Perform the download into an Analog Devices micro.  As a quick and
+* dirty hack against flash relocations at 0x80000
+* \return 0 if ok, error code else
+* \ToDo: possible to implement the return value instead of calling
+* exit() in sub-functions
+*/
+int AnalogDevicesDownload(ISP_ENVIRONMENT *IspEnvironment)
+{
+    AnalogDevicesSync(IspEnvironment);
+    AnalogDevicesErase(IspEnvironment);
+    if (IspEnvironment->BinaryLength > 0x80000)
+    {
+        DebugPrintf(2, "Note:  Flash remapped 0x80000 to 0.\n");
+        AnalogDevicesWrite(IspEnvironment, IspEnvironment->BinaryContent + 0x80000, 0, IspEnvironment->BinaryLength-0x80000);
+    }
+    else
+    {
+        AnalogDevicesWrite(IspEnvironment, IspEnvironment->BinaryContent, 0, IspEnvironment->BinaryLength);
+    }
+    return (0);
+}
+#endif // AD_SUPPORT
diff --git a/reform2-lpc-fw/tools/lpc21isp/adprog.h b/reform2-lpc-fw/tools/lpc21isp/adprog.h
new file mode 100644
index 0000000000000000000000000000000000000000..3235289f9ba222e847e923a2dfe58a5cd0292f21
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/adprog.h
@@ -0,0 +1,47 @@
+/******************************************************************************
+
+Project:           Portable command line ISP for NXP LPC1000 / LPC2000 family
+                   and Analog Devices ADUC70xx
+
+Filename:          adprog.h
+
+Compiler:          Microsoft VC 6/7, Microsoft VS2008, Microsoft VS2010,
+                   GCC Cygwin, GCC Linux, GCC ARM ELF
+
+Author:            Martin Maurer (Martin.Maurer@clibb.de)
+
+Copyright:         (c) Martin Maurer 2003-2011, All rights reserved
+Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com
+
+    This file is part of lpc21isp.
+
+    lpc21isp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    any later version.
+
+    lpc21isp is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    and GNU General Public License along with lpc21isp.
+    If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define ANALOG_DEVICES_SYNC_CHAR                ((BINARY)0x08)
+#define ANALOG_DEVICES_SYNC_RESPONSE        ("ADuC")
+#define ANALOG_DEVICES_SYNC_SIZE                (strlen(ANALOG_DEVICES_SYNC_RESPONSE))
+#define ANALOG_DEVICES_ACK                        0x6
+#define ANALOG_DEVICES_NAK                        0x7
+
+typedef struct
+{
+    BINARY product_id[15];
+    BINARY version[3];
+    BINARY reserved[4];
+    BINARY terminator[2];
+} AD_SYNC_RESPONSE;
+
+int AnalogDevicesDownload(ISP_ENVIRONMENT *IspEnvironment);
diff --git a/reform2-lpc-fw/tools/lpc21isp/gpl.txt b/reform2-lpc-fw/tools/lpc21isp/gpl.txt
new file mode 100644
index 0000000000000000000000000000000000000000..94a9ed024d3859793618152ea559a168bbcbb5e2
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/gpl.txt
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/reform2-lpc-fw/tools/lpc21isp/lgpl-3.0.txt b/reform2-lpc-fw/tools/lpc21isp/lgpl-3.0.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fc8a5de7edf437cdc98a216370faf7c757279bcb
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/lgpl-3.0.txt
@@ -0,0 +1,165 @@
+		   GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions. 
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version. 
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+  Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/reform2-lpc-fw/tools/lpc21isp/lpc21isp.c b/reform2-lpc-fw/tools/lpc21isp/lpc21isp.c
new file mode 100644
index 0000000000000000000000000000000000000000..5324eb6a37c16ec41a513e2da06441b5370138b0
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/lpc21isp.c
@@ -0,0 +1,2192 @@
+/******************************************************************************
+
+Project:           Portable command line ISP for NXP LPC1000 / LPC2000 family
+                   and Analog Devices ADUC70xx
+
+Filename:          lpc21isp.c
+
+Compiler:          Microsoft VC 6/7, Microsoft VS2008, Microsoft VS2010,
+                   GCC Cygwin, GCC Linux, GCC ARM ELF
+
+Author:            Martin Maurer (Martin.Maurer@clibb.de)
+
+Copyright:         (c) Martin Maurer 2003-2011, All rights reserved
+Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com
+
+    This file is part of lpc21isp.
+
+    lpc21isp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    any later version.
+
+    lpc21isp is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    and GNU General Public License along with lpc21isp.
+    If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#if defined(_WIN32)
+#if !defined __BORLANDC__
+#include "StdAfx.h"        // Precompiled Header for WIN32
+#endif
+#endif // defined(_WIN32)
+#include "lpc21isp.h"   // if using propriatory serial port communication (customize attached lpc21isp.h)
+#include "adprog.h"
+#include "lpcprog.h"
+#include "lpcterm.h"
+
+/*
+Change-History:
+
+1.00  2004-01-08  Initial Version, tested for MSVC6/7 and GCC under Cygwin
+1.01  2004-01-10  Porting to Linux (at least compiling must work)
+1.02  2004-01-10  Implemented conversion intel hex format -> binary
+1.03  2004-01-25  Preparation to upload to public website
+1.04  2004-02-12  Merged in bugfixes by Soeren Gust
+1.05  2004-03-14  Implement printing of error codes as text / strings
+1.06  2004-03-09  Merged in bugfixes by Charles Manning:
+                  The '?' sychronisation does not reliably respond to the first '?'.
+                  I added some retries.
+                  The LPC2106 sometimes responds to the '?' by echoing them back.
+                  This sometimes causes an attempt to match "?Synchonized".
+                  Added code to strip off any leading '?'s.
+                  Timeouts were too long.
+                  Change from RTS/CTS to no flow control.
+                  Done because many/most people will use only 3-wire comms.
+                  Added some progress tracing.
+1.07  2004-03-14  Implement handling of control lines for easier booting
+1.08  2004-04-01  Bugfix for upload problem
+1.09  2004-04-03  Redesign of upload routine
+                  Now always 180 byte blocks are uploaded, to prevent
+                  small junks in uuencoding
+1.10  2004-04-03  Clear buffers before sending commands to LPC21xx,
+                  this prevents synchronizing errors when previously loaded
+                  program does a lot of output, so FIFO of PC runs full
+1.11  2004-04-03  Small optimization for controlling reset line
+                  otherwise termonly starts LPC twice, free PC buffers
+1.12  2004-04-04  Add switch to enable logging terminal output to lpc21isp.log
+1.13  2004-05-19  Merged in improvement by Charles Manning:
+                  Instead of exiting the wrong hex file size is corrected
+1.14  2004-07-07  Merged in improvement by Alex Holden:
+                  Remove little/big endian dependancy
+1.15  2004-09-27  Temporary improvement by Cyril Holweck:
+                  Removed test (data echoed = data transmited) on the main
+                  data transfert, since this was the biggest failure
+                  reason and is covered by checksome anyway.
+                  Added COMPILE_FOR_LPC21, to have target dump it's own
+                  memory to stdout.
+1.16  2004-10-09  Merged in bugfix / improvement by Sinelnikov Evgeny
+                  I found out that Linux and Windows serial port initialization
+                  are different with pinouts states. My board don't get
+                  reset signal at first cycle of DTR pinout moving.
+                  And I add this moving to initalization cycle.
+1.17  2004-10-21  Changes by Cyril Holweck
+                  Divide main, take out the real programming function, that can
+                  also be used by a target to copy its own code to another.
+1.18  2004-10-26  Changes by Cyril Holweck
+                  Added a "G 0 A\r\n" at end of programming to run code.
+1.19  2004-11-03  Changes by Robert Adsett
+                  Add support for Analog Devices.
+                  Separate file load from programming.
+                  Change from a debug on/off flag to debug level
+                  Remove if (debug) tests and replace with DebugPrintf
+                  statements.
+                  Change serial I/O and timing so that the system
+                  dependancies are isolated to a few portability functions.
+                  Add support for binary serial I/O.
+                  Add doxygen support.
+1.20  2004-11-07  Preparation for multiport booting (factory support)
+1.21  2004-11-08  Bugfix from Robert Adsett
+                  BinaryLength was not initialized
+1.22  2004-11-08  Changes from Cyril Holweck / Evgeny Sinelnikov
+                  Forgotten IspEnvironment-> and bugfixes if COMPILE_FOR_LINUX
+                  If COMPILE_FOR_LPC21, PhilipsDownload() 'acts as' main():
+                  - it should not be static and should return int.
+                  - no sub-function can use exit() but only return ()
+                  Use 'char' instead of 'byte' ;)
+1.23  2005-01-16  Build in automatic detection of LPC chiptype
+                  (needed for 256 KByte support)
+1.24B 2005-06-02  Changes by Thiadmer Riemersma: completed support for other
+                  chip types (LPC213x series and others).
+1.24C 2005-06-11  Changes by Thiadmer Riemersma: added the device ID codes for
+                  chip types LPC2131 and LPC2132.
+1.25  2005-06-19  Martin Maurer: Setup more parameters in DCB,
+                  otherwise wrong code is downloaded (only Windows and Cygwin)
+                  when a previous program has changed these parameters
+                  Check exact string of "G 0 A\r\n0\r\n" instead of whole received buffer,
+                  to prevent checking of already received by program start
+                  (error on running program, but reports CMD_SUCCESS)
+                  Add ifdefs for all baudrates (needed only for high baudrate,
+                  which seem to be not available on Macs...)
+1.26  2005-06-26  Martin Maurer:
+                  Correct check again: "G 0 A\r\n0\r\n" is cutted, because of reboot
+                  (error on running program, but reports CMD_SUCCESS)
+1.27  2005-06-29  Martin Maurer:
+                  Add LPC chip ID's (thanks to Robert from Philips) for
+                  missing LPC213x and upcoming new LPC214x chips
+                  (currently untested, because i don't have access to these chips,
+                  please give me feedback !)
+1.28  2005-07-27  Anders Rosvall / Embedded Artists AB:
+                  Changed the reset timeout to 500 ms when entering the bootloader.
+                  Some external reset controllers have quite long timeout periods,
+                  so extening the timeout delay would be a good thing.
+1.29  2005-09-14  Rob Jansen:
+                  Added functionality to download to RAM and run from there.
+                  In LoadFile() added record types 04 (Extended Linear Address Record)
+                  and 05 (Start Linear Address Record), added address offset
+                  (IspEnvironment->BinaryOffset) and start address (...->StartAddress).
+                  Changed PhilipsDownload to skip all Flash prepare/erase/copy commands.
+                  Note: Tested with VC7 only
+1.30   2005-10-04 Rob Jansen:
+                  - forgot to change the version string in 1.29
+                  - Wrong text in LoadFile corrected (printed text mentions record type 05,
+                    this should be 04
+                  - Changed LoadFile to accept multiple record types 04
+                  - Changed LoadFile to check on memory size, will not load more than x MB
+                    if linear extended address records are used
+1.31   2005-11-13 Martin Maurer: Thanks to Frank Gutmann
+                  Updated number of sectors in device table
+                  for LPC2194, LPC2292 and LPC2294
+1.32   2005-12-02 Martin Maurer: Corrected missing control of RTS/DTR
+                  in case user selected -termonly and -control
+                  Small correction (typo in debug)
+1.33   2006-10-01 Jean-Marc Koller:
+                  Added support for MacOS X (difference on how to set termios baudrate).
+1.34   2006-10-01  Cyril Holweck:
+                  Made it compile again for lpc21isp
+                  Added const keyword to constant variables to make it better
+                  code for embeded target. (decrease RAM usage)
+                  Replaced all regular call to printf() by DebugPrintf()
+                  Removed call to scanf() (not much usefull and cost a lot to my target)
+1.35   2006-22-01 Cyril Holweck
+                  Added feature for LPC21: will start downloading at Sector 1 and upward,
+                  to finish with Sector 0, the one containing the checksum controling BSL entry
+1.36   2006-25-01 Cyril Holweck
+                  PhilipsDownload() will now return a unique error code for each error
+1.37   2006-10-03 Jeroen Domburg
+                  Added LPC2103 (and only the 2103, I can't find the IDs for 2101/2102)
+                  Corrected a loop which occured if the program completely fits in sector 0
+1.38   2007-01-05 Ray Molenkamp
+                  Added feature for LPC21: Wipe entire device before programming to enable
+                  reflashing of chips with the lpc codeprotection feature enabled.
+1.39   2007-01-12 Martin Maurer
+                  Added initial support for new processors LPC23xx and LPC24xx
+1.40   2007-01-22 Martin Maurer
+                  Correction of chip id of LPC2458
+1.41   2007-01-28 Jean-Marc Koller
+                  Modified Terminal() to disable ECHO with termios only once, instead of
+                  modifying and restoring termios in each getch and kbhit call (which caused
+                  a strange echo behaviour in MacOS X).
+1.42   2007-01-28 Rob Probin
+                  Added -localecho command to allow local echoing in terminal mode for use
+                  where target does not echo back keystrokes.
+1.43   2007-01-29 Martin Maurer
+                  Moved keyboard handling routines to own subroutines,
+                  so they can be used during aborting synchronisation.
+                  Newest cygwin made problems, StringOscillator always contained '\0x0d'
+                  at the end, when calling lpc21isp from batch file
+1.44   2007-02-23 Yang Yang
+                  Added feature for LPC21: Verify the data in Flash after every writes
+                  to sector. To detect errors in writing to Flash ROM.
+1.45   2007-02-25 Martin Maurer
+                  Replace printf syntax of DumpString by a simple pointer to a string
+                  printf syntax is a nice thing, but it is not working :-(
+                  and therefore makes debugging much more difficult...
+                  Moved VERSION_STR to top of file to avoid possible cosmetical errors
+1.46   2007-02-25 Martin Maurer
+                  Again corrected debug output: should solve output of
+                  (FFFFFFB5) instead of (B5)
+1.47   2007-02-27 Robert Adsett
+                  Raised timeout on AD send packet function.
+1.48   2007-04-20 Martin Maurer
+                  Thanks to Josef Wolf for preventing to overwrite over end of array
+1.49   2007-10-16 New Option -halfduplex allow single wire using.
+                  Implemented and tested only for Windows. Data Resend implemented.
+1.50   2007-10-31 Changes by Simon Ellwood
+                  Formated the code for readablity
+                  Fixed some c++ compiler issues
+1.51   2007-11-20 Changes by Simon Ellwood
+                  Split into seperate files
+                  Made more modular so when used in an embedded mode only the required code is built
+1.52   2008-01-22 Changes by Manuel Koeppen
+                  Made compileable again for linux and windows
+                  Fixed bug in ClearSerialPortBuffers (linux)
+1.53   2008-02-25 Changes by Michael Roth
+                  Get priority of debug messages wih -control right
+1.54   2008-03-03 Martin Maurer
+                  Try to bring lpc21isp back to a useable state in Windows, Cygwin, Linux and Mac OS.
+                  Merged in changes by Erika Stefanini, which were done only for old version 1.49:
+                  Added device ids for revision B chips
+1.55   2008-03-03 Martin Maurer
+                  Thanks to Fausto Marzoli, bugfix for compiling latest version under Linux
+1.56   2008-04-01 Steve Franks
+                  Integrate FreeBSD patch.
+                  Add support for swapping and/or inverting RTS & DTR
+1.57   2008-04-06 Mauricio Scaff
+                  Changed OpenSerialPort to work with MacOS
+                  Corrected the number of sectors in some 512K devices (28 instead of 27)
+                  Added support for LPC2387 and LPC2388
+                  Defined BL error 19 (Code Protected)
+1.58   2008-05-10 Herbert Demmel dh2@demmel.com
+                  I had the special requirement to integrate the program into my own Windows
+                  software compiled with Borland C++ Builder 5. I had to do some minor changes
+                  for Borland (see defined __BORLANDC__) and modified to code slightly to have
+                  some simple callbacks for screen i/o (see define INTEGRATED_IN_WIN_APP).
+                  Please notet that I don *not* check / modify the part for AnalogDevices !!
+                  Besides that I fixed some minor issues:
+                  added dcb.fOutxCtsFlow = FALSE and dcb.fOutxDsrFlow = FALSE (sometimes required)
+                  Now comparing one character less of answer to "Now launching ... code" command
+1.59   2008-07-07 Peter Hayward
+                  Fixed freeze under Windows XP SP2 by removing redundant call to SetCommMask.
+1.60   2008-07-21 Martin Maurer
+                  Added uptodate part ids for LPC2458, LPC2468 and LPC2478
+                  Add comment "obsolete" for older part ids for LPC2458 and LPC2468
+                  Add ", " between compile date and time
+1.61   2008-10-21 Fausto Marzoli (thanks to Geoffrey Wossum for the patches)
+                  Fix for compiling latest version under Linux and "ControlLinesSwapped" issue
+1.62   2008-11-19 Martin Maurer
+                  Added (untested) support for LPC2109
+                  Added (untested) support for LPC2361 / LPC2362
+                  Heavy update of part identification number of LPC23xx and LPC24xx
+                  Correct bug, that hex file must exist, when "-detectonly" is used
+                  Correct Makefile.vc: use /Fe instead of -o
+1.63   2008-11-23 Martin Maurer
+                  Changed to GNU Lesser General Public License
+1.64   2009-01-19 Steve Franks
+                  __FREEBSD__ changed to __FreeBSD__ at some point, plus other com port fixes
+1.65   2009-03-26 Vito Marolda
+                  Added pre-erasure of sector 0 to invalidate checksum before starting
+                  modification of the other sectors, so that the bootloader restarts
+                  if programming gets aborted while writing on a non-empty part.
+1.66   2009-03-26 Vito Marolda
+                  Corrected interpretation of intel hex record 03 which is execution start address
+                  and not data segment address
+1.67   2009-04-19 SASANO Takayoshi
+                  Add OpenBSD support
+1.68   2009-05-17 Martin Maurer
+                  Merge in changes done by Bruno Quoitin (baudrate problem when __APPLE__ is used)
+                  Remove TABs from source code and replaced them with spaces
+1.69   2009-06-18 Martin Maurer
+                  Add support for LPC17xx devices
+1.70   2009-06-29 Martin Maurer
+                  Further improvement of LPC17xx support
+                  Workaround for booter (4.1) of LPC17xx, which does not echo all sent characters (0D,0A,...)
+                  ISP command GO seems to be broken:
+                  Sending 'G 196 T(0A)'
+                  Answer(Length=15): 'G 196 T(0A)0(0D)(0A)'
+                  leads to 'prefetch_abort_exception(0D)(0A)1FFF07A5'
+                  No solution known...need your help here...
+                  Manual workaround: Use DTR and RTS toggling to start application (e.g. 2 batch files)
+1.71   2009-07-19 Martin Maurer
+                  Added LPC17xx with CPUID starting with 0x26 (not according user manual)
+1.72   2009-09-14 Martin Maurer
+                  Add support for LPC13xx devices
+1.73   2009-09-14 Martin Maurer
+                  Correct again (hopefully the last time) the CPUIDs for some LPC17xx devices
+                  (Now according to User Manual LPC17xx Version 00.07 (31 July 2009))
+1.74   2009-09-14 Mario Ivancic
+                  Added support for multiple HEX files, besed on internal version 1.37B.
+                  NOTE: this feature is used in production in 1.37B but is not tested in this version.
+                  Added numeric debug level command line switch -debugn, n=[0-5]
+                  Added command line scitch -try n to specify nQuestionMarks limit. Defaul: 100
+                  Merged in DoNotStart patch from cgommel_new
+                  Static functions declarations moved from lpc21isp.h to this file
+                  Modified LoadFile() to return error_code instead exit(1)
+                  Removed IspEnvironment.debug_level, all code uses global debug_level
+1.75   2010-01-05 Martin Maurer
+                  Added support for LPC11xx devices (not tested at all)
+                  Changed Product in LPC_DEVICE_TYPE from number to string to distinguish new LPC11 devices
+                  Changed "unsigned" to "unsigned int" in LPC_DEVICE_TYPE
+1.76   2010-02-01 Published test version without source code
+1.77   2010-02-01 Martin Maurer
+                  Corrected chip id of LPC1342 and LPC1343
+                  Added a new chip type for LPC11xx and LPC13xx microcontrollers
+                  Use higher area of RAM with LPC11xx and LPC13xx, because lower RAM is occupied by ISP
+                  Add code to lpcprog.c to read unique id, but not yet activate.
+                  Adapt block sizes for copying for each model of LPC11xx and LPC13xx
+1.78   2010-02-16 Martin Maurer
+                  Corrected chip id of LPC1751
+                  Added support for LPC1759, LPC1767 and LPC1769
+1.79   2010-02-19 Andrew Pines
+                  Added __APPLE__ flag to CFLAGS in Makefile to detect and handle OS X
+                  Added -Wall to Makefile to report warnings more comprehensively
+                  Added #define in lpc21isp.h to substitute strnicmp with strncasecmp (needed for Unix)
+                  Fixed a few format specifiers in lpcprog.c to eliminate some warnings
+1.80   2010-03-04 Philip Munts
+                  Added entries to LPCtypes[] in lpcprog.c for obsolete revisions of LPC2364/6/8/78.
+                  Added entry to LPCtypes[] in lpcprog.c for new LPC2387.
+1.81   2011-03-30 Mario Ivancic
+                  As per message #517 from Thiadmer Riemersma, removed WaitForWatchDog and WatchDogSeconds
+                  in PhilipsDownload().
+1.82   2011-06-25 Moses McKnight
+                  Corrected MaxCopySize for a number of the LPC11xx series
+                  Added support for several more LPC11xx and LPC11Cxx series
+1.83   2011-08-02 Martin Maurer
+                  Thanks to Conurus for detecting and fixing a bug with patching checksum
+                  (patching was too early, chip id was not yet available)
+                  (Re-)Added code to start downloaded via "G 0 T", when using LPC1xxx
+                  (Starting code at position 0 seems to work, compare to comment of version 1.70)
+                  Changed some occurances of Philips to NXP
+                  Added -static to Makefile (thanks to Camilo)
+                  Added support for LPC1311/01 and LPC1313/01 (they have separate identifiers)
+                  Correct flash size of LPC1342 to 16 KByte (thanks to Decio)
+                  Abort programming when unknown NXP chip id is detected
+*/
+
+// Please don't use TABs in the source code !!!
+
+// Don't forget to update the version string that is on the next line
+#define VERSION_STR "1.83"
+
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+static char RxTmpBuf[256];        // save received data to this buffer for half-duplex
+char * pRxTmpBuf = RxTmpBuf;
+#endif
+
+#if !defined COMPILE_FOR_LPC21
+int debug_level = 2;
+#endif
+
+static void ControlModemLines(ISP_ENVIRONMENT *IspEnvironment, unsigned char DTR, unsigned char RTS);
+static unsigned char Ascii2Hex(unsigned char c);
+
+#ifdef COMPILE_FOR_WINDOWS
+static void SerialTimeoutSet(ISP_ENVIRONMENT *IspEnvironment, unsigned timeout_milliseconds);
+static int SerialTimeoutCheck(ISP_ENVIRONMENT *IspEnvironment);
+#endif // COMPILE_FOR_WINDOWS
+
+static int AddFileHex(ISP_ENVIRONMENT *IspEnvironment, const char *arg);
+static int AddFileBinary(ISP_ENVIRONMENT *IspEnvironment, const char *arg);
+static int LoadFile(ISP_ENVIRONMENT *IspEnvironment, const char *filename, int FileFormat);
+
+#define ERR_RECORD_TYPE_LOADFILE	55 /** File record type not yet implemented. */
+#define ERR_ALLOC_FILE_LIST 60
+#define ERR_FILE_OPEN_HEX	61	/**< Couldn't open hex file. */
+#define ERR_FILE_SIZE_HEX	62	/**< Unexpected hex file size. */
+#define ERR_FILE_ALLOC_HEX	63	/**< Couldn't allocate enough memory for hex file. */
+#define ERR_FILE_ALLOC_BIN	64	/**< Couldn't allocate enough memory for bin file. */
+#define ERR_FILE_RECST_HEX	65	/**< Can't find start of record indicator for Intel Hex file.*/
+#define ERR_FILE_OPEN_BIN	66	/**< Couldn't open binary file. */
+#define ERR_FILE_SIZE_BIN	67	/**< Unexpected binary file size. */
+#define ERR_FILE_WRITE_BIN	68	/**< Couldn't write debug binary file to disk. How's that for ironic? */
+#define ERR_MEMORY_RANGE    69  /**< Out of memory range. */
+
+/************* Portability layer. Serial and console I/O differences    */
+/* are taken care of here.                                              */
+
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+static void OpenSerialPort(ISP_ENVIRONMENT *IspEnvironment)
+{
+    DCB    dcb;
+    COMMTIMEOUTS commtimeouts;
+
+    IspEnvironment->hCom = CreateFile(IspEnvironment->serial_port, GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
+
+    if (IspEnvironment->hCom == INVALID_HANDLE_VALUE)
+    {
+        DebugPrintf(1, "Can't open COM-Port %s ! - Error: %ld\n", IspEnvironment->serial_port, GetLastError());
+        exit(2);
+    }
+
+    DebugPrintf(3, "COM-Port %s opened...\n", IspEnvironment->serial_port);
+
+    GetCommState(IspEnvironment->hCom, &dcb);
+    dcb.BaudRate    = atol(IspEnvironment->baud_rate);
+    dcb.ByteSize    = 8;
+    dcb.StopBits    = ONESTOPBIT;
+    dcb.Parity      = NOPARITY;
+    dcb.fDtrControl = DTR_CONTROL_DISABLE;
+    dcb.fOutX       = FALSE;
+    dcb.fInX        = FALSE;
+    dcb.fNull       = FALSE;
+    dcb.fRtsControl = RTS_CONTROL_DISABLE;
+
+    // added by Herbert Demmel - iF CTS line has the wrong state, we would never send anything!
+    dcb.fOutxCtsFlow = FALSE;
+    dcb.fOutxDsrFlow = FALSE;
+
+    if (SetCommState(IspEnvironment->hCom, &dcb) == 0)
+    {
+        DebugPrintf(1, "Can't set baudrate %s ! - Error: %ld", IspEnvironment->baud_rate, GetLastError());
+        exit(3);
+    }
+
+   /*
+    *  Peter Hayward 02 July 2008
+    *
+    *  The following call is only needed if the WaitCommEvent
+    *  or possibly the GetCommMask functions are used.  They are
+    *  *not* in this implimentation.  However, under Windows XP SP2
+    *  on my laptop the use of this call causes XP to freeze (crash) while
+    *  this program is running, e.g. in section 5/6/7 ... of a largish
+    *  download.  Removing this *unnecessary* call fixed the problem.
+    *  At the same time I've added a call to SetupComm to request
+    *  (not necessarity honoured) the operating system to provide
+    *  large I/O buffers for high speed I/O without handshaking.
+    *
+    *   SetCommMask(IspEnvironment->hCom,EV_RXCHAR | EV_TXEMPTY);
+    */
+    SetupComm(IspEnvironment->hCom, 32000, 32000);
+
+    SetCommMask(IspEnvironment->hCom, EV_RXCHAR | EV_TXEMPTY);
+
+    commtimeouts.ReadIntervalTimeout         = MAXDWORD;
+    commtimeouts.ReadTotalTimeoutMultiplier  =    0;
+    commtimeouts.ReadTotalTimeoutConstant    =    1;
+    commtimeouts.WriteTotalTimeoutMultiplier =    0;
+    commtimeouts.WriteTotalTimeoutConstant   =    0;
+    SetCommTimeouts(IspEnvironment->hCom, &commtimeouts);
+}
+#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+#if defined COMPILE_FOR_LINUX
+static void OpenSerialPort(ISP_ENVIRONMENT *IspEnvironment)
+{
+    IspEnvironment->fdCom = open(IspEnvironment->serial_port, O_RDWR | O_NOCTTY | O_NONBLOCK);
+
+    if (IspEnvironment->fdCom < 0)
+    {
+        int err = errno;
+        DebugPrintf(1, "Can't open COM-Port %s ! (Error: %dd (0x%X))\n", IspEnvironment->serial_port, err, err);
+        exit(2);
+    }
+
+    DebugPrintf(3, "COM-Port %s opened...\n", IspEnvironment->serial_port);
+
+    /* clear input & output buffers, then switch to "blocking mode" */
+    tcflush(IspEnvironment->fdCom, TCOFLUSH);
+    tcflush(IspEnvironment->fdCom, TCIFLUSH);
+    fcntl(IspEnvironment->fdCom, F_SETFL, fcntl(IspEnvironment->fdCom, F_GETFL) & ~O_NONBLOCK);
+
+    tcgetattr(IspEnvironment->fdCom, &IspEnvironment->oldtio); /* save current port settings */
+
+    bzero(&IspEnvironment->newtio, sizeof(IspEnvironment->newtio));
+    IspEnvironment->newtio.c_cflag = CS8 | CLOCAL | CREAD;
+
+#if defined(__FreeBSD__) || defined(__OpenBSD__)
+
+    if(cfsetspeed(&IspEnvironment->newtio,(speed_t) strtol(IspEnvironment->baud_rate,NULL,10))) {
+                  DebugPrintf(1, "baudrate %s not supported\n", IspEnvironment->baud_rate);
+                  exit(3);
+              };
+#else
+
+#ifdef __APPLE__
+#define NEWTERMIOS_SETBAUDARTE(bps) IspEnvironment->newtio.c_ispeed = IspEnvironment->newtio.c_ospeed = bps;
+#else
+#define NEWTERMIOS_SETBAUDARTE(bps) IspEnvironment->newtio.c_cflag |= bps;
+#endif
+
+    switch (atol(IspEnvironment->baud_rate))
+    {
+#ifdef B1152000
+          case 1152000: NEWTERMIOS_SETBAUDARTE(B1152000); break;
+#endif // B1152000
+#ifdef B576000
+          case  576000: NEWTERMIOS_SETBAUDARTE(B576000); break;
+#endif // B576000
+#ifdef B230400
+          case  230400: NEWTERMIOS_SETBAUDARTE(B230400); break;
+#endif // B230400
+#ifdef B115200
+          case  115200: NEWTERMIOS_SETBAUDARTE(B115200); break;
+#endif // B115200
+#ifdef B57600
+          case   57600: NEWTERMIOS_SETBAUDARTE(B57600); break;
+#endif // B57600
+#ifdef B38400
+          case   38400: NEWTERMIOS_SETBAUDARTE(B38400); break;
+#endif // B38400
+#ifdef B19200
+          case   19200: NEWTERMIOS_SETBAUDARTE(B19200); break;
+#endif // B19200
+#ifdef B9600
+          case    9600: NEWTERMIOS_SETBAUDARTE(B9600); break;
+#endif // B9600
+
+          // Special value
+          // case   32000: NEWTERMIOS_SETBAUDARTE(32000); break;
+
+          default:
+              {
+                  DebugPrintf(1, "unknown baudrate %s\n", IspEnvironment->baud_rate);
+                  exit(3);
+              }
+    }
+
+#endif
+
+    IspEnvironment->newtio.c_iflag = IGNPAR | IGNBRK | IXON | IXOFF;
+    IspEnvironment->newtio.c_oflag = 0;
+
+    /* set input mode (non-canonical, no echo,...) */
+    IspEnvironment->newtio.c_lflag = 0;
+
+    cfmakeraw(&IspEnvironment->newtio);
+    IspEnvironment->newtio.c_cc[VTIME]    = 1;   /* inter-character timer used */
+    IspEnvironment->newtio.c_cc[VMIN]     = 0;   /* blocking read until 0 chars received */
+
+    tcflush(IspEnvironment->fdCom, TCIFLUSH);
+    if(tcsetattr(IspEnvironment->fdCom, TCSANOW, &IspEnvironment->newtio))
+    {
+       DebugPrintf(1, "Could not change serial port behaviour (wrong baudrate?)\n");
+       exit(3);
+    }
+
+}
+#endif // defined COMPILE_FOR_LINUX
+
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+static void CloseSerialPort(ISP_ENVIRONMENT *IspEnvironment)
+{
+    CloseHandle(IspEnvironment->hCom);
+}
+
+#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+#if defined COMPILE_FOR_LINUX
+static void CloseSerialPort(ISP_ENVIRONMENT *IspEnvironment)
+{
+    tcflush(IspEnvironment->fdCom, TCOFLUSH);
+    tcflush(IspEnvironment->fdCom, TCIFLUSH);
+    tcsetattr(IspEnvironment->fdCom, TCSANOW, &IspEnvironment->oldtio);
+
+    close(IspEnvironment->fdCom);
+}
+#endif // defined COMPILE_FOR_LINUX
+
+
+/***************************** SendComPortBlock *************************/
+/**  Sends a block of bytes out the opened com port.
+\param [in] s block to send.
+\param [in] n size of the block.
+*/
+void SendComPortBlock(ISP_ENVIRONMENT *IspEnvironment, const void *s, size_t n)
+{
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+    unsigned long realsize;
+    size_t m;
+    unsigned long rxsize;
+    char * pch;
+    char * rxpch;
+#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+    DumpString(4, s, n, "Sending ");
+
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+    if (IspEnvironment->HalfDuplex == 0)
+    {
+        WriteFile(IspEnvironment->hCom, s, n, &realsize, NULL);
+    }
+    else
+    {
+        pch = (char *)s;
+        rxpch = RxTmpBuf;
+        pRxTmpBuf = RxTmpBuf;
+
+        // avoid buffer otherflow
+        if (n > sizeof (RxTmpBuf))
+            n = sizeof (RxTmpBuf);
+
+        for (m = 0; m < n; m++)
+        {
+            WriteFile(IspEnvironment->hCom, pch, 1, &realsize, NULL);
+
+            if ((*pch != '?') || (n != 1))
+            {
+                do
+                {
+                    ReadFile(IspEnvironment->hCom, rxpch, 1, &rxsize, NULL);
+                }while (rxsize == 0);
+            }
+            pch++;
+            rxpch++;
+        }
+        *rxpch = 0;        // terminate echo string
+    }
+#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_LPC21
+
+    write(IspEnvironment->fdCom, s, n);
+
+#endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_LPC21
+}
+
+/***************************** SendComPort ******************************/
+/**  Sends a string out the opened com port.
+\param [in] s string to send.
+*/
+void SendComPort(ISP_ENVIRONMENT *IspEnvironment, const char *s)
+{
+    SendComPortBlock(IspEnvironment, s, strlen(s));
+}
+
+/***************************** SerialTimeoutTick ************************/
+/**  Performs a timer tick.  In this simple case all we do is count down
+with protection against underflow and wrapping at the low end.
+*/
+static void SerialTimeoutTick(ISP_ENVIRONMENT *IspEnvironment)
+{
+    if (IspEnvironment->serial_timeout_count <= 1)
+    {
+        IspEnvironment->serial_timeout_count = 0;
+    }
+    else
+    {
+        IspEnvironment->serial_timeout_count--;
+    }
+}
+
+
+/***************************** ReceiveComPortBlock **********************/
+/**  Receives a buffer from the open com port. Returns all the characters
+ready (waits for up to 'n' milliseconds before accepting that no more
+characters are ready) or when the buffer is full. 'n' is system dependant,
+see SerialTimeout routines.
+\param [out] answer buffer to hold the bytes read from the serial port.
+\param [in] max_size the size of buffer pointed to by answer.
+\param [out] real_size pointer to a long that returns the amout of the
+buffer that is actually used.
+*/
+static void ReceiveComPortBlock(ISP_ENVIRONMENT *IspEnvironment,
+                                          void *answer, unsigned long max_size,
+                                          unsigned long *real_size)
+{
+    char tmp_string[32];
+
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+    if (IspEnvironment->HalfDuplex == 0)
+        ReadFile(IspEnvironment->hCom, answer, max_size, real_size, NULL);
+    else
+    {
+        *real_size = strlen (pRxTmpBuf);
+        if (*real_size)
+        {
+            if (max_size >= *real_size)
+            {
+                strncpy((char*) answer, pRxTmpBuf, *real_size);
+                RxTmpBuf[0] = 0;
+                pRxTmpBuf = RxTmpBuf;
+            }
+            else
+            {
+                strncpy((char*) answer, pRxTmpBuf, max_size);
+                *real_size = max_size;
+                pRxTmpBuf += max_size;
+            }
+        }
+        else
+            ReadFile(IspEnvironment->hCom, answer, max_size, real_size, NULL);
+    }
+
+#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_LPC21
+
+    *real_size = read(IspEnvironment->fdCom, answer, max_size);
+
+#endif // defined COMPILE_FOR_LINUX
+
+    sprintf(tmp_string, "Read(Length=%ld): ", (*real_size));
+    DumpString(5, answer, (*real_size), tmp_string);
+
+    if (*real_size == 0)
+    {
+        SerialTimeoutTick(IspEnvironment);
+    }
+}
+
+
+/***************************** SerialTimeoutSet *************************/
+/**  Sets (or resets) the timeout to the timout period requested.  Starts
+counting to this period.  This timeout support is a little odd in that the
+timeout specifies the accumulated deadtime waiting to read not the total
+time waiting to read. They should be close enought to the same for this
+use. Used by the serial input routines, the actual counting takes place in
+ReceiveComPortBlock.
+\param [in] timeout_milliseconds the time in milliseconds to use for
+timeout.  Note that just because it is set in milliseconds doesn't mean
+that the granularity is that fine.  In many cases (particularly Linux) it
+will be coarser.
+*/
+static void SerialTimeoutSet(ISP_ENVIRONMENT *IspEnvironment, unsigned timeout_milliseconds)
+{
+#if defined COMPILE_FOR_LINUX
+    IspEnvironment->serial_timeout_count = timeout_milliseconds / 100;
+#elif defined COMPILE_FOR_LPC21
+    IspEnvironment->serial_timeout_count = timeout_milliseconds * 200;
+#else
+    IspEnvironment->serial_timeout_count = timeout_milliseconds;
+#endif
+}
+
+
+
+/***************************** SerialTimeoutCheck ***********************/
+/**  Check to see if the serial timeout timer has run down.
+\retval 1 if timer has run out.
+\retval 0 if timer still has time left.
+*/
+static int SerialTimeoutCheck(ISP_ENVIRONMENT *IspEnvironment)
+{
+    if (IspEnvironment->serial_timeout_count == 0)
+    {
+        return 1;
+    }
+    return 0;
+}
+
+
+#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
+/***************************** getch ************************************/
+/** Replacement for the common dos function of the same name. Reads a
+single unbuffered character from the 'keyboard'.
+\return The character read from the keyboard.
+*/
+int getch(void)
+{
+    char ch;
+
+    /* Read in one character */
+    read(0,&ch,1);
+
+    return ch;
+}
+#endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
+
+#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
+/***************************** kbhit ************************************/
+/** Replacement for the common dos function of the same name. Indicates if
+there are characters to be read from the console.
+\retval 0 No characters ready.
+\retval 1 Characters from the console ready to be read.
+*/
+int kbhit(void)
+{
+    /* return 0 for no key pressed, 1 for key pressed */
+    int return_value = 0;
+
+    /* time struct for the select() function, to only wait a little while */
+    struct timeval select_time;
+    /* file descriptor variable for the select() call */
+    fd_set readset;
+
+    /* we're only interested in STDIN */
+    FD_ZERO(&readset);
+    FD_SET(STDIN_FILENO, &readset);
+
+    /* how long to block for - this must be > 0.0, but could be changed
+    to some other setting. 10-18msec seems to work well and only
+    minimally load the system (0% CPU loading) */
+    select_time.tv_sec = 0;
+    select_time.tv_usec = 10;
+
+    /* is there a keystroke there? */
+    if (select(1, &readset, NULL, NULL, &select_time))
+    {
+        /* yes, remember it */
+        return_value = 1;
+    }
+
+
+    /* return with what we found out */
+    return return_value;
+}
+struct termios keyboard_origtty;
+#endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
+
+
+/***************************** PrepareKeyboardTtySettings ***************/
+/** Set the keyboard tty to be able to check for new characters via kbhit
+getting them via getch
+*/
+
+void PrepareKeyboardTtySettings(void)
+{
+#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
+    /* store the current tty settings */
+    if (!tcgetattr(0, &keyboard_origtty))
+    {
+        struct termios tty;
+        /* start with the current settings */
+        tty = keyboard_origtty;
+        /* make modifications to put it in raw mode, turn off echo */
+        tty.c_lflag &= ~ICANON;
+        tty.c_lflag &= ~ECHO;
+        tty.c_lflag &= ~ISIG;
+        tty.c_cc[VMIN] = 1;
+        tty.c_cc[VTIME] = 0;
+
+        /* put the settings into effect */
+        tcsetattr(0, TCSADRAIN, &tty);
+    }
+#endif
+}
+
+
+/***************************** ResetKeyboardTtySettings *****************/
+/** Reset the keyboard tty to original settings
+*/
+void ResetKeyboardTtySettings(void)
+{
+#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
+    /* reset the tty to its original settings */
+    tcsetattr(0, TCSADRAIN, &keyboard_origtty);
+#endif
+}
+
+
+#if !defined COMPILE_FOR_LPC21
+/***************************** ControlModemLines ************************/
+/**  Controls the modem lines to place the microcontroller into various
+states during the programming process.
+error rather abruptly terminates the program.
+\param [in] DTR the state to set the DTR line to.
+\param [in] RTS the state to set the RTS line to.
+*/
+static void ControlModemLines(ISP_ENVIRONMENT *IspEnvironment, unsigned char DTR, unsigned char RTS)
+{
+    //handle wether to invert the control lines:
+    DTR ^= IspEnvironment->ControlLinesInverted;
+    RTS ^= IspEnvironment->ControlLinesInverted;
+
+    //handle wether to swap the control lines
+    if (IspEnvironment->ControlLinesSwapped)
+    {
+        unsigned char tempRTS;
+        tempRTS = RTS;
+        RTS = DTR;
+        DTR = tempRTS;
+    }
+
+#if defined COMPILE_FOR_LINUX
+    int status;
+
+    if (ioctl(IspEnvironment->fdCom, TIOCMGET, &status) == 0)
+    {
+        DebugPrintf(3, "ioctl get ok, status = %X\n",status);
+    }
+    else
+    {
+        DebugPrintf(1, "ioctl get failed\n");
+    }
+
+    if (DTR) status |=  TIOCM_DTR;
+    else    status &= ~TIOCM_DTR;
+
+    if (RTS) status |=  TIOCM_RTS;
+    else    status &= ~TIOCM_RTS;
+
+    if (ioctl(IspEnvironment->fdCom, TIOCMSET, &status) == 0)
+    {
+        DebugPrintf(3, "ioctl set ok, status = %X\n",status);
+    }
+    else
+    {
+        DebugPrintf(1, "ioctl set failed\n");
+    }
+
+    if (ioctl(IspEnvironment->fdCom, TIOCMGET, &status) == 0)
+    {
+        DebugPrintf(3, "ioctl get ok, status = %X\n",status);
+    }
+    else
+    {
+        DebugPrintf(1, "ioctl get failed\n");
+    }
+
+#endif // defined COMPILE_FOR_LINUX
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+    if (DTR) EscapeCommFunction(IspEnvironment->hCom, SETDTR);
+    else    EscapeCommFunction(IspEnvironment->hCom, CLRDTR);
+
+    if (RTS) EscapeCommFunction(IspEnvironment->hCom, SETRTS);
+    else    EscapeCommFunction(IspEnvironment->hCom, CLRRTS);
+
+#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+#if defined COMPILE_FOR_LPC21
+    LPC_RESET(DTR);
+    LPC_BSL(RTS);
+#endif
+
+    DebugPrintf(3, "DTR (%d), RTS (%d)\n", DTR, RTS);
+}
+
+
+/***************************** ClearSerialPortBuffers********************/
+/**  Empty the serial port buffers.  Cleans things to a known state.
+*/
+void ClearSerialPortBuffers(ISP_ENVIRONMENT *IspEnvironment)
+{
+#if defined COMPILE_FOR_LINUX
+    /* variables to store the current tty state, create a new one */
+    struct termios origtty, tty;
+
+    /* store the current tty settings */
+    tcgetattr(IspEnvironment->fdCom, &origtty);
+
+    // Flush input and output buffers
+    tty=origtty;
+    tcsetattr(IspEnvironment->fdCom, TCSAFLUSH, &tty);
+
+    /* reset the tty to its original settings */
+    tcsetattr(IspEnvironment->fdCom, TCSADRAIN, &origtty);
+#endif // defined COMPILE_FOR_LINUX
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+    PurgeComm(IspEnvironment->hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
+#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+}
+#endif // !defined COMPILE_FOR_LPC21
+
+
+#if defined COMPILE_FOR_LINUX
+/***************************** Sleep ************************************/
+/**  Provide linux replacement for windows function.
+\param [in] Milliseconds the time to wait for in milliseconds.
+*/
+void Sleep(unsigned long MilliSeconds)
+{
+    usleep(MilliSeconds*1000); //convert to microseconds
+}
+#endif // defined COMPILE_FOR_LINUX
+
+
+#if defined COMPILE_FOR_LPC21
+/**  Provide linux replacement for windows function.
+\note I implement that one in my private header file today...
+\param [in] Milliseconds the time to wait for in milliseconds.
+*/
+/*static void Sleep(unsigned long MilliSeconds)
+{
+#   warning Sleep function not implemented
+}
+*/
+#endif // defined COMPILE_FOR_LPC21
+
+
+
+/************* Applicationlayer.                                        */
+
+#if !defined COMPILE_FOR_LPC21
+/***************************** DebugPrintf ******************************/
+/**  Prints a debug string depending the current debug level. The higher
+the debug level the more detail that will be printed.  Each print
+has an associated level, the higher the level the more detailed the
+debugging information being sent.
+\param [in] level the debug level of the print statement, if the level
+is less than or equal to the current debug level it will be printed.
+\param [in] fmt a standard printf style format string.
+\param [in] ... the usual printf parameters.
+*/
+#if !defined INTEGRATED_IN_WIN_APP
+void DebugPrintf(int level, const char *fmt, ...)
+{
+    va_list ap;
+
+    if (level <= debug_level)
+    {
+        char pTemp[2000];
+        va_start(ap, fmt);
+        //vprintf(fmt, ap);
+        vsprintf(pTemp, fmt, ap);
+        TRACE(pTemp);
+        va_end(ap);
+        fflush(stdout);
+    }
+}
+#endif
+#endif // !defined COMPILE_FOR_LPC21
+
+
+/***************************** ReceiveComPort ***************************/
+/**  Receives a buffer from the open com port. Returns when the buffer is
+filled, the numer of requested linefeeds has been received or the timeout
+period has passed
+\param [in] ISPEnvironment.
+\param [out] Answer buffer to hold the bytes read from the serial port.
+\param [in] MaxSize the size of buffer pointed to by Answer.
+\param [out] RealSize pointer to a long that returns the amout of the
+buffer that is actually used.
+\param [in] WantedNr0x0A the maximum number of linefeeds to accept before
+returning.
+\param [in] timeOutMilliseconds the maximum amount of time to wait before
+reading with an incomplete buffer.
+*/
+void ReceiveComPort(ISP_ENVIRONMENT *IspEnvironment,
+                                    const char *Ans, unsigned long MaxSize,
+                                    unsigned long *RealSize, unsigned long WantedNr0x0A,
+                                    unsigned timeOutMilliseconds)
+{
+    unsigned long tmp_realsize;
+    unsigned long nr_of_0x0A = 0;
+    unsigned long nr_of_0x0D = 0;
+    int eof = 0;
+    unsigned long p;
+    unsigned char *Answer;
+    char tmp_string[32];
+
+    Answer = (unsigned char*) Ans;
+
+    SerialTimeoutSet(IspEnvironment, timeOutMilliseconds);
+
+    (*RealSize) = 0;
+
+    do
+    {
+        ReceiveComPortBlock(IspEnvironment, Answer + (*RealSize), MaxSize - 1 - (*RealSize), &tmp_realsize);
+
+        if (tmp_realsize != 0)
+        {
+            for (p = (*RealSize); p < (*RealSize) + tmp_realsize; p++)
+            {
+                if (Answer[p] == 0x0a)
+                {
+                    nr_of_0x0A++;
+                }
+                else if (Answer[p] == 0x0d)
+                {
+                    nr_of_0x0D++;
+                }
+                else if (((signed char) Answer[p]) < 0)
+                {
+                    eof = 1;
+                }
+            }
+        }
+
+        (*RealSize) += tmp_realsize;
+
+    } while (((*RealSize) < MaxSize) && (SerialTimeoutCheck(IspEnvironment) == 0) && (nr_of_0x0A < WantedNr0x0A) && (nr_of_0x0D < WantedNr0x0A) && !eof);
+
+    Answer[(*RealSize)] = 0;
+
+    sprintf(tmp_string, "Answer(Length=%ld): ", (*RealSize));
+    DumpString(3, Answer, (*RealSize), tmp_string);
+}
+
+
+#if !defined COMPILE_FOR_LPC21
+
+/***************************** ReceiveComPortBlockComplete **************/
+/**  Receives a fixed block from the open com port. Returns when the
+block is completely filled or the timeout period has passed
+\param [out] block buffer to hold the bytes read from the serial port.
+\param [in] size the size of the buffer pointed to by block.
+\param [in] timeOut the maximum amount of time to wait before guvung up on
+completing the read.
+\return 0 if successful, non-zero otherwise.
+*/
+int ReceiveComPortBlockComplete(ISP_ENVIRONMENT *IspEnvironment,
+                                                    void *block, size_t size, unsigned timeout)
+{
+    unsigned long realsize = 0, read;
+    char *result;
+    char tmp_string[32];
+
+    result = (char*) block;
+
+    SerialTimeoutSet(IspEnvironment, timeout);
+
+    do
+    {
+        ReceiveComPortBlock(IspEnvironment, result + realsize, size - realsize, &read);
+
+        realsize += read;
+
+    } while ((realsize < size) && (SerialTimeoutCheck(IspEnvironment) == 0));
+
+    sprintf(tmp_string, "Answer(Length=%ld): ", realsize);
+    DumpString(3, result, realsize, tmp_string);
+
+    if (realsize != size)
+    {
+        return 1;
+    }
+    return 0;
+}
+
+/***************************** ReadArguments ****************************/
+/**  Reads the command line arguments and parses it for the various
+options. Uses the same arguments as main.  Used to separate the command
+line parsing from main and improve its readability.  This should also make
+it easier to modify the command line parsing in the future.
+\param [in] argc the number of arguments.
+\param [in] argv an array of pointers to the arguments.
+*/
+static void ReadArguments(ISP_ENVIRONMENT *IspEnvironment, unsigned int argc, char *argv[])
+{
+    unsigned int i;
+
+    if (argc >= 5)
+    {
+        for (i = 1; i < argc - 3; i++)
+        {
+            if (stricmp(argv[i], "-wipe") == 0)
+            {
+                IspEnvironment->WipeDevice = 1;
+                DebugPrintf(3, "Wipe entire device before writing.\n");
+                continue;
+            }
+
+            if (stricmp(argv[i], "-bin") == 0)
+            {
+                IspEnvironment->FileFormat = FORMAT_BINARY;
+                DebugPrintf(3, "Binary format file input.\n");
+                continue;
+            }
+
+            if (stricmp(argv[i], "-hex") == 0)
+            {
+                IspEnvironment->FileFormat = FORMAT_HEX;
+                DebugPrintf(3, "Hex format file input.\n");
+                continue;
+            }
+
+            if (stricmp(argv[i], "-logfile") == 0)
+            {
+                IspEnvironment->LogFile = 1;
+                DebugPrintf(3, "Log terminal output.\n");
+                continue;
+            }
+
+            if (stricmp(argv[i], "-detectonly") == 0)
+            {
+                IspEnvironment->DetectOnly  = 1;
+                IspEnvironment->ProgramChip = 0;
+                DebugPrintf(3, "Only detect LPC chip part id.\n");
+                continue;
+            }
+
+            if(strnicmp(argv[i],"-debug", 6) == 0)
+            {
+                char* num;
+                num = argv[i] + 6;
+                while(*num && isdigit(*num) == 0) num++;
+                if(isdigit(*num) != 0) debug_level = atoi( num);
+                else debug_level = 4;
+                DebugPrintf(3, "Turn on debug, level: %d.\n", debug_level);
+                continue;
+            }
+
+            if (stricmp(argv[i], "-DoNotStart") == 0)
+            {
+                IspEnvironment->DoNotStart = 1;
+                DebugPrintf(3, "Do NOT start MCU after programming.\n");
+                continue;
+            }
+
+            if (stricmp(argv[i], "-control") == 0)
+            {
+                IspEnvironment->ControlLines = 1;
+                DebugPrintf(3, "Use RTS/DTR to control target state.\n");
+                continue;
+            }
+
+            if (stricmp(argv[i], "-controlswap") == 0)
+            {
+                IspEnvironment->ControlLinesSwapped = 1;
+                DebugPrintf(3, "Use RTS to control reset, and DTR to control P0.14(ISP).\n");
+                continue;
+            }
+
+            if (stricmp(argv[i], "-controlinv") == 0)
+            {
+                IspEnvironment->ControlLinesInverted = 1;
+                DebugPrintf(3, "Invert state of RTS & DTR (0=true/assert/set, 1=false/deassert/clear).\n");
+                continue;
+            }
+
+            if (stricmp(argv[i], "-halfduplex") == 0)
+            {
+                IspEnvironment->HalfDuplex = 1;
+                DebugPrintf(3, "halfduplex serial communication.\n");
+                continue;
+            }
+
+            if (stricmp(argv[i], "-ADARM") == 0)
+            {
+                IspEnvironment->micro = ANALOG_DEVICES_ARM;
+                DebugPrintf(2, "Target: Analog Devices.\n");
+                continue;
+            }
+
+            if (stricmp(argv[i], "-NXPARM") == 0 || stricmp(argv[i], "-PHILIPSARM") == 0)
+            {
+                IspEnvironment->micro = NXP_ARM;
+                DebugPrintf(2, "Target: NXP.\n");
+                continue;
+            }
+
+            if (stricmp(argv[i], "-Verify") == 0)
+            {
+                IspEnvironment->Verify = 1;
+                DebugPrintf(2, "Verify after copy RAM to Flash.\n");
+                continue;
+            }
+
+#ifdef INTEGRATED_IN_WIN_APP
+            if (stricmp(argv[i], "-nosync") == 0)
+            {
+                IspEnvironment->NoSync = 1;
+                DebugPrintf(2, "Performing no syncing, already done.\n");
+                continue;
+            }
+#endif
+
+#ifdef TERMINAL_SUPPORT
+            if (CheckTerminalParameters(IspEnvironment, argv[i]))
+            {
+                continue;
+            }
+#endif
+
+            if(*argv[i] == '-') DebugPrintf( 2, "Unknown command line option: \"%s\"\n", argv[i]);
+            else
+            {
+                int ret_val;
+                if(IspEnvironment->FileFormat == FORMAT_HEX)
+                {
+                    ret_val = AddFileHex(IspEnvironment, argv[i]);
+                }
+                else
+                {
+                    ret_val = AddFileBinary(IspEnvironment, argv[i]);
+                }
+                if( ret_val != 0)
+                {
+                    DebugPrintf( 2, "Unknown command line option: \"%s\"\n", argv[i]);
+                }
+            }
+        }
+
+        // Newest cygwin delivers a '\x0d' at the end of argument
+        // when calling lpc21isp from batch file
+        for (i = 0; i < strlen(argv[argc - 1]) && i < (sizeof(IspEnvironment->StringOscillator) - 1) &&
+            argv[argc - 1][i] >= '0' && argv[argc - 1][i] <= '9'; i++)
+        {
+            IspEnvironment->StringOscillator[i] = argv[argc - 1][i];
+        }
+        IspEnvironment->StringOscillator[i] = 0;
+
+        IspEnvironment->serial_port = argv[argc - 3];
+        IspEnvironment->baud_rate = argv[argc - 2];
+    }
+
+    if (argc < 5)
+    {
+        debug_level = (debug_level < 2) ? 2 : debug_level;
+    }
+
+    if (argc < 5)
+    {
+        DebugPrintf(2, "\n"
+                       "Portable command line ISP\n"
+                       "for NXP LPC1000 / LPC2000 family and Analog Devices ADUC 70xx\n"
+                       "Version " VERSION_STR " compiled for " COMPILED_FOR ": " __DATE__ ", " __TIME__ "\n"
+                       "Copyright (c) by Martin Maurer, 2003-2011, Email: Martin.Maurer@clibb.de\n"
+                       "Portions Copyright (c) by Aeolus Development 2004, www.aeolusdevelopment.com\n"
+                       "\n");
+
+        DebugPrintf(1, "Syntax:  lpc21isp [Options] file[ file[ ...]] comport baudrate Oscillator_in_kHz\n\n"
+                       "Example: lpc21isp test.hex com1 115200 14746\n\n"
+                       "Options: -bin         for uploading binary file\n"
+                       "         -hex         for uploading file in intel hex format (default)\n"
+                       "         -term        for starting terminal after upload\n"
+                       "         -termonly    for starting terminal without an upload\n"
+                       "         -localecho   for local echo in terminal\n"
+                       "         -detectonly  detect only used LPC chiptype (NXPARM only)\n"
+                       "         -debug0      for no debug\n"
+                       "         -debug3      for progress info only\n"
+                       "         -debug5      for full debug\n"
+                       "         -donotstart  do not start MCU after download\n"
+                       "         -try<n>      try n times to synchronise\n"
+                       "         -wipe        Erase entire device before upload\n"
+                       "         -control     for controlling RS232 lines for easier booting\n"
+                       "                      (Reset = DTR, EnableBootLoader = RTS)\n"
+#ifdef INTEGRATED_IN_WIN_APP
+                       "         -nosync      Do not synchronize device via '?'\n"
+#endif
+                       "         -controlswap swap RS232 control lines\n"
+                       "                      (Reset = RTS, EnableBootLoader = DTR)\n"
+                       "         -controlinv  Invert state of RTS & DTR \n"
+                       "                      (0=true/assert/set, 1=false/deassert/clear).\n"
+                       "         -verify      Verify the data in Flash after every writes to\n"
+                       "                      sector. To detect errors in writing to Flash ROM\n"
+                       "         -logfile     for enabling logging of terminal output to lpc21isp.log\n"
+                       "         -halfduplex  use halfduplex serial communication (i.e. with K-Line)\n"
+                       "         -ADARM       for downloading to an Analog Devices\n"
+                       "                      ARM microcontroller ADUC70xx\n"
+                       "         -NXPARM      for downloading to a NXP LPC1xxx/LPC2xxx (default)\n");
+
+        exit(1);
+    }
+
+    if (IspEnvironment->micro == NXP_ARM)
+    {
+        // If StringOscillator is bigger than 100 MHz, there seems to be something wrong
+        if (strlen(IspEnvironment->StringOscillator) > 5)
+        {
+            DebugPrintf(1, "Invalid crystal frequency %s\n", IspEnvironment->StringOscillator);
+            exit(1);
+        }
+    }
+}
+
+/***************************** ResetTarget ******************************/
+/**  Resets the target leaving it in either download (program) mode or
+run mode.
+\param [in] mode the mode to leave the target in.
+*/
+void ResetTarget(ISP_ENVIRONMENT *IspEnvironment, TARGET_MODE mode)
+{
+    if (IspEnvironment->ControlLines)
+    {
+        switch (mode)
+        {
+        /* Reset and jump to boot loader.                       */
+        case PROGRAM_MODE:
+            ControlModemLines(IspEnvironment, 1, 1);
+            Sleep(100);
+            ClearSerialPortBuffers(IspEnvironment);
+            Sleep(100);
+            ControlModemLines(IspEnvironment, 0, 1);
+            //Longer delay is the Reset signal is conected to an external rest controller
+            Sleep(500);
+            // Clear the RTS line after having reset the micro
+            // Needed for the "GO <Address> <Mode>" ISP command to work */
+            ControlModemLines(IspEnvironment, 0, 0);
+            break;
+
+        /* Reset and start uploaded program                     */
+        case RUN_MODE:
+            ControlModemLines(IspEnvironment, 1, 0);
+            Sleep(100);
+            ClearSerialPortBuffers(IspEnvironment);
+            Sleep(100);
+            ControlModemLines(IspEnvironment, 0, 0);
+            Sleep(100);
+            break;
+        }
+    }
+}
+
+
+/***************************** Ascii2Hex ********************************/
+/**  Converts a hex character to its equivalent number value. In case of an
+error rather abruptly terminates the program.
+\param [in] c the hex digit to convert.
+\return the value of the hex digit.
+*/
+static unsigned char Ascii2Hex(unsigned char c)
+{
+    if (c >= '0' && c <= '9')
+    {
+        return (unsigned char)(c - '0');
+    }
+
+    if (c >= 'A' && c <= 'F')
+    {
+        return (unsigned char)(c - 'A' + 10);
+    }
+
+    if (c >= 'a' && c <= 'f')
+    {
+        return (unsigned char)(c - 'a' + 10);
+    }
+
+    DebugPrintf(1, "Wrong Hex-Nibble %c (%02X)\n", c, c);
+    exit(1);
+
+    return 0;  // this "return" will never be reached, but some compilers give a warning if it is not present
+}
+
+
+/***************************** AddFileHex *******************************/
+/**  Add a file to the list of files to read in, flag it as hex format.
+\param [in] IspEnvironment Programming environment.
+\param [in] arg The argument that was passed to the program as a file name.
+\return 0 on success, an error code otherwise.
+*/
+static int AddFileHex(ISP_ENVIRONMENT *IspEnvironment, const char *arg)
+{
+    FILE_LIST *entry;
+
+    // Add file to list.  If cannot allocate storage for node return an error.
+    entry = malloc(sizeof(FILE_LIST));
+    if( entry == 0)
+    {
+        DebugPrintf(1, "Error %d Could not allocated memory for file node %s\n", ERR_ALLOC_FILE_LIST, arg);
+        return  ERR_ALLOC_FILE_LIST;
+    }
+
+    // Build up entry and insert it at the start of the list.
+    entry->name = arg;
+    entry->prev = IspEnvironment->f_list;
+    entry->hex_flag = 1;
+    IspEnvironment->f_list = entry;
+
+    return 0;       // Success.
+}
+
+
+/***************************** AddFileBinary ****************************/
+/**  Add a file to the list of files to read in, flag it as binary format.
+\param [in] IspEnvironment Programming environment.
+\param [in] arg The argument that was passed to the program as a file name.
+\return 0 on success, an error code otherwise.
+*/
+static int AddFileBinary(ISP_ENVIRONMENT *IspEnvironment, const char *arg)
+{
+    FILE_LIST *entry;
+
+    // Add file to list. If cannot allocate storage for node return an error.
+    entry = malloc(sizeof(FILE_LIST));
+    if( entry == 0)
+    {
+        DebugPrintf( 1, "Error %d Could not allocated memory for file node %s\n", ERR_ALLOC_FILE_LIST, arg);
+        return  ERR_ALLOC_FILE_LIST;
+    }
+
+    // Build up entry and insert it at the start of the list.
+    entry->name = arg;
+    entry->prev = IspEnvironment->f_list;
+    entry->hex_flag = 0;
+    IspEnvironment->f_list = entry;
+
+    return 0;       // Success.
+}
+
+#if 0
+void ReadHexFile(ISP_ENVIRONMENT *IspEnvironment)
+{
+    LoadFile(IspEnvironment);
+
+    if (IspEnvironment->BinaryLength)
+    {
+        BINARY* FileContent = IspEnvironment->FileContent;
+
+        unsigned long  Pos;
+        unsigned char  RecordLength;
+        unsigned short RecordAddress;
+        unsigned long  RealAddress = 0;
+        unsigned char  RecordType;
+        unsigned char  Hexvalue;
+        unsigned long  StartAddress;
+        int            BinaryOffsetDefined = 0;
+        unsigned char  i;
+
+
+        DebugPrintf(3, "Converting file %s to binary format...\n", IspEnvironment->input_file);
+
+        Pos = 0;
+        while (Pos < IspEnvironment->BinaryLength)
+        {
+            if (FileContent[Pos] == '\r')
+            {
+                Pos++;
+                continue;
+            }
+
+            if (FileContent[Pos] == '\n')
+            {
+                Pos++;
+                continue;
+            }
+
+            if (FileContent[Pos] != ':')
+            {
+                DebugPrintf(1, "Missing start of record (':') wrong byte %c / %02X\n", FileContent[Pos], FileContent[Pos]);
+                exit(1);
+            }
+
+            Pos++;
+
+            RecordLength   = Ascii2Hex(FileContent[Pos++]);
+            RecordLength <<= 4;
+            RecordLength  |= Ascii2Hex(FileContent[Pos++]);
+
+            DebugPrintf(4, "RecordLength = %02X\n", RecordLength);
+
+            RecordAddress   = Ascii2Hex(FileContent[Pos++]);
+            RecordAddress <<= 4;
+            RecordAddress  |= Ascii2Hex(FileContent[Pos++]);
+            RecordAddress <<= 4;
+            RecordAddress  |= Ascii2Hex(FileContent[Pos++]);
+            RecordAddress <<= 4;
+            RecordAddress  |= Ascii2Hex(FileContent[Pos++]);
+
+            DebugPrintf(4, "RecordAddress = %04X\n", RecordAddress);
+
+            RealAddress = RealAddress - (RealAddress & 0xffff) + RecordAddress;
+
+            DebugPrintf(4, "RealAddress = %08lX\n", RealAddress);
+
+            RecordType      = Ascii2Hex(FileContent[Pos++]);
+            RecordType    <<= 4;
+            RecordType     |= Ascii2Hex(FileContent[Pos++]);
+
+            DebugPrintf(4, "RecordType = %02X\n", RecordType);
+
+            if (RecordType == 0x00)          // 00 - Data record
+            {
+                /*
+                * Binary Offset is defined as soon as first data record read
+                */
+
+                //BinaryOffsetDefined = 1;
+
+                // Memory for binary file big enough ?
+                while ((RealAddress + RecordLength - IspEnvironment->BinaryOffset) > IspEnvironment->BinaryMemSize)
+                {
+                    IspEnvironment->BinaryMemSize <<= 1;    // Double the size allocated !!!
+                    IspEnvironment->BinaryContent = (BINARY*) realloc(IspEnvironment->BinaryContent, IspEnvironment->BinaryMemSize);
+                }
+
+                // We need to know, what the highest address is,
+                // how many bytes / sectors we must flash
+                if (RealAddress + RecordLength - IspEnvironment->BinaryOffset > IspEnvironment->BinaryLength)
+                {
+                    IspEnvironment->BinaryLength = RealAddress + RecordLength - IspEnvironment->BinaryOffset;
+                    DebugPrintf(3, "Image size now: %ld\n", IspEnvironment->BinaryLength);
+                }
+
+                for (i = 0; i < RecordLength; i++)
+                {
+                    Hexvalue        = Ascii2Hex(FileContent[Pos++]);
+                    Hexvalue      <<= 4;
+                    Hexvalue       |= Ascii2Hex(FileContent[Pos++]);
+                    IspEnvironment->BinaryContent[RealAddress + i - IspEnvironment->BinaryOffset] = Hexvalue;
+                }
+            }
+            else if (RecordType == 0x01)     // 01 - End of file record
+            {
+                break;
+            }
+            else if (RecordType == 0x02)     // 02 - Extended segment address record
+            {
+                for (i = 0; i < RecordLength * 2; i++)   // double amount of nibbles
+                {
+                    RealAddress <<= 4;
+                    if (i == 0)
+                    {
+                        RealAddress  = Ascii2Hex(FileContent[Pos++]);
+                    }
+                    else
+                    {
+                        RealAddress |= Ascii2Hex(FileContent[Pos++]);
+                    }
+                }
+                RealAddress <<= 4;
+            }
+            else if (RecordType == 0x03)     // 03 - Start segment address record
+            {
+                for (i = 0; i < RecordLength * 2; i++)   // double amount of nibbles
+                {
+                    RealAddress <<= 4;
+                    if (i == 0)
+                    {
+                        RealAddress  = Ascii2Hex(FileContent[Pos++]);
+                    }
+                    else
+                    {
+                        RealAddress |= Ascii2Hex(FileContent[Pos++]);
+                    }
+                }
+                RealAddress <<= 8;
+            }
+            else if (RecordType == 0x04)     // 04 - Extended linear address record, used by IAR
+            {
+                for (i = 0; i < RecordLength * 2; i++)   // double amount of nibbles
+                {
+                    RealAddress <<= 4;
+                    if (i == 0)
+                    {
+                        RealAddress  = Ascii2Hex(FileContent[Pos++]);
+                    }
+                    else
+                    {
+                        RealAddress |= Ascii2Hex(FileContent[Pos++]);
+                    }
+                }
+                RealAddress <<= 16;
+                if (!BinaryOffsetDefined)
+                {
+                    // set startaddress of BinaryContent
+                    // use of LPC_FLASHMASK to allow a memory range, not taking the first
+                    // [04] record as actual start-address.
+                    IspEnvironment->BinaryOffset = RealAddress & LPC_FLASHMASK;
+                }
+                else
+                {
+                    if ((RealAddress & LPC_FLASHMASK) != IspEnvironment->BinaryOffset)
+                    {
+                        DebugPrintf(1, "New Extended Linear Address Record [04] out of memory range\n"
+                                       "Current Memory starts at: 0x%08X, new Address is: 0x%08X",
+                                       IspEnvironment->BinaryOffset, RealAddress);
+                        exit(1);
+                    }
+                }
+            }
+            else if (RecordType == 0x05)     // 05 - Start linear address record
+            {
+                StartAddress = 0;
+                for (i = 0; i < RecordLength * 2; i++)   // double amount of nibbles
+                {
+                    StartAddress <<= 4;
+                    if (i == 0)
+                    {
+                        StartAddress  = Ascii2Hex(FileContent[Pos++]);
+                    }
+                    else
+                    {
+                        StartAddress |= Ascii2Hex(FileContent[Pos++]);
+                    }
+                }
+                DebugPrintf(1,"Start Address = 0x%08X\n", StartAddress);
+                IspEnvironment->StartAddress = StartAddress;
+            }
+
+            while (FileContent[Pos++] != 0x0a)      // Search till line end
+            {
+            }
+        }
+
+        DebugPrintf(2, "\tconverted to binary format...\n");
+
+        // When debugging is switched on, output result of conversion to file debugout.bin
+        if (debug_level >= 4)
+        {
+            int fdout;
+            fdout = open("debugout.bin", O_RDWR | O_BINARY | O_CREAT | O_TRUNC, 0777);
+            write(fdout, IspEnvironment->BinaryContent, IspEnvironment->BinaryLength);
+            close(fdout);
+        }
+    }
+}
+#endif // #if 0
+
+
+/***************************** LoadFile *********************************/
+/**  Loads the requested file to download into memory.
+\param [in] IspEnvironment  structure containing input filename
+\param [in] filename	the name of the file to read in.
+\param [in] FileFormat	the format of the file to read in (FORMAT_HEX or FORMAT_BINARY)
+\return 0 if successful, otherwise an error code.
+*/
+static int LoadFile(ISP_ENVIRONMENT *IspEnvironment, const char *filename, int FileFormat)
+{
+    int            fd;
+    int            i;
+    int            BinaryOffsetDefined;
+    unsigned long  Pos;
+    unsigned long  FileLength;
+    BINARY        *FileContent;              /**< Used to store the content of a hex */
+                                             /*   file before converting to binary.  */
+    unsigned long  BinaryMemSize;
+
+    fd = open(filename, O_RDONLY | O_BINARY);
+    if (fd == -1)
+    {
+        DebugPrintf(1, "Can't open file %s\n", filename);
+        return ERR_FILE_OPEN_HEX;
+    }
+
+    FileLength = lseek(fd, 0L, 2);      // Get file size
+
+    if (FileLength == (size_t)-1)
+    {
+        DebugPrintf(1, "\nFileLength = -1 !?!\n");
+        return ERR_FILE_SIZE_HEX;
+    }
+
+    lseek(fd, 0L, 0);
+
+    // Just read the entire file into memory to parse.
+    FileContent = (BINARY*) malloc(FileLength);
+
+    if( FileContent == 0)
+    {
+        DebugPrintf( 1, "\nCouldn't allocate enough memory for file.\n");
+        return ERR_FILE_ALLOC_HEX;
+    }
+
+    BinaryOffsetDefined = 0;
+
+    BinaryMemSize = IspEnvironment->BinaryLength;
+
+    read(fd, FileContent, FileLength);
+
+    close(fd);
+
+    DebugPrintf(2, "File %s:\n\tloaded...\n", filename);
+
+    // Intel-Hex -> Binary Conversion
+
+    if (FileFormat == FORMAT_HEX)
+    {
+        unsigned char  RecordLength;
+        unsigned short RecordAddress;
+        unsigned long  RealAddress = 0;
+        unsigned char  RecordType;
+        unsigned char  Hexvalue;
+        unsigned long  StartAddress;
+
+        DebugPrintf(3, "Converting file %s to binary format...\n", filename);
+
+        Pos = 0;
+        while (Pos < FileLength)
+        {
+            if (FileContent[Pos] == '\r')
+            {
+                Pos++;
+                continue;
+            }
+
+            if (FileContent[Pos] == '\n')
+            {
+                Pos++;
+                continue;
+            }
+
+            if (FileContent[Pos] != ':')
+            {
+                DebugPrintf(1, "Missing start of record (':') wrong byte %c / %02X\n", FileContent[Pos], FileContent[Pos]);
+                exit(1);
+            }
+
+            Pos++;
+
+            RecordLength   = Ascii2Hex(FileContent[Pos++]);
+            RecordLength <<= 4;
+            RecordLength  |= Ascii2Hex(FileContent[Pos++]);
+
+            DebugPrintf(4, "RecordLength = %02X\n", RecordLength);
+
+            RecordAddress   = Ascii2Hex(FileContent[Pos++]);
+            RecordAddress <<= 4;
+            RecordAddress  |= Ascii2Hex(FileContent[Pos++]);
+            RecordAddress <<= 4;
+            RecordAddress  |= Ascii2Hex(FileContent[Pos++]);
+            RecordAddress <<= 4;
+            RecordAddress  |= Ascii2Hex(FileContent[Pos++]);
+
+            DebugPrintf(4, "RecordAddress = %04X\n", RecordAddress);
+
+            RealAddress = RealAddress - (RealAddress & 0xffff) + RecordAddress;
+
+            DebugPrintf(4, "RealAddress = %08lX\n", RealAddress);
+
+            RecordType      = Ascii2Hex(FileContent[Pos++]);
+            RecordType    <<= 4;
+            RecordType     |= Ascii2Hex(FileContent[Pos++]);
+
+            DebugPrintf(4, "RecordType = %02X\n", RecordType);
+
+            if (RecordType == 0x00)          // 00 - Data record
+            {
+                /*
+                * Binary Offset is defined as soon as first data record read
+                */
+                BinaryOffsetDefined = 1;
+                // Memory for binary file big enough ?
+                while (RealAddress + RecordLength - IspEnvironment->BinaryOffset > BinaryMemSize)
+                {
+                    if(!BinaryMemSize) BinaryMemSize = FileLength * 2;
+                    else BinaryMemSize <<= 1;
+                    IspEnvironment->BinaryContent = realloc(IspEnvironment->BinaryContent, BinaryMemSize);
+                }
+
+                // We need to know, what the highest address is,
+                // how many bytes / sectors we must flash
+                if (RealAddress + RecordLength - IspEnvironment->BinaryOffset > IspEnvironment->BinaryLength)
+                {
+                    IspEnvironment->BinaryLength = RealAddress + RecordLength - IspEnvironment->BinaryOffset;
+                    DebugPrintf(3, "Image size now: %ld\n", IspEnvironment->BinaryLength);
+                }
+
+                for (i = 0; i < RecordLength; i++)
+                {
+                    Hexvalue        = Ascii2Hex(FileContent[Pos++]);
+                    Hexvalue      <<= 4;
+                    Hexvalue       |= Ascii2Hex(FileContent[Pos++]);
+                    IspEnvironment->BinaryContent[RealAddress + i - IspEnvironment->BinaryOffset] = Hexvalue;
+                }
+            }
+            else if (RecordType == 0x01)     // 01 - End of file record
+            {
+                break;
+            }
+            else if (RecordType == 0x02)     // 02 - Extended segment address record
+            {
+                for (i = 0; i < RecordLength * 2; i++)   // double amount of nibbles
+                {
+                    RealAddress <<= 4;
+                    if (i == 0)
+                    {
+                        RealAddress  = Ascii2Hex(FileContent[Pos++]);
+                    }
+                    else
+                    {
+                        RealAddress |= Ascii2Hex(FileContent[Pos++]);
+                    }
+                }
+                RealAddress <<= 4;
+            }
+            else if (RecordType == 0x03)     // 03 - Start segment address record
+            {
+                unsigned long cs,ip;
+                StartAddress = 0;
+                for (i = 0; i < RecordLength * 2; i++)   // double amount of nibbles
+                {
+                    StartAddress <<= 4;
+                    if (i == 0)
+                    {
+                        StartAddress  = Ascii2Hex(FileContent[Pos++]);
+                    }
+                    else
+                    {
+                        StartAddress |= Ascii2Hex(FileContent[Pos++]);
+                    }
+                }
+                cs = StartAddress >> 16; //high part
+                ip = StartAddress & 0xffff; //low part
+                StartAddress = cs*16+ip; //segmented 20-bit space
+                DebugPrintf(1,"Start Address = 0x%08X\n", StartAddress);
+                IspEnvironment->StartAddress = StartAddress;
+            }
+            else if (RecordType == 0x04)     // 04 - Extended linear address record, used by IAR
+            {
+                for (i = 0; i < RecordLength * 2; i++)   // double amount of nibbles
+                {
+                    RealAddress <<= 4;
+                    if (i == 0)
+                    {
+                        RealAddress  = Ascii2Hex(FileContent[Pos++]);
+                    }
+                    else
+                    {
+                        RealAddress |= Ascii2Hex(FileContent[Pos++]);
+                    }
+                }
+                RealAddress <<= 16;
+                if (!BinaryOffsetDefined)
+                {
+                    // set startaddress of BinaryContent
+                    // use of LPC_FLASHMASK to allow a memory range, not taking the first
+                    // [04] record as actual start-address.
+                    IspEnvironment->BinaryOffset = RealAddress & LPC_FLASHMASK;
+                }
+                else
+                {
+                    if ((RealAddress & LPC_FLASHMASK) != IspEnvironment->BinaryOffset)
+                    {
+                        DebugPrintf(1, "New Extended Linear Address Record [04] out of memory range\n");
+                        DebugPrintf(1, "Current Memory starts at: 0x%08X, new Address is: 0x%08X",
+                            IspEnvironment->BinaryOffset, RealAddress);
+                        return ERR_MEMORY_RANGE;
+                    }
+                }
+            }
+            else if (RecordType == 0x05)     // 05 - Start linear address record
+            {
+                StartAddress = 0;
+                for (i = 0; i < RecordLength * 2; i++)   // double amount of nibbles
+                {
+                    StartAddress <<= 4;
+                    if (i == 0)
+                    {
+                        StartAddress  = Ascii2Hex(FileContent[Pos++]);
+                    }
+                    else
+                    {
+                        StartAddress |= Ascii2Hex(FileContent[Pos++]);
+                    }
+                }
+                DebugPrintf(1,"Start Address = 0x%08X\n", StartAddress);
+                IspEnvironment->StartAddress = StartAddress;
+            }
+            else
+            {
+                free( FileContent);
+                DebugPrintf( 1, "Error %d RecordType %02X not yet implemented\n", ERR_RECORD_TYPE_LOADFILE, RecordType);
+                return( ERR_RECORD_TYPE_LOADFILE);
+            }
+
+            while (FileContent[Pos++] != 0x0a)      // Search till line end
+            {
+            }
+        }
+
+        DebugPrintf(2, "\tconverted to binary format...\n");
+
+        // When debugging is switched on, output result of conversion to file debugout.bin
+        if (debug_level >= 4)
+        {
+            int fdout;
+            fdout = open("debugout.bin", O_RDWR | O_BINARY | O_CREAT | O_TRUNC, 0777);
+            write(fdout, IspEnvironment->BinaryContent, IspEnvironment->BinaryLength);
+            close(fdout);
+        }
+
+        free( FileContent);		// Done with file contents
+    }
+    else // FORMAT_BINARY
+    {
+        IspEnvironment->BinaryContent = FileContent;
+        IspEnvironment->BinaryLength = FileLength;
+    }
+
+    DebugPrintf(2, "\timage size : %ld\n", IspEnvironment->BinaryLength);
+
+    return 0;
+}
+
+/***************************** LoadFiles1 ********************************/
+/**  Loads the requested files to download into memory.
+\param [in] IspEnvironment structure containing input filename(s).
+\param [in] file simple linked list of files to read
+\return 0 if successful, otherwise an error code.
+*/
+static int LoadFiles1(ISP_ENVIRONMENT *IspEnvironment, const FILE_LIST *file)
+{
+    int ret_val;
+
+    if(!file || !file->prev)
+    {
+        return -1;
+    }
+
+    DebugPrintf( 3, "Follow file list %s\n", file->name);
+
+    ret_val = LoadFiles1( IspEnvironment, file->prev);
+    if( ret_val != 0)
+    {
+        return ret_val;
+    }
+
+    DebugPrintf( 3, "Attempt to read File %s\n", file->name);
+    if(file->hex_flag != 0)
+    {
+        ret_val = LoadFile(IspEnvironment, file->name, FORMAT_HEX);
+    }
+    else
+    {
+		ret_val = LoadFile(IspEnvironment, file->name, FORMAT_BINARY);
+    }
+    if( ret_val != 0)
+    {
+		return ret_val;
+    }
+
+    return 0;
+}
+
+/***************************** LoadFiles ********************************/
+/**  Loads the requested files to download into memory.
+\param [in] IspEnvironment structure containing input filename(s).
+\param [in] file simple linked list of files to read
+\return 0 if successful, otherwise an error code.
+*/
+static int LoadFiles(ISP_ENVIRONMENT *IspEnvironment)
+{
+	int ret_val;
+
+    ret_val = LoadFiles1(IspEnvironment, IspEnvironment->f_list);
+    if( ret_val != 0)
+    {
+		exit(1); // return ret_val;
+    }
+
+	DebugPrintf( 2, "Image size : %ld\n", IspEnvironment->BinaryLength);
+
+    // check length to flash for correct alignment, can happen with broken ld-scripts
+    if (IspEnvironment->BinaryLength % 4 != 0)
+    {
+        unsigned long NewBinaryLength = ((IspEnvironment->BinaryLength + 3)/4) * 4;
+
+        DebugPrintf( 2, "Warning:  data not aligned to 32 bits, padded (length was %lX, now %lX)\n", IspEnvironment->BinaryLength, NewBinaryLength);
+
+        IspEnvironment->BinaryLength = NewBinaryLength;
+    }
+
+	// When debugging is switched on, output result of conversion to file debugout.bin
+    if(debug_level >= 4)
+    {
+         int fdout;
+		 DebugPrintf( 1, "Dumping image file.\n");
+         fdout = open("debugout.bin", O_RDWR | O_BINARY | O_CREAT | O_TRUNC, 0777);
+         write(fdout, IspEnvironment->BinaryContent, IspEnvironment->BinaryLength);
+         close(fdout);
+    }
+    return 0;
+}
+#endif // !defined COMPILE_FOR_LPC21
+
+#ifndef COMPILE_FOR_LPC21
+int PerformActions(ISP_ENVIRONMENT *IspEnvironment)
+{
+    int downloadResult = -1;
+
+    DebugPrintf(2, "lpc21isp version " VERSION_STR "\n");
+
+    /* Download requested, read in the input file.                  */
+    if (IspEnvironment->ProgramChip)
+    {
+        LoadFiles(IspEnvironment);
+    }
+
+    OpenSerialPort(IspEnvironment);   /* Open the serial port to the microcontroller. */
+
+    ResetTarget(IspEnvironment, PROGRAM_MODE);
+
+    ClearSerialPortBuffers(IspEnvironment);
+
+    /* Perform the requested download.                              */
+    if (IspEnvironment->ProgramChip || IspEnvironment->DetectOnly)
+    {
+        switch (IspEnvironment->micro)
+        {
+#ifdef LPC_SUPPORT
+        case NXP_ARM:
+            downloadResult = NxpDownload(IspEnvironment);
+            break;
+#endif
+
+#ifdef AD_SUPPORT
+        case ANALOG_DEVICES_ARM:
+            downloadResult = AnalogDevicesDownload(IspEnvironment);
+            break;
+#endif
+        }
+
+        if (downloadResult != 0)
+        {
+            CloseSerialPort(IspEnvironment);
+            exit(downloadResult);
+        }
+    }
+
+    if (IspEnvironment->StartAddress == 0 || IspEnvironment->TerminalOnly)
+    {
+        /* Only reset target if startaddress = 0
+        * Otherwise stay with the running program as started in Download()
+        */
+        ResetTarget(IspEnvironment, RUN_MODE);
+    }
+
+    debug_level = 1;    /* From now on there is no more debug output !! */
+                                        /* Therefore switch it off...                   */
+
+#ifdef TERMINAL_SUPPORT
+    // Pass control to Terminal which will provide a terminal if one was asked for
+    // User asked for terminal emulation, provide a really dumb terminal.
+    Terminal(IspEnvironment);
+#endif
+
+    CloseSerialPort(IspEnvironment);  /*  All done, close the serial port to the      */
+
+    return 0;
+}
+#endif
+
+/***************************** main *************************************/
+/**  main. Everything starts from here.
+\param [in] argc the number of arguments.
+\param [in] argv an array of pointers to the arguments.
+*/
+
+#if !defined COMPILE_FOR_LPC21
+
+#if defined INTEGRATED_IN_WIN_APP
+int AppDoProgram(int argc, char *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+    ISP_ENVIRONMENT IspEnvironment;
+
+    // Initialize debug level
+    debug_level = 2;
+
+    // Initialize ISP Environment
+    memset(&IspEnvironment, 0, sizeof(IspEnvironment));       // Clear the IspEnviroment to a known value
+    IspEnvironment.micro       = NXP_ARM;                     // Default Micro
+    IspEnvironment.FileFormat  = FORMAT_HEX;                  // Default File Format
+    IspEnvironment.ProgramChip = TRUE;                        // Default to Programming the chip
+    IspEnvironment.nQuestionMarks = 100;
+    IspEnvironment.DoNotStart = 0;
+    ReadArguments(&IspEnvironment, argc, argv);               // Read and parse the command line
+
+    return PerformActions(&IspEnvironment);                   // Do as requested !
+}
+
+#endif // !defined COMPILE_FOR_LPC21
+
+/***************************** DumpString ******************************/
+/**  Prints an area of memory to stdout. Converts non-printables to hex.
+\param [in] level the debug level of the block to be dumped.  If this is
+less than or equal to the current debug level than the dump will happen
+otherwise this just returns.
+\param [in] b pointer to an area of memory.
+\param [in] size the length of the memory block to print.
+\param [in] prefix string is a pointer to a prefix string.
+*/
+void DumpString(int level, const void *b, size_t size, const char *prefix_string)
+{
+    size_t i;
+    const char * s = (const char*) b;
+    unsigned char c;
+
+    DebugPrintf(level, prefix_string);
+
+    DebugPrintf(level, "'");
+    for (i = 0; i < size; i++)
+    {
+        c = s[i];
+        if (c >= 0x20 && c <= 0x7e) /*isprint?*/
+        {
+            DebugPrintf(level, "%c", c);
+        }
+        else
+        {
+            DebugPrintf(level, "(%02X)", c);
+        }
+    }
+    DebugPrintf(level, "'\n");
+}
+
+#if !defined COMPILE_FOR_LPC21
+int lpctest(char* FileName)
+{
+    ISP_ENVIRONMENT IspEnvironment;
+
+    // Initialize debug level
+    debug_level = 2;
+
+    // Initialize ISP Environment
+    memset(&IspEnvironment, 0, sizeof(IspEnvironment));        // Clear the IspEnviroment to a known value
+    IspEnvironment.micro        = NXP_ARM;                     // Default Micro
+    IspEnvironment.FileFormat   = FORMAT_HEX;                  // Default File Format
+    IspEnvironment.ProgramChip  = TRUE;                        // Default to Programming the chip
+    // IspEnvironment.input_file   = FileName;
+    IspEnvironment.ControlLines = TRUE;
+    IspEnvironment.serial_port  = "COM2";
+    IspEnvironment.baud_rate    = "19200";
+    IspEnvironment.nQuestionMarks = 100;
+    IspEnvironment.DoNotStart = 0;
+    strcpy(IspEnvironment.StringOscillator, "25000");
+
+    return PerformActions(&IspEnvironment);                    // Do as requested !
+}
+#endif
diff --git a/reform2-lpc-fw/tools/lpc21isp/lpc21isp.cbp b/reform2-lpc-fw/tools/lpc21isp/lpc21isp.cbp
new file mode 100644
index 0000000000000000000000000000000000000000..0069e37906320d0aed59bd88adfbfb6579c77c35
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/lpc21isp.cbp
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_project_file>
+	<FileVersion major="1" minor="6" />
+	<Project>
+		<Option title="lpc21isp" />
+		<Option pch_mode="2" />
+		<Option compiler="gcc" />
+		<Build>
+			<Target title="Debug">
+				<Option output="bin\Debug\lpc21isp" prefix_auto="1" extension_auto="1" />
+				<Option object_output="obj\Debug\" />
+				<Option type="1" />
+				<Option compiler="gcc" />
+				<Compiler>
+					<Add option="-g" />
+				</Compiler>
+			</Target>
+			<Target title="Release">
+				<Option output="bin\Release\lpc21isp" prefix_auto="1" extension_auto="1" />
+				<Option object_output="obj\Release\" />
+				<Option type="1" />
+				<Option compiler="gcc" />
+				<Compiler>
+					<Add option="-O2" />
+				</Compiler>
+				<Linker>
+					<Add option="-s" />
+				</Linker>
+			</Target>
+		</Build>
+		<Compiler>
+			<Add option="-Wall" />
+		</Compiler>
+		<Unit filename="adprog.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="adprog.h" />
+		<Unit filename="lpc21isp.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="lpc21isp.h" />
+		<Unit filename="lpcprog.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="lpcprog.h" />
+		<Unit filename="lpcterm.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="lpcterm.h" />
+		<Extensions>
+			<code_completion />
+			<envvars />
+			<debugger />
+			<lib_finder disable_auto="1" />
+		</Extensions>
+	</Project>
+</CodeBlocks_project_file>
diff --git a/reform2-lpc-fw/tools/lpc21isp/lpc21isp.h b/reform2-lpc-fw/tools/lpc21isp/lpc21isp.h
new file mode 100644
index 0000000000000000000000000000000000000000..0159faa0c1955f57195131f37324f400c8b6fe36
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/lpc21isp.h
@@ -0,0 +1,289 @@
+/******************************************************************************
+
+Project:           Portable command line ISP for NXP LPC1000 / LPC2000 family
+                   and Analog Devices ADUC70xx
+
+Filename:          lsp21isp.h
+
+Compiler:          Microsoft VC 6/7, Microsoft VS2008, Microsoft VS2010,
+                   GCC Cygwin, GCC Linux, GCC ARM ELF
+
+Author:            Martin Maurer (Martin.Maurer@clibb.de)
+
+Copyright:         (c) Martin Maurer 2003-2011, All rights reserved
+Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com
+
+    This file is part of lpc21isp.
+
+    lpc21isp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    any later version.
+
+    lpc21isp is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    and GNU General Public License along with lpc21isp.
+    If not, see <http://www.gnu.org/licenses/>.
+*/
+
+// #define INTEGRATED_IN_WIN_APP
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define COMPILE_FOR_WINDOWS
+#define COMPILED_FOR "Windows"
+#elif defined(__CYGWIN__)
+#define COMPILE_FOR_CYGWIN
+#define COMPILED_FOR "Cygwin"
+#elif defined(__arm__) || defined(__thumb__)
+#define COMPILE_FOR_LPC21
+#define COMPILED_FOR "ARM"
+#define printf iprintf
+#elif defined(__APPLE__)
+#define COMPILE_FOR_LINUX
+#define COMPILED_FOR "Apple MacOS X"
+#elif defined(__FreeBSD__)
+#define COMPILE_FOR_LINUX
+#define COMPILED_FOR "FreeBSD"
+#elif defined(__OpenBSD__)
+#define COMPILE_FOR_LINUX
+#define COMPILED_FOR "OpenBSD"
+#else
+#define COMPILE_FOR_LINUX
+#define COMPILED_FOR "Linux"
+#endif
+
+// The Required features can be enabled / disabled here
+#define LPC_SUPPORT
+
+#ifndef COMPILE_FOR_LPC21
+#define AD_SUPPORT
+#define TERMINAL_SUPPORT
+#endif
+
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+#include <windows.h>
+#include <io.h>
+#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+#if defined COMPILE_FOR_WINDOWS
+#include <conio.h>
+//#define TRACE(x) OutputDebugString(x)
+#define TRACE(x) printf("%s",x)
+#endif // defined COMPILE_FOR_WINDOWS
+
+#if defined COMPILE_FOR_CYGWIN
+//#define TRACE(x) OutputDebugString(x)
+#define TRACE(x) printf("%s",x)
+#endif // defined COMPILE_FOR_WINDOWS
+
+#if defined COMPILE_FOR_LINUX
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <sys/ioctl.h>
+extern void Sleep(unsigned long MilliSeconds);
+#define TRACE(x) printf("%s",x)
+#endif // defined COMPILE_FOR_LINUX
+
+#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
+#include <termios.h>
+#include <unistd.h>     // for read and return value of lseek
+#include <sys/time.h>   // for select_time
+extern int kbhit(void);
+extern int getch(void);
+extern struct termios keyboard_origtty;
+#endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_CYGWIN
+
+#include <ctype.h>      // isdigit()
+#include <stdio.h>      // stdout
+#include <stdarg.h>
+#include <time.h>
+#if defined (COMPILE_FOR_LINUX)
+#if defined(__OpenBSD__)
+#include <errno.h>
+#else
+#include <sys/errno.h>
+#endif
+#endif
+
+#if defined COMPILE_FOR_LPC21
+#include <stdlib.h>
+#include <string.h>
+//#include <lpc_ioctl.h>  // if using libc serial port communication
+#else
+#include <fcntl.h>
+#endif
+
+typedef enum
+{
+    NXP_ARM,
+    ANALOG_DEVICES_ARM
+} TARGET;
+
+typedef enum
+{
+    PROGRAM_MODE,
+    RUN_MODE
+} TARGET_MODE;
+
+typedef enum
+{
+    FORMAT_BINARY,
+    FORMAT_HEX
+} FILE_FORMAT_TYPE;
+
+typedef unsigned char BINARY;               // Data type used for microcontroller
+
+/** Used to create list of files to read in. */
+typedef struct file_list FILE_LIST;
+
+/** Structure used to build list of input files. */
+struct file_list
+{
+    const char *name;       /**< The name of the input file.	*/
+    FILE_LIST *prev;        /**< The previous file name in the list.*/
+    char hex_flag;          /**< True if the input file is hex.	*/
+};
+
+typedef struct
+{
+#if !defined COMPILE_FOR_LPC21
+    TARGET micro;                                // The type of micro that will be programmed.
+    FILE_FORMAT_TYPE FileFormat;
+    unsigned char ProgramChip;                // Normally set
+
+    unsigned char ControlLines;
+    unsigned char ControlLinesSwapped;
+    unsigned char ControlLinesInverted;
+    unsigned char LogFile;
+    FILE_LIST *f_list;                  // List of files to read in.
+    int nQuestionMarks; // how many times to try to synchronise
+    int DoNotStart;
+    char *serial_port;                  // Name of the serial port to use to
+                                        // communicate with the microcontroller.
+                                        // Read from the command line.
+#endif // !defined COMPILE_FOR_LPC21
+
+    unsigned char TerminalOnly;         // Declared here for lazyness saves ifdef's
+#ifdef TERMINAL_SUPPORT
+    unsigned char TerminalAfterUpload;
+    unsigned char LocalEcho;
+#endif
+
+    unsigned char HalfDuplex;           // Only used for LPC Programming
+    unsigned char DetectOnly;
+    unsigned char WipeDevice;
+    unsigned char Verify;
+    int           DetectedDevice;       /* index in LPCtypes[] array */
+    char *baud_rate;                    /**< Baud rate to use on the serial
+                                           * port communicating with the
+                                           * microcontroller. Read from the
+                                           * command line.                        */
+
+    char StringOscillator[6];           /**< Holds representation of oscillator
+                                           * speed from the command line.         */
+
+    BINARY *FileContent;
+    BINARY *BinaryContent;              /**< Binary image of the                  */
+                                          /* microcontroller's memory.            */
+    unsigned long BinaryLength;
+    unsigned long BinaryOffset;
+    unsigned long StartAddress;
+    unsigned long BinaryMemSize;
+
+#if defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+    HANDLE hCom;
+#endif // defined COMPILE_FOR_WINDOWS || defined COMPILE_FOR_CYGWIN
+
+#if defined COMPILE_FOR_LINUX || defined COMPILE_FOR_LPC21
+    int fdCom;
+#endif // defined COMPILE_FOR_LINUX || defined COMPILE_FOR_LPC21
+
+#if defined COMPILE_FOR_LINUX
+    struct termios oldtio, newtio;
+#endif // defined COMPILE_FOR_LINUX
+
+#ifdef INTEGRATED_IN_WIN_APP
+    unsigned char NoSync;
+#endif
+
+    unsigned serial_timeout_count;   /**< Local used to track timeouts on serial port read. */
+
+} ISP_ENVIRONMENT;
+
+#if defined COMPILE_FOR_LPC21
+
+#define DebugPrintf(in, ...)
+
+#else
+extern int debug_level;
+
+#if defined INTEGRATED_IN_WIN_APP
+
+#define DebugPrintf AppDebugPrintf
+void AppDebugPrintf(int level, const char *fmt, ...);
+
+#define exit(val)   AppException(val)
+void AppException(int exception_level);
+
+int AppDoProgram(int argc, char *argv[]);
+
+#define Exclude_kbhit 1
+int AppSyncing(int trials);
+void AppWritten(int size);
+
+#else
+void DebugPrintf(int level, const char *fmt, ...);
+//#define DebugPrintf(level, ...) if (level <= debug_level) { TRACE( __VA_ARGS__ ); }
+#endif
+
+void ClearSerialPortBuffers(ISP_ENVIRONMENT *IspEnvironment);
+
+#endif
+
+
+#if defined COMPILE_FOR_LINUX
+#define stricmp strcasecmp
+#define strnicmp strncasecmp
+#endif // defined COMPILE_FOR_LINUX
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif // O_BINARY
+
+#ifndef DWORD
+#define DWORD unsigned long
+#endif // DWORD
+
+/*
+debug levels
+0 - very quiet          - Nothing gets printed at this level
+1 - quiet               - Only error messages should be printed
+2 - indicate progress   - Add progress messages
+3 - first level debug   - Major level tracing
+4 - second level debug  - Add detailed debugging
+5 - log comm's          - log serial I/O
+*/
+
+
+void ReceiveComPort(ISP_ENVIRONMENT *IspEnvironment,
+                    const char *Ans, unsigned long MaxSize,
+                    unsigned long *RealSize, unsigned long WantedNr0x0A,
+                    unsigned timeOutMilliseconds);
+void PrepareKeyboardTtySettings(void);
+void ResetKeyboardTtySettings(void);
+void ResetTarget(ISP_ENVIRONMENT *IspEnvironment, TARGET_MODE mode);
+
+void DumpString(int level, const void *s, size_t size, const char *prefix_string);
+void SendComPort(ISP_ENVIRONMENT *IspEnvironment, const char *s);
+void SendComPortBlock(ISP_ENVIRONMENT *IspEnvironment, const void *s, size_t n);
+int ReceiveComPortBlockComplete(ISP_ENVIRONMENT *IspEnvironment, void *block, size_t size, unsigned timeout);
+void ClearSerialPortBuffers(ISP_ENVIRONMENT *IspEnvironment);
+
+int lpctest(char* FileName);
diff --git a/reform2-lpc-fw/tools/lpc21isp/lpc21isp.layout b/reform2-lpc-fw/tools/lpc21isp/lpc21isp.layout
new file mode 100644
index 0000000000000000000000000000000000000000..d6bec7763d291d7a860b2b32199f42bd5d8c8571
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/lpc21isp.layout
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_layout_file>
+	<ActiveTarget name="Release" />
+	<File name="lpc21isp.c" open="1" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+		<Cursor1 position="20180" topLine="309" />
+	</File>
+	<File name="lpc21isp.h" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+		<Cursor1 position="566" topLine="226" />
+	</File>
+	<File name="lpcprog.c" open="1" top="1" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+		<Cursor1 position="4072" topLine="74" />
+	</File>
+	<File name="lpcprog.h" open="1" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+		<Cursor1 position="0" topLine="63" />
+	</File>
+</CodeBlocks_layout_file>
diff --git a/reform2-lpc-fw/tools/lpc21isp/lpcprog.c b/reform2-lpc-fw/tools/lpc21isp/lpcprog.c
new file mode 100644
index 0000000000000000000000000000000000000000..36a74484bcecbee2261dd9fddaf7946d67855eb7
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/lpcprog.c
@@ -0,0 +1,1273 @@
+/******************************************************************************
+
+Project:           Portable command line ISP for NXP LPC1000 / LPC2000 family
+                   and Analog Devices ADUC70xx
+
+Filename:          lpcprog.c
+
+Compiler:          Microsoft VC 6/7, Microsoft VS2008, Microsoft VS2010,
+                   GCC Cygwin, GCC Linux, GCC ARM ELF
+
+Author:            Martin Maurer (Martin.Maurer@clibb.de)
+
+Copyright:         (c) Martin Maurer 2003-2011, All rights reserved
+Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com
+
+    This file is part of lpc21isp.
+
+    lpc21isp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    any later version.
+
+    lpc21isp is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    and GNU General Public License along with lpc21isp.
+    If not, see <http://www.gnu.org/licenses/>.
+*/
+
+// This file is for the Actual Programming of the LPC Chips
+
+#if defined(_WIN32)
+#if !defined __BORLANDC__
+#include "StdAfx.h"
+#endif
+#endif // defined(_WIN32)
+#include "lpc21isp.h"
+
+#ifdef LPC_SUPPORT
+#include "lpcprog.h"
+
+static const unsigned int SectorTable_210x[] =
+{
+    8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
+    8192, 8192, 8192, 8192, 8192, 8192, 8192
+};
+
+static const unsigned int SectorTable_2103[] =
+{
+    4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096
+};
+
+static const unsigned int SectorTable_2109[] =
+{
+    8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192
+};
+
+static const unsigned int SectorTable_211x[] =
+{
+    8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
+    8192, 8192, 8192, 8192, 8192, 8192, 8192,
+};
+
+static const unsigned int SectorTable_212x[] =
+{
+    8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
+    65536, 65536, 8192, 8192, 8192, 8192, 8192, 8192, 8192
+};
+
+// Used for devices with 500K (LPC2138 and LPC2148) and
+// for devices with 504K (1 extra 4k block at the end)
+static const unsigned int SectorTable_213x[] =
+{
+     4096,  4096,  4096,  4096,  4096,  4096,  4096,  4096,
+    32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
+    32768, 32768, 32768, 32768, 32768, 32768,  4096,  4096,
+     4096,  4096,  4096,  4096
+};
+
+// Used for LPC17xx devices
+static const unsigned int SectorTable_17xx[] =
+{
+     4096,  4096,  4096,  4096,  4096,  4096,  4096,  4096,
+     4096,  4096,  4096,  4096,  4096,  4096,  4096,  4096,
+    32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
+    32768, 32768, 32768, 32768, 32768, 32768
+};
+
+static int unsigned SectorTable_RAM[]  = { 65000 };
+
+static LPC_DEVICE_TYPE LPCtypes[] =
+{
+   { 0, 0, 0, 0, 0, 0, 0, CHIP_VARIANT_NONE },  /* unknown */
+
+   // id, name of product, flash size, ram size, total number of sector, max copy size, sector table, chip variant
+
+   { 0x2500102B, "1102",         32,  8,  8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+
+   { 0x041E502B, "1111.../101",   8,  2,  2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x2516D02B, "1111.../102",   8,  2,  2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x0416502B, "1111.../201",   8,  4,  2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x2516902B, "1111.../202",   8,  4,  2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x042D502B, "1112.../101",  16,  2,  4, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x2524D02B, "1112.../102",  16,  2,  4, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x0425502B, "1112.../201",  16,  4,  4, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x2524902B, "1112.../202",  16,  4,  4, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x0434502B, "1113.../201",  24,  4,  6, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x2532902B, "1113.../202",  24,  4,  6, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x0434102B, "1113.../301",  24,  8,  6, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x2532102B, "1113.../302",  24,  8,  6, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x0444502B, "1114.../201",  32,  4,  8, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x2540902B, "1114.../202",  32,  4,  8, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x1A40902B, "1114FN.../102",  32,  4,  8, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x0444102B, "1114.../301",  32,  8,  8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x2540102B, "1114.../302",  32,  8,  8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+
+   { 0x1421102B, "11C12.../301",  16,  8,  4, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x1440102B, "11C14.../301",  32,  8,  8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x1431102B, "11C22.../301",  16,  8,  4, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x1430102B, "11C24.../301",  32,  8,  8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+
+   { 0x0364002B, "1224.../101",  32,  8,  4, 2048, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x0364202B, "1224.../121",  48, 12, 32, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x0365002B, "1225.../301",  64, 16, 32, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x0365202B, "1225.../321",  80, 20, 32, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x0366002B, "1226",         96, 24, 32, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+   { 0x0367002B, "1227",        128, 32, 32, 4096, SectorTable_17xx, CHIP_VARIANT_LPC11XX },
+
+   { 0x2C42502B, "1311",          8,  4,  2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC13XX },
+   { 0x1816902B, "1311/01",       8,  4,  2, 1024, SectorTable_17xx, CHIP_VARIANT_LPC13XX },
+   { 0x2C40102B, "1313",         32,  8,  8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC13XX },
+   { 0x1830102B, "1313/01",      32,  8,  8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC13XX },
+   { 0x3D01402B, "1342",         16,  4,  4, 1024, SectorTable_17xx, CHIP_VARIANT_LPC13XX },
+   { 0x3D00002B, "1343",         32,  8,  8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC13XX },
+
+   { 0x25001118, "1751",         32,  8,  8, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+   { 0x25001121, "1752",         64, 16, 16, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+   { 0x25011722, "1754",        128, 32, 18, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+   { 0x25011723, "1756",        256, 32, 22, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+   { 0x25013F37, "1758",        512, 64, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+   { 0x25113737, "1759",        512, 64, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+   { 0x26011922, "1764",        128, 32, 18, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+   { 0x26013733, "1765",        256, 64, 22, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+   { 0x26013F33, "1766",        256, 64, 22, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+   { 0x26012837, "1767",        512, 64, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+   { 0x26013F37, "1768",        512, 64, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+   { 0x26113F37, "1769",        512, 64, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+
+   { 0x27011132, "1774",        128, 40, 18, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+   { 0x27191F43, "1776",        256, 80, 22, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+   { 0x27193747, "1777",        512, 96, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+   { 0x27193F47, "1778",        512, 96, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+   { 0x281D1743, "1785",        256, 80, 22, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+   { 0x281D1F43, "1786",        256, 80, 22, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+   { 0x281D3747, "1787",        512, 96, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+   { 0x281D3F47, "1788",        512, 96, 30, 4096, SectorTable_17xx, CHIP_VARIANT_LPC17XX },
+
+   { 0x0004FF11, "2103",         32,  8,  8, 4096, SectorTable_2103, CHIP_VARIANT_LPC2XXX },
+   { 0xFFF0FF12, "2104",        128, 16, 15, 8192, SectorTable_210x, CHIP_VARIANT_LPC2XXX },
+   { 0xFFF0FF22, "2105",        128, 32, 15, 8192, SectorTable_210x, CHIP_VARIANT_LPC2XXX },
+   { 0xFFF0FF32, "2106",        128, 64, 15, 8192, SectorTable_210x, CHIP_VARIANT_LPC2XXX },
+   { 0x0201FF01, "2109",         64,  8,  8, 4096, SectorTable_2109, CHIP_VARIANT_LPC2XXX },
+   { 0x0101FF12, "2114",        128, 16, 15, 8192, SectorTable_211x, CHIP_VARIANT_LPC2XXX },
+   { 0x0201FF12, "2119",        128, 16, 15, 8192, SectorTable_211x, CHIP_VARIANT_LPC2XXX },
+   { 0x0101FF13, "2124",        256, 16, 17, 8192, SectorTable_212x, CHIP_VARIANT_LPC2XXX },
+   { 0x0201FF13, "2129",        256, 16, 17, 8192, SectorTable_212x, CHIP_VARIANT_LPC2XXX },
+   { 0x0002FF01, "2131",         32,  8,  8, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x0002FF11, "2132",         64, 16,  9, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x0002FF12, "2134",        128, 16, 11, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x0002FF23, "2136",        256, 32, 15, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x0002FF25, "2138",        512, 32, 27, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x0402FF01, "2141",         32,  8,  8, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x0402FF11, "2142",         64, 16,  9, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x0402FF12, "2144",        128, 16, 11, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x0402FF23, "2146",        256, 40, 15, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x0402FF25, "2148",        512, 40, 27, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x0301FF13, "2194",        256, 16, 17, 8192, SectorTable_212x, CHIP_VARIANT_LPC2XXX },
+   { 0x0301FF12, "2210",          0, 16,  0, 8192, SectorTable_211x, CHIP_VARIANT_LPC2XXX }, /* table is a "don't care" */
+   { 0x0401FF12, "2212",        128, 16, 15, 8192, SectorTable_211x, CHIP_VARIANT_LPC2XXX },
+   { 0x0601FF13, "2214",        256, 16, 17, 8192, SectorTable_212x, CHIP_VARIANT_LPC2XXX },
+   /*            "2290"; same id as the LPC2210 */
+   { 0x0401FF13, "2292",        256, 16, 17, 8192, SectorTable_212x, CHIP_VARIANT_LPC2XXX },
+   { 0x0501FF13, "2294",        256, 16, 17, 8192, SectorTable_212x, CHIP_VARIANT_LPC2XXX },
+   { 0x00000000, "2361",        128, 34, 11, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x00000000, "2362",        128, 34, 11, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x0603FB02, "2364",        128, 34, 11, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 01 -- 6 July 2007 */
+   { 0x1600F902, "2364",        128, 34, 11, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x1600E823, "2365",        256, 58, 15, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x0603FB23, "2366",        256, 58, 15, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 01 -- 6 July 2007 */
+   { 0x1600F923, "2366",        256, 58, 15, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x1600E825, "2367",        512, 58, 15, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x0603FB25, "2368",        512, 58, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 01 -- 6 July 2007 */
+   { 0x1600F925, "2368",        512, 58, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x1700E825, "2377",        512, 58, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x0703FF25, "2378",        512, 58, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 01 -- 6 July 2007 */
+   { 0x1600FD25, "2378",        512, 58, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 01 -- 29 October 2007 */
+   { 0x1700FD25, "2378",        512, 58, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x1700FF35, "2387",        512, 98, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }, /* From UM10211 Rev. 03 -- 25 August 2008 */
+   { 0x1800F935, "2387",        512, 98, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x1800FF35, "2388",        512, 98, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x1500FF35, "2458",        512, 98, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x1600FF30, "2460",          0, 98,  0, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x1600FF35, "2468",        512, 98, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x1701FF30, "2470",          0, 98,  0, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX },
+   { 0x1701FF35, "2478",        512, 98, 28, 4096, SectorTable_213x, CHIP_VARIANT_LPC2XXX }
+};
+
+/***************************** NXP Download *********************************/
+/**  Download the file from the internal memory image to the NXP microcontroller.
+*   This function is visible from outside if COMPILE_FOR_LPC21
+*/
+
+static int SendAndVerify(ISP_ENVIRONMENT *IspEnvironment, const char *Command,
+                                 char *AnswerBuffer, int AnswerLength)
+{
+    unsigned long realsize;
+    int cmdlen;
+
+    SendComPort(IspEnvironment, Command);
+    ReceiveComPort(IspEnvironment, AnswerBuffer, AnswerLength - 1, &realsize, 2, 5000);
+    cmdlen = strlen(Command);
+    return (strncmp(AnswerBuffer, Command, cmdlen) == 0
+        && strcmp(AnswerBuffer + cmdlen, "0\r\n") == 0);
+}
+
+
+
+/***************************** NxpOutputErrorMessage ***********************/
+/**  Given an error number find and print the appropriate error message.
+\param [in] ErrorNumber The number of the error.
+*/
+#if defined COMPILE_FOR_LPC21
+
+#define NxpOutputErrorMessage(in)        // Cleanly remove this feature from the embedded version !!
+
+#else
+
+static void NxpOutputErrorMessage(unsigned char ErrorNumber)
+{
+    switch (ErrorNumber)
+    {
+    case   0:
+        DebugPrintf(1, "CMD_SUCCESS\n");
+        break;
+
+    case   1:
+        DebugPrintf(1, "INVALID_COMMAND\n");
+        break;
+
+    case   2:
+        DebugPrintf(1, "SRC_ADDR_ERROR: Source address is not on word boundary.\n");
+        break;
+    case   3:
+        DebugPrintf(1, "DST_ADDR_ERROR: Destination address is not on a correct boundary.\n");
+        break;
+
+    case   4:
+        DebugPrintf(1, "SRC_ADDR_NOT_MAPPED: Source address is not mapped in the memory map.\n"
+                       "                     Count value is taken into consideration where applicable.\n");
+        break;
+
+    case   5:
+        DebugPrintf(1, "DST_ADDR_NOT_MAPPED: Destination address is not mapped in the memory map.\n"
+                       "                     Count value is taken into consideration where applicable.\n");
+        break;
+
+    case   6:
+        DebugPrintf(1, "COUNT_ERROR: Byte count is not multiple of 4 or is not a permitted value.\n");
+        break;
+
+    case   7:
+        DebugPrintf(1, "INVALID_SECTOR: Sector number is invalid or end sector number is\n"
+                       "                greater than start sector number.\n");
+        break;
+
+    case   8:
+        DebugPrintf(1, "SECTOR_NOT_BLANK\n");
+        break;
+
+    case   9:
+        DebugPrintf(1, "SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION:\n"
+                       "Command to prepare sector for write operation was not executed.\n");
+        break;
+
+    case  10:
+        DebugPrintf(1, "COMPARE_ERROR: Source and destination data not equal.\n");
+        break;
+
+    case  11:
+        DebugPrintf(1, "BUSY: Flash programming hardware interface is busy.\n");
+        break;
+
+    case  12:
+        DebugPrintf(1, "PARAM_ERROR: Insufficient number of parameters or invalid parameter.\n");
+        break;
+
+    case  13:
+        DebugPrintf(1, "ADDR_ERROR: Address is not on word boundary.\n");
+        break;
+
+    case  14:
+        DebugPrintf(1, "ADDR_NOT_MAPPED: Address is not mapped in the memory map.\n"
+                       "                 Count value is taken in to consideration where applicable.\n");
+        break;
+
+    case  15:
+        DebugPrintf(1, "CMD_LOCKED\n");
+        break;
+
+    case  16:
+        DebugPrintf(1, "INVALID_CODE: Unlock code is invalid.\n");
+        break;
+
+    case  17:
+        DebugPrintf(1, "INVALID_BAUD_RATE: Invalid baud rate setting.\n");
+        break;
+
+    case  18:
+        DebugPrintf(1, "INVALID_STOP_BIT: Invalid stop bit setting.\n");
+        break;
+
+    case  19:
+        DebugPrintf( 1, "CODE READ PROTECTION ENABLED\n");
+        break;
+
+    case 255:
+        break;
+
+    default:
+        DebugPrintf(1, "unknown error %u\n", ErrorNumber);
+        break;
+    }
+
+    //DebugPrintf(1, "error (%u), see  NxpOutputErrorMessage() in lpc21isp.c for help \n\r", ErrorNumber);
+}
+#endif // !defined COMPILE_FOR_LPC21
+
+/***************************** GetAndReportErrorNumber ***************************/
+/**  Find error number in string.  This will normally be the string
+returned from the microcontroller.
+\param [in] Answer the buffer to search for the error number.
+\return the error number found, if no linefeed found before the end of the
+string an error value of 255 is returned. If a non-numeric value is found
+then it is printed to stdout and an error value of 255 is returned.
+*/
+static unsigned char GetAndReportErrorNumber(const char *Answer)
+{
+    unsigned char Result = 0xFF;                            // Error !!!
+    unsigned int i = 0;
+
+    while (1)
+    {
+        if (Answer[i] == 0x00)
+        {
+            break;
+        }
+
+        if (Answer[i] == 0x0a)
+        {
+            i++;
+
+            if (Answer[i] < '0' || Answer[i] > '9')
+            {
+                DebugPrintf(1, "ErrorString: %s", &Answer[i]);
+                break;
+            }
+
+            Result = (unsigned char) (atoi(&Answer[i]));
+            break;
+        }
+
+        i++;
+    }
+
+    NxpOutputErrorMessage(Result);
+
+    return Result;
+}
+
+
+int NxpDownload(ISP_ENVIRONMENT *IspEnvironment)
+{
+    unsigned long realsize;
+    char Answer[128];
+    char ExpectedAnswer[128];
+    char temp[128];
+    /*const*/ char *strippedAnswer, *endPtr;
+    int  strippedsize;
+    int nQuestionMarks;
+    int found;
+    unsigned long Sector;
+    unsigned long SectorLength;
+    unsigned long SectorStart, SectorOffset, SectorChunk;
+    char tmpString[128];
+    char uuencode_table[64];
+    int Line;
+    unsigned long tmpStringPos;
+    unsigned long BlockOffset;
+    unsigned long Block;
+    unsigned long Pos;
+    unsigned long CopyLength;
+    int c,k=0,i;
+    unsigned long ivt_CRC;          // CRC over interrupt vector table
+    unsigned long block_CRC;
+    time_t tStartUpload=0, tDoneUpload=0;
+    char tmp_string[64];
+    char * cmdstr;
+
+#if !defined COMPILE_FOR_LPC21
+
+#if defined __BORLANDC__
+#define local_static static
+#else
+#define local_static
+#endif
+
+//    char * cmdstr;
+    int repeat = 0;
+    // Puffer for data to resend after "RESEND\r\n" Target responce
+    local_static char sendbuf0[128];
+    local_static char sendbuf1[128];
+    local_static char sendbuf2[128];
+    local_static char sendbuf3[128];
+    local_static char sendbuf4[128];
+    local_static char sendbuf5[128];
+    local_static char sendbuf6[128];
+    local_static char sendbuf7[128];
+    local_static char sendbuf8[128];
+    local_static char sendbuf9[128];
+    local_static char sendbuf10[128];
+    local_static char sendbuf11[128];
+    local_static char sendbuf12[128];
+    local_static char sendbuf13[128];
+    local_static char sendbuf14[128];
+    local_static char sendbuf15[128];
+    local_static char sendbuf16[128];
+    local_static char sendbuf17[128];
+    local_static char sendbuf18[128];
+    local_static char sendbuf19[128];
+
+    char * sendbuf[20] = {    sendbuf0,  sendbuf1,  sendbuf2,  sendbuf3,  sendbuf4,
+                              sendbuf5,  sendbuf6,  sendbuf7,  sendbuf8,  sendbuf9,
+                              sendbuf10, sendbuf11, sendbuf12, sendbuf13, sendbuf14,
+                              sendbuf15, sendbuf16, sendbuf17, sendbuf18, sendbuf19};
+#endif
+
+    DebugPrintf(2, "Synchronizing (ESC to abort)");
+
+    PrepareKeyboardTtySettings();
+
+#if defined INTEGRATED_IN_WIN_APP
+    if (IspEnvironment->NoSync)
+    {
+        found = 1;
+    }
+    else
+#endif
+    {
+        for (nQuestionMarks = found = 0; !found && nQuestionMarks < IspEnvironment->nQuestionMarks; nQuestionMarks++)
+        {
+#if defined INTEGRATED_IN_WIN_APP
+            // allow calling application to abort when syncing takes too long
+
+            if (!AppSyncing(nQuestionMarks))
+            {
+                return (USER_ABORT_SYNC);
+            }
+#else
+#ifndef Exclude_kbhit
+            if (kbhit())
+            {
+                if (getch() == 0x1b)
+                {
+                    ResetKeyboardTtySettings();
+                    DebugPrintf(2, "\nUser aborted during synchronisation\n");
+                    return (USER_ABORT_SYNC);
+                }
+            }
+#endif
+#endif
+
+            DebugPrintf(2, ".");
+            SendComPort(IspEnvironment, "?");
+
+            memset(Answer,0,sizeof(Answer));
+            ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,100);
+
+            strippedAnswer = Answer;
+            strippedsize = realsize;
+            while ((strippedsize > 0) && ((*strippedAnswer == '?') || (*strippedAnswer == 0)))
+            {
+                strippedAnswer++;
+                strippedsize--;
+            }
+
+            sprintf(tmp_string, "StrippedAnswer(Length=%d): '", strippedsize);
+            DumpString(3, strippedAnswer, strippedsize, tmp_string);
+
+            tStartUpload = time(NULL);
+
+            if (strcmp(strippedAnswer, "Synchronized\r\n") == 0)
+            {
+                found = 1;
+            }
+#if !defined COMPILE_FOR_LPC21
+            else
+            {
+                ResetTarget(IspEnvironment, PROGRAM_MODE);
+            }
+#endif
+        }
+    }
+
+    ResetKeyboardTtySettings();
+
+    if (!found)
+    {
+        DebugPrintf(1, " no answer on '?'\n");
+        return (NO_ANSWER_QM);
+    }
+
+#if defined INTEGRATED_IN_WIN_APP
+    AppSyncing(-1);                         // flag syncing done
+#endif
+
+    DebugPrintf(2, " OK\n");
+
+    SendComPort(IspEnvironment, "Synchronized\n");
+
+    ReceiveComPort(IspEnvironment, Answer, sizeof(Answer) - 1, &realsize, 2, 1000);
+
+    if ((strcmp(Answer, "Synchronized\r\nOK\r\n") != 0) && (strcmp(Answer, "Synchronized\rOK\r\n") != 0) &&
+        (strcmp(Answer, "Synchronized\nOK\r\n") != 0))
+    {
+        DebugPrintf(1, "No answer on 'Synchronized'\n");
+        return (NO_ANSWER_SYNC);
+    }
+
+    DebugPrintf(3, "Synchronized 1\n");
+
+    DebugPrintf(3, "Setting oscillator\n");
+
+    sprintf(temp, "%s\n", IspEnvironment->StringOscillator);
+
+    SendComPort(IspEnvironment, temp);
+
+    ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2, 1000);
+
+    sprintf(temp, "%s\nOK\r\n", IspEnvironment->StringOscillator);
+
+    if (strcmp(Answer, temp) != 0)
+    {
+        DebugPrintf(1, "No answer on Oscillator-Command\n");
+        return (NO_ANSWER_OSC);
+    }
+
+    DebugPrintf(3, "Unlock\n");
+
+    cmdstr = "U 23130\n";
+
+    if (!SendAndVerify(IspEnvironment, cmdstr, Answer, sizeof Answer))
+    {
+        DebugPrintf(1, "Unlock-Command:\n");
+        return (UNLOCK_ERROR + GetAndReportErrorNumber(Answer));
+    }
+
+    DebugPrintf(2, "Read bootcode version: ");
+
+    cmdstr = "K\n";
+
+    SendComPort(IspEnvironment, cmdstr);
+
+    ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 4,5000);
+
+    if (strncmp(Answer, cmdstr, strlen(cmdstr)) != 0)
+    {
+        DebugPrintf(1, "no answer on Read Boot Code Version\n");
+        return (NO_ANSWER_RBV);
+    }
+
+    if (strncmp(Answer + strlen(cmdstr), "0\r\n", 3) == 0)
+    {
+        strippedAnswer = Answer + strlen(cmdstr) + 3;
+        /*
+        int maj, min, build;
+        if (sscanf(strippedAnswer, "%d %d %d", &build, &min, &maj) == 2) {
+        maj = min;
+        min = build;
+        build = 0;
+        } // if
+        DebugPrintf(2, "%d.%d.%d\n", maj, min, build);
+        */
+        DebugPrintf(2, strippedAnswer);
+    }
+    else
+    {
+        DebugPrintf(2, "unknown\n");
+    }
+
+    DebugPrintf(2, "Read part ID: ");
+
+    cmdstr = "J\n";
+
+    SendComPort(IspEnvironment, cmdstr);
+
+    ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 3,5000);
+
+    if (strncmp(Answer, cmdstr, strlen(cmdstr)) != 0)
+    {
+        DebugPrintf(1, "no answer on Read Part Id\n");
+        return (NO_ANSWER_RPID);
+    }
+
+    strippedAnswer = (strncmp(Answer, "J\n0\r\n", 5) == 0) ? Answer + 5 : Answer;
+
+    Pos = strtoul(strippedAnswer, &endPtr, 10);
+    *endPtr = '\0'; /* delete \r\n */
+    for (i = sizeof LPCtypes / sizeof LPCtypes[0] - 1; i > 0 && LPCtypes[i].id != Pos; i--)
+        /* nothing */;
+        IspEnvironment->DetectedDevice = i;
+    if (IspEnvironment->DetectedDevice == 0) {
+        DebugPrintf(2, "unknown");
+    }
+    else {
+        DebugPrintf(2, "LPC%s, %d kiB ROM / %d kiB SRAM",
+            LPCtypes[IspEnvironment->DetectedDevice].Product,
+            LPCtypes[IspEnvironment->DetectedDevice].FlashSize,
+            LPCtypes[IspEnvironment->DetectedDevice].RAMSize);
+    }
+    DebugPrintf(2, " (0x%X)\n", Pos);//strippedAnswer);
+
+    if (!IspEnvironment->DetectOnly)
+    {
+        // Build up uuencode table
+        uuencode_table[0] = 0x60;           // 0x20 is translated to 0x60 !
+
+        for (i = 1; i < 64; i++)
+        {
+            uuencode_table[i] = (char)(0x20 + i);
+        }
+
+        if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC2XXX)
+        {
+            // Patch 0x14, otherwise it is not running and jumps to boot mode
+
+            ivt_CRC = 0;
+
+            // Clear the vector at 0x14 so it doesn't affect the checksum:
+            for (i = 0; i < 4; i++)
+            {
+                IspEnvironment->BinaryContent[i + 0x14] = 0;
+            }
+
+            // Calculate a native checksum of the little endian vector table:
+            for (i = 0; i < (4 * 8);) {
+                ivt_CRC += IspEnvironment->BinaryContent[i++];
+                ivt_CRC += IspEnvironment->BinaryContent[i++] << 8;
+                ivt_CRC += IspEnvironment->BinaryContent[i++] << 16;
+                ivt_CRC += IspEnvironment->BinaryContent[i++] << 24;
+            }
+
+            /* Negate the result and place in the vector at 0x14 as little endian
+            * again. The resulting vector table should checksum to 0. */
+            ivt_CRC = (unsigned long) (0 - ivt_CRC);
+            for (i = 0; i < 4; i++)
+            {
+                IspEnvironment->BinaryContent[i + 0x14] = (unsigned char)(ivt_CRC >> (8 * i));
+            }
+
+            DebugPrintf(3, "Position 0x14 patched: ivt_CRC = 0x%08lX\n", ivt_CRC);
+        }
+        else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC17XX ||
+                LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC13XX ||
+                LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC11XX)
+        {
+            // Patch 0x1C, otherwise it is not running and jumps to boot mode
+
+            ivt_CRC = 0;
+
+            // Clear the vector at 0x1C so it doesn't affect the checksum:
+            for (i = 0; i < 4; i++)
+            {
+                IspEnvironment->BinaryContent[i + 0x1C] = 0;
+            }
+
+            // Calculate a native checksum of the little endian vector table:
+            for (i = 0; i < (4 * 8);) {
+                ivt_CRC += IspEnvironment->BinaryContent[i++];
+                ivt_CRC += IspEnvironment->BinaryContent[i++] << 8;
+                ivt_CRC += IspEnvironment->BinaryContent[i++] << 16;
+                ivt_CRC += IspEnvironment->BinaryContent[i++] << 24;
+            }
+
+            /* Negate the result and place in the vector at 0x1C as little endian
+            * again. The resulting vector table should checksum to 0. */
+            ivt_CRC = (unsigned long) (0 - ivt_CRC);
+            for (i = 0; i < 4; i++)
+            {
+                IspEnvironment->BinaryContent[i + 0x1C] = (unsigned char)(ivt_CRC >> (8 * i));
+            }
+
+            DebugPrintf(3, "Position 0x1C patched: ivt_CRC = 0x%08lX\n", ivt_CRC);
+        }
+        else
+        {
+          DebugPrintf(1, "Internal error: wrong chip variant %d (detected device %d)\n", LPCtypes[IspEnvironment->DetectedDevice].ChipVariant, IspEnvironment->DetectedDevice);
+          exit(1);
+        }
+    }
+
+#if 0
+    DebugPrintf(2, "Read Unique ID:\n");
+
+    cmdstr = "N\n";
+
+    SendComPort(IspEnvironment, cmdstr);
+
+    ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 5,5000);
+
+    if (strncmp(Answer, cmdstr, strlen(cmdstr)) != 0)
+    {
+        DebugPrintf(1, "no answer on Read Unique ID\n");
+        return (NO_ANSWER_RBV);
+    }
+
+    if (strncmp(Answer + strlen(cmdstr), "0\r\n", 3) == 0)
+    {
+        strippedAnswer = Answer + strlen(cmdstr) + 3;
+        DebugPrintf(2, strippedAnswer);
+    }
+    else
+    {
+        DebugPrintf(2, "unknown\n");
+    }
+#endif // 0
+
+    /* In case of a download to RAM, use full RAM for downloading
+    * set the flash parameters to full RAM also.
+    * This makes sure that all code is downloaded as one big sector
+    */
+
+    if (IspEnvironment->BinaryOffset >= ReturnValueLpcRamStart(IspEnvironment))
+    {
+        LPCtypes[IspEnvironment->DetectedDevice].FlashSectors = 1;
+        LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize  = LPCtypes[IspEnvironment->DetectedDevice].RAMSize*1024 - (ReturnValueLpcRamBase(IspEnvironment) - ReturnValueLpcRamStart(IspEnvironment));
+        LPCtypes[IspEnvironment->DetectedDevice].SectorTable  = SectorTable_RAM;
+        SectorTable_RAM[0] = LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize;
+    }
+    if (IspEnvironment->DetectOnly)
+        return (0);
+
+
+    // Start with sector 1 and go upward... Sector 0 containing the interrupt vectors
+    // will be loaded last, since it contains a checksum and device will re-enter
+    // bootloader mode as long as this checksum is invalid.
+    DebugPrintf(2, "Will start programming at Sector 1 if possible, and conclude with Sector 0 to ensure that checksum is written last.\n");
+    if (LPCtypes[IspEnvironment->DetectedDevice].SectorTable[0] >= IspEnvironment->BinaryLength)
+    {
+        Sector = 0;
+        SectorStart = 0;
+    }
+    else
+    {
+        SectorStart = LPCtypes[IspEnvironment->DetectedDevice].SectorTable[0];
+        Sector = 1;
+    }
+
+    if (IspEnvironment->WipeDevice == 1)
+    {
+        DebugPrintf(2, "Wiping Device. ");
+
+        sprintf(tmpString, "P %d %d\n", 0, LPCtypes[IspEnvironment->DetectedDevice].FlashSectors-1);
+
+        if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+        {
+            DebugPrintf(1, "Wrong answer on Prepare-Command\n");
+            return (WRONG_ANSWER_PREP + GetAndReportErrorNumber(Answer));
+        }
+
+        sprintf(tmpString, "E %d %d\n", 0, LPCtypes[IspEnvironment->DetectedDevice].FlashSectors-1);
+
+        if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+        {
+            DebugPrintf(1, "Wrong answer on Erase-Command\n");
+            return (WRONG_ANSWER_ERAS + GetAndReportErrorNumber(Answer));
+        }
+        DebugPrintf(2, "OK \n");
+    }
+    else{
+        //no wiping requested: erasing sector 0 first
+        DebugPrintf(2, "Erasing sector 0 first, to invalidate checksum. ");
+
+        sprintf(tmpString, "P %d %d\n", 0, 0);
+
+        if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+        {
+            DebugPrintf(1, "Wrong answer on Prepare-Command\n");
+            return (WRONG_ANSWER_PREP + GetAndReportErrorNumber(Answer));
+        }
+
+        sprintf(tmpString, "E %d %d\n", 0, 0);
+
+        if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+        {
+            DebugPrintf(1, "Wrong answer on Erase-Command\n");
+            return (WRONG_ANSWER_ERAS + GetAndReportErrorNumber(Answer));
+        }
+        DebugPrintf(2, "OK \n");
+    }
+    while (1)
+    {
+        if (Sector >= LPCtypes[IspEnvironment->DetectedDevice].FlashSectors)
+        {
+            DebugPrintf(1, "Program too large; running out of Flash sectors.\n");
+            return (PROGRAM_TOO_LARGE);
+        }
+
+        DebugPrintf(2, "Sector %ld: ", Sector);
+        fflush(stdout);
+
+        if (IspEnvironment->BinaryOffset < ReturnValueLpcRamStart(IspEnvironment)) // Skip Erase when running from RAM
+        {
+            sprintf(tmpString, "P %ld %ld\n", Sector, Sector);
+
+            if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+            {
+                DebugPrintf(1, "Wrong answer on Prepare-Command (1) (Sector %ld)\n", Sector);
+                return (WRONG_ANSWER_PREP + GetAndReportErrorNumber(Answer));
+            }
+
+            DebugPrintf(2, ".");
+            fflush(stdout);
+            if (IspEnvironment->WipeDevice == 0 && (Sector!=0)) //Sector 0 already erased
+            {
+                sprintf(tmpString, "E %ld %ld\n", Sector, Sector);
+
+                if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+                {
+                    DebugPrintf(1, "Wrong answer on Erase-Command (Sector %ld)\n", Sector);
+                    return (WRONG_ANSWER_ERAS + GetAndReportErrorNumber(Answer));
+                }
+
+                DebugPrintf(2, ".");
+                fflush(stdout);
+            }
+        }
+
+        SectorLength = LPCtypes[IspEnvironment->DetectedDevice].SectorTable[Sector];
+        if (SectorLength > IspEnvironment->BinaryLength - SectorStart)
+        {
+            SectorLength = IspEnvironment->BinaryLength - SectorStart;
+        }
+
+        for (SectorOffset = 0; SectorOffset < SectorLength; SectorOffset += SectorChunk)
+        {
+            if (SectorOffset > 0)
+            {
+                // Add a visible marker between segments in a sector
+                DebugPrintf(2, "|");  /* means: partial segment copied */
+                fflush(stdout);
+            }
+
+            // If the Flash ROM sector size is bigger than the number of bytes
+            // we can copy from RAM to Flash, we must "chop up" the sector and
+            // copy these individually.
+            // This is especially needed in the case where a Flash sector is
+            // bigger than the amount of SRAM.
+            SectorChunk = SectorLength - SectorOffset;
+            if (SectorChunk > (unsigned)LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize)
+            {
+                SectorChunk = LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize;
+            }
+
+            // Write multiple of 45 * 4 Byte blocks to RAM, but copy maximum of on sector to Flash
+            // In worst case we transfer up to 180 byte to much to RAM
+            // but then we can always use full 45 byte blocks and length is multiple of 4
+            CopyLength = SectorChunk;
+            if ((CopyLength % (45 * 4)) != 0)
+            {
+                CopyLength += ((45 * 4) - (CopyLength % (45 * 4)));
+            }
+
+            sprintf(tmpString, "W %ld %ld\n", ReturnValueLpcRamBase(IspEnvironment), CopyLength);
+
+            if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+            {
+                DebugPrintf(1, "Wrong answer on Write-Command\n");
+                return (WRONG_ANSWER_WRIT + GetAndReportErrorNumber(Answer));
+            }
+
+            DebugPrintf(2, ".");
+            fflush(stdout);
+
+            block_CRC = 0;
+            Line = 0;
+
+            // Transfer blocks of 45 * 4 bytes to RAM
+            for (Pos = SectorStart + SectorOffset; (Pos < SectorStart + SectorOffset + CopyLength) && (Pos < IspEnvironment->BinaryLength); Pos += (45 * 4))
+            {
+                for (Block = 0; Block < 4; Block++)  // Each block 45 bytes
+                {
+                    DebugPrintf(2, ".");
+                    fflush(stdout);
+
+#if defined INTEGRATED_IN_WIN_APP
+                    // inform the calling application about having written another chuck of data
+                    AppWritten(45);
+#endif
+
+                    // Uuencode one 45 byte block
+                    tmpStringPos = 0;
+
+#if !defined COMPILE_FOR_LPC21
+                    sendbuf[Line][tmpStringPos++] = (char)(' ' + 45);    // Encode Length of block
+#else
+                    tmpString[tmpStringPos++] = (char)(' ' + 45);        // Encode Length of block
+#endif
+
+                    for (BlockOffset = 0; BlockOffset < 45; BlockOffset++)
+                    {
+                        if (IspEnvironment->BinaryOffset < ReturnValueLpcRamStart(IspEnvironment))
+                        { // Flash: use full memory
+                            c = IspEnvironment->BinaryContent[Pos + Block * 45 + BlockOffset];
+                        }
+                        else
+                        { // RAM: Skip first 0x200 bytes, these are used by the download program in LPC21xx
+                            c = IspEnvironment->BinaryContent[Pos + Block * 45 + BlockOffset + 0x200];
+                        }
+
+                        block_CRC += c;
+
+                        k = (k << 8) + (c & 255);
+
+                        if ((BlockOffset % 3) == 2)   // Collecting always 3 Bytes, then do processing in 4 Bytes
+                        {
+#if !defined COMPILE_FOR_LPC21
+                            sendbuf[Line][tmpStringPos++] = uuencode_table[(k >> 18) & 63];
+                            sendbuf[Line][tmpStringPos++] = uuencode_table[(k >> 12) & 63];
+                            sendbuf[Line][tmpStringPos++] = uuencode_table[(k >>  6) & 63];
+                            sendbuf[Line][tmpStringPos++] = uuencode_table[ k        & 63];
+#else
+                            tmpString[tmpStringPos++] = uuencode_table[(k >> 18) & 63];
+                            tmpString[tmpStringPos++] = uuencode_table[(k >> 12) & 63];
+                            tmpString[tmpStringPos++] = uuencode_table[(k >>  6) & 63];
+                            tmpString[tmpStringPos++] = uuencode_table[ k        & 63];
+#endif
+                        }
+                    }
+
+
+#if !defined COMPILE_FOR_LPC21
+                    sendbuf[Line][tmpStringPos++] = '\n';
+                    sendbuf[Line][tmpStringPos++] = 0;
+
+                    SendComPort(IspEnvironment, sendbuf[Line]);
+                    // receive only for debug proposes
+                    ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,5000);
+#else
+                    tmpString[tmpStringPos++] = '\n';
+                    tmpString[tmpStringPos++] = 0;
+
+                    SendComPort(IspEnvironment, tmpString);
+                    ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,5000);
+                    if (strncmp(Answer, tmpString, tmpStringPos) != 0)
+                    {
+                        DebugPrintf(1, "Error on writing data (1)\n");
+                        return (ERROR_WRITE_DATA);
+                    }
+#endif
+
+                    Line++;
+
+                    DebugPrintf(3, "Line = %d\n", Line);
+
+                    if (Line == 20)
+                    {
+#if !defined COMPILE_FOR_LPC21
+                        for (repeat = 0; repeat < 3; repeat++)
+                        {
+
+                            // printf("block_CRC = %ld\n", block_CRC);
+
+                            sprintf(tmpString, "%ld\n", block_CRC);
+
+                            SendComPort(IspEnvironment, tmpString);
+
+                            ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,5000);
+
+                            sprintf(tmpString, "%ld\nOK\r\n", block_CRC);
+
+                            if (strcmp(Answer, tmpString) != 0)
+                            {
+                                for (i = 0; i < Line; i++)
+                                {
+                                    SendComPort(IspEnvironment, sendbuf[i]);
+                                    ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,5000);
+                                }
+                            }
+                            else
+                                break;
+                        }
+
+                        if (repeat >= 3)
+                        {
+                            DebugPrintf(1, "Error on writing block_CRC (1)\n");
+                            return (ERROR_WRITE_CRC);
+                        }
+#else
+                        // printf("block_CRC = %ld\n", block_CRC);
+                        sprintf(tmpString, "%ld\r\n", block_CRC);
+                        SendComPort(IspEnvironment, tmpString);
+
+                        ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,5000);
+
+                        sprintf(tmpString, "%ld\r\nOK\r\n", block_CRC);
+                        if (strcmp(Answer, tmpString) != 0)
+                        {
+                            DebugPrintf(1, "Error on writing block_CRC (2)\n");
+                            return (ERROR_WRITE_CRC);
+                        }
+#endif
+                        Line = 0;
+                        block_CRC = 0;
+                    }
+                }
+            }
+
+            if (Line != 0)
+            {
+#if !defined COMPILE_FOR_LPC21
+                for (repeat = 0; repeat < 3; repeat++)
+                {
+                    sprintf(tmpString, "%ld\n", block_CRC);
+
+                    SendComPort(IspEnvironment, tmpString);
+
+                    ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,5000);
+
+                    sprintf(tmpString, "%ld\nOK\r\n", block_CRC);
+
+                    if (strcmp(Answer, tmpString) != 0)
+                    {
+                        for (i = 0; i < Line; i++)
+                        {
+                            SendComPort(IspEnvironment, sendbuf[i]);
+                            ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,5000);
+                        }
+                    }
+                    else
+                        break;
+                }
+
+                if (repeat >= 3)
+                {
+                    DebugPrintf(1, "Error on writing block_CRC (3)\n");
+                    return (ERROR_WRITE_CRC2);
+                }
+#else
+                sprintf(tmpString, "%ld\r\n", block_CRC);
+                SendComPort(IspEnvironment, tmpString);
+
+                ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,5000);
+
+                sprintf(tmpString, "%ld\r\nOK\r\n", block_CRC);
+                if (strcmp(Answer, tmpString) != 0)
+                {
+                    DebugPrintf(1, "Error on writing block_CRC (4)\n");
+                    return (ERROR_WRITE_CRC2);
+                }
+#endif
+            }
+
+            if (IspEnvironment->BinaryOffset < ReturnValueLpcRamStart(IspEnvironment))
+            {
+                // Prepare command must be repeated before every write
+                sprintf(tmpString, "P %ld %ld\n", Sector, Sector);
+
+                if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+                {
+                    DebugPrintf(1, "Wrong answer on Prepare-Command (2) (Sector %ld)\n", Sector);
+                    return (WRONG_ANSWER_PREP2 + GetAndReportErrorNumber(Answer));
+                }
+
+                // Round CopyLength up to one of the following values: 512, 1024,
+                // 4096, 8192; but do not exceed the maximum copy size (usually
+                // 8192, but chip-dependent)
+                if (CopyLength < 512)
+                {
+                    CopyLength = 512;
+                }
+                else if (SectorLength < 1024)
+                {
+                    CopyLength = 1024;
+                }
+                else if (SectorLength < 4096)
+                {
+                    CopyLength = 4096;
+                }
+                else
+                {
+                    CopyLength = 8192;
+                }
+                if (CopyLength > (unsigned)LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize)
+                {
+                    CopyLength = LPCtypes[IspEnvironment->DetectedDevice].MaxCopySize;
+                }
+
+                sprintf(tmpString, "C %ld %ld %ld\n", SectorStart + SectorOffset, ReturnValueLpcRamBase(IspEnvironment), CopyLength);
+
+                if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+                {
+                    DebugPrintf(1, "Wrong answer on Copy-Command\n");
+                    return (WRONG_ANSWER_COPY + GetAndReportErrorNumber(Answer));
+                }
+
+                if (IspEnvironment->Verify)
+                {
+
+                    //Avoid compare first 64 bytes.
+                    //Because first 64 bytes are re-mapped to flash boot sector,
+                    //and the compare result may not be correct.
+                    if (SectorStart + SectorOffset<64)
+                    {
+                        sprintf(tmpString, "M %d %ld %ld\n", 64, ReturnValueLpcRamBase(IspEnvironment) + (64 - SectorStart - SectorOffset), CopyLength-(64 - SectorStart - SectorOffset));
+                    }
+                    else
+                    {
+                        sprintf(tmpString, "M %ld %ld %ld\n", SectorStart + SectorOffset, ReturnValueLpcRamBase(IspEnvironment), CopyLength);
+                    }
+
+                    if (!SendAndVerify(IspEnvironment, tmpString, Answer, sizeof Answer))
+                    {
+                        DebugPrintf(1, "Wrong answer on Compare-Command\n");
+                        return (WRONG_ANSWER_COPY + GetAndReportErrorNumber(Answer));
+                    }
+                }
+            }
+        }
+
+        DebugPrintf(2, "\n");
+        fflush(stdout);
+
+        if ((SectorStart + SectorLength) >= IspEnvironment->BinaryLength && Sector!=0)
+        {
+            Sector = 0;
+            SectorStart = 0;
+        }
+        else if (Sector == 0) {
+            break;
+        }
+        else {
+            SectorStart += LPCtypes[IspEnvironment->DetectedDevice].SectorTable[Sector];
+            Sector++;
+        }
+    }
+
+    tDoneUpload = time(NULL);
+    if (IspEnvironment->Verify)
+        DebugPrintf(2, "Download Finished and Verified correct... taking %d seconds\n", tDoneUpload - tStartUpload);
+    else
+        DebugPrintf(2, "Download Finished... taking %d seconds\n", tDoneUpload - tStartUpload);
+
+    if(IspEnvironment->DoNotStart == 0)
+    {
+        DebugPrintf(2, "Now launching the brand new code\n");
+        fflush(stdout);
+
+        if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC2XXX)
+        {
+            sprintf(tmpString, "G %ld A\n", IspEnvironment->StartAddress);
+        }
+        else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC17XX ||
+                LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC13XX ||
+                LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC11XX)
+        {
+            sprintf(tmpString, "G %ld T\n", IspEnvironment->StartAddress & ~1);
+        }
+        else
+        {
+            printf("Internal Error %s %d\n", __FILE__, __LINE__);
+            exit(1);
+        }
+
+        SendComPort(IspEnvironment, tmpString); //goto 0 : run this fresh new downloaded code code
+        if (IspEnvironment->BinaryOffset < ReturnValueLpcRamStart(IspEnvironment))
+        { // Skip response on G command - show response on Terminal instead
+            ReceiveComPort(IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2, 5000);
+            /* the reply string is frequently terminated with a -1 (EOF) because the
+            * connection gets broken; zero-terminate the string ourselves
+            */
+            while (realsize > 0 && ((signed char) Answer[(int)realsize - 1]) < 0)
+                realsize--;
+            Answer[(int)realsize] = '\0';
+            /* Better to check only the first 9 chars instead of complete receive buffer,
+            * because the answer can contain the output by the started programm
+            */
+            if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC2XXX)
+            {
+                sprintf(ExpectedAnswer, "G %ld A\n0", IspEnvironment->StartAddress);
+            }
+            else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC17XX ||
+                    LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC13XX ||
+                    LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC11XX)
+            {
+                sprintf(ExpectedAnswer, "G %ld T\n0", IspEnvironment->StartAddress & ~1);
+            }
+            else
+            {
+                printf("Internal Error %s %d\n", __FILE__, __LINE__);
+                exit(1);
+            }
+
+            if (realsize == 0 || strncmp((const char *)Answer, /*cmdstr*/ExpectedAnswer, strlen(/*cmdstr*/ExpectedAnswer)) != 0)
+            {
+                DebugPrintf(2, "Failed to run the new downloaded code: ");
+                return (FAILED_RUN + GetAndReportErrorNumber(Answer));
+            }
+        }
+
+        fflush(stdout);
+    }
+    return (0);
+}
+#endif // LPC_SUPPORT
+
+
+unsigned long ReturnValueLpcRamStart(ISP_ENVIRONMENT *IspEnvironment)
+{
+  if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC2XXX)
+  {
+    return LPC_RAMSTART_LPC2XXX;
+  }
+  else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC17XX)
+  {
+    return LPC_RAMSTART_LPC17XX;
+  }
+  else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC13XX)
+  {
+    return LPC_RAMSTART_LPC13XX;
+  }
+  else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC11XX)
+  {
+    return LPC_RAMSTART_LPC11XX;
+  }
+  printf("Error in ReturnValueLpcRamStart (%d)\n", LPCtypes[IspEnvironment->DetectedDevice].ChipVariant);
+  exit(1);
+}
+
+
+unsigned long ReturnValueLpcRamBase(ISP_ENVIRONMENT *IspEnvironment)
+{
+  if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC2XXX)
+  {
+    return LPC_RAMBASE_LPC2XXX;
+  }
+  else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC17XX)
+  {
+    return LPC_RAMBASE_LPC17XX;
+  }
+  else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC13XX)
+  {
+    return LPC_RAMBASE_LPC13XX;
+  }
+  else if(LPCtypes[IspEnvironment->DetectedDevice].ChipVariant == CHIP_VARIANT_LPC11XX)
+  {
+    return LPC_RAMBASE_LPC11XX;
+  }
+  printf("Error in ReturnValueLpcRamBase (%d)\n", LPCtypes[IspEnvironment->DetectedDevice].ChipVariant);
+  exit(1);
+}
diff --git a/reform2-lpc-fw/tools/lpc21isp/lpcprog.dsp b/reform2-lpc-fw/tools/lpc21isp/lpcprog.dsp
new file mode 100644
index 0000000000000000000000000000000000000000..935210c71045637ab5357d584c42d3c3f5f0c329
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/lpcprog.dsp
@@ -0,0 +1,100 @@
+# Microsoft Developer Studio Project File - Name="lpcprog" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=lpcprog - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "lpcprog.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "lpcprog.mak" CFG="lpcprog - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "lpcprog - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "lpcprog - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "lpcprog - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF  "$(CFG)" == "lpcprog - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "lpcprog - Win32 Release"
+# Name "lpcprog - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\adprog.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lpc21isp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lpcprog.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\lpcterm.c
+# End Source File
+# End Target
+# End Project
diff --git a/reform2-lpc-fw/tools/lpc21isp/lpcprog.dsw b/reform2-lpc-fw/tools/lpc21isp/lpcprog.dsw
new file mode 100644
index 0000000000000000000000000000000000000000..30bcfd42b514de5689bc58e6cf0d8b336b67a670
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/lpcprog.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "lpcprog"=.\lpcprog.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/reform2-lpc-fw/tools/lpc21isp/lpcprog.h b/reform2-lpc-fw/tools/lpc21isp/lpcprog.h
new file mode 100644
index 0000000000000000000000000000000000000000..0a7c7d6a422ad566ff390a1459497af2e00a81bc
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/lpcprog.h
@@ -0,0 +1,127 @@
+/******************************************************************************
+
+Project:           Portable command line ISP for NXP LPC1000 / LPC2000 family
+                   and Analog Devices ADUC70xx
+
+Filename:          lpcprog.h
+
+Compiler:          Microsoft VC 6/7, Microsoft VS2008, Microsoft VS2010,
+                   GCC Cygwin, GCC Linux, GCC ARM ELF
+
+Author:            Martin Maurer (Martin.Maurer@clibb.de)
+
+Copyright:         (c) Martin Maurer 2003-2011, All rights reserved
+Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com
+
+    This file is part of lpc21isp.
+
+    lpc21isp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    any later version.
+
+    lpc21isp is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    and GNU General Public License along with lpc21isp.
+    If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* LPC_RAMSTART, LPC_RAMBASE
+*
+* Used in NxpDownload() to decide whether to Flash code or just place in in RAM
+* (works for .hex files only)
+*
+* LPC_RAMSTART - the Physical start address of the SRAM
+* LPC_RAMBASE  - the base address where downloading starts.
+*                Note that any code in the .hex file that resides in 0x4000,0000 ~ 0x4000,0200
+*                will _not_ be written to the LPCs SRAM.
+*                This is due to the fact that 0x4000,0040 - 0x4000,0200 is used by the bootrom.
+*                Any interrupt vectors must be copied to 0x4000,0000 and remapped to 0x0000,0000
+*                by the startup code.
+*/
+#define LPC_RAMSTART_LPC2XXX    0x40000000L
+#define LPC_RAMBASE_LPC2XXX     0x40000200L
+
+#define LPC_RAMSTART_LPC17XX    0x10000000L
+#define LPC_RAMBASE_LPC17XX     0x10000200L
+
+#define LPC_RAMSTART_LPC13XX    0x10000000L
+#define LPC_RAMBASE_LPC13XX     0x10000300L
+
+#define LPC_RAMSTART_LPC11XX    0x10000000L
+#define LPC_RAMBASE_LPC11XX     0x10000300L
+
+/* Return values used by NxpDownload(): reserving all values from 0x1000 to 0x1FFF */
+
+#define NO_ANSWER_WDT       0x1000
+#define NO_ANSWER_QM        0x1001
+#define NO_ANSWER_SYNC      0x1002
+#define NO_ANSWER_OSC       0x1003
+#define NO_ANSWER_RBV       0x1004
+#define NO_ANSWER_RPID      0x1005
+#define ERROR_WRITE_DATA    0x1006
+#define ERROR_WRITE_CRC     0x1007
+#define ERROR_WRITE_CRC2    0x1008
+#define PROGRAM_TOO_LARGE   0x1009
+
+#define USER_ABORT_SYNC     0x100A   /* User aborted synchronisation process */
+
+#define UNLOCK_ERROR        0x1100   /* return value is 0x1100 + NXP ISP returned value (0 to 255) */
+#define WRONG_ANSWER_PREP   0x1200   /* return value is 0x1200 + NXP ISP returned value (0 to 255) */
+#define WRONG_ANSWER_ERAS   0x1300   /* return value is 0x1300 + NXP ISP returned value (0 to 255) */
+#define WRONG_ANSWER_WRIT   0x1400   /* return value is 0x1400 + NXP ISP returned value (0 to 255) */
+#define WRONG_ANSWER_PREP2  0x1500   /* return value is 0x1500 + NXP ISP returned value (0 to 255) */
+#define WRONG_ANSWER_COPY   0x1600   /* return value is 0x1600 + NXP ISP returned value (0 to 255) */
+#define FAILED_RUN          0x1700   /* return value is 0x1700 + NXP ISP returned value (0 to 255) */
+
+#if defined COMPILE_FOR_LPC21
+#ifndef WIN32
+#define LPC_BSL_PIN         13
+#define LPC_RESET_PIN       47
+#define LPC_RESET(in)       NAsetGPIOpin(LPC_RESET_PIN, (in))
+#define LPC_BSL(in)         NAsetGPIOpin(LPC_BSL_PIN,   (in))
+#endif // WIN32
+#endif // COMPILE_FOR_LPC21
+
+
+/* LPC_FLASHMASK
+*
+* LPC_FLASHMASK - bitmask to define the maximum size of the Filesize to download.
+*                 LoadFile() will check any new segment address record (03) or extended linear
+*                 address record (04) to see if the addressed 64 kByte data block still falls
+*                 in the max. flash size.
+*                 LoadFile() will not load any files that are larger than this size.
+*/
+#define LPC_FLASHMASK  0xFFC00000 /* 22 bits = 4 MB */
+
+typedef enum
+  {
+  CHIP_VARIANT_NONE,
+  CHIP_VARIANT_LPC2XXX,
+  CHIP_VARIANT_LPC17XX,
+  CHIP_VARIANT_LPC13XX,
+  CHIP_VARIANT_LPC11XX
+  } CHIP_VARIANT;
+
+typedef struct
+{
+    const unsigned long  id;
+    const char *Product;
+    const unsigned int   FlashSize;     /* in kiB, for informational purposes only */
+    const unsigned int   RAMSize;       /* in kiB, for informational purposes only */
+          unsigned int   FlashSectors;  /* total number of sectors */
+          unsigned int   MaxCopySize;   /* maximum size that can be copied to Flash in a single command */
+    const unsigned int  *SectorTable;   /* pointer to a sector table with constant the sector sizes */
+    const CHIP_VARIANT   ChipVariant;
+} LPC_DEVICE_TYPE;
+
+int NxpDownload(ISP_ENVIRONMENT *IspEnvironment);
+
+unsigned long ReturnValueLpcRamStart(ISP_ENVIRONMENT *IspEnvironment);
+
+unsigned long ReturnValueLpcRamBase(ISP_ENVIRONMENT *IspEnvironment);
+
diff --git a/reform2-lpc-fw/tools/lpc21isp/lpcterm.c b/reform2-lpc-fw/tools/lpc21isp/lpcterm.c
new file mode 100644
index 0000000000000000000000000000000000000000..2f26fc82a311e06e6678dd0091e599a9b653da8e
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/lpcterm.c
@@ -0,0 +1,138 @@
+/******************************************************************************
+
+Project:           Portable command line ISP for NXP LPC1000 / LPC2000 family
+                   and Analog Devices ADUC70xx
+
+Filename:          lpcterm.c
+
+Compiler:          Microsoft VC 6/7, Microsoft VS2008, Microsoft VS2010,
+                   GCC Cygwin, GCC Linux, GCC ARM ELF
+
+Author:            Martin Maurer (Martin.Maurer@clibb.de)
+
+Copyright:         (c) Martin Maurer 2003-2011, All rights reserved
+Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com
+
+    This file is part of lpc21isp.
+
+    lpc21isp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    any later version.
+
+    lpc21isp is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    and GNU General Public License along with lpc21isp.
+    If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#if defined(_WIN32)
+#if !defined __BORLANDC__
+#include "StdAfx.h"
+#endif
+#endif // defined(_WIN32)
+#include "lpc21isp.h"
+#include "lpcterm.h"
+
+#ifdef TERMINAL_SUPPORT
+/***************************** Terminal *********************************/
+/**  Acts as a simple dumb terminal. Press 'ESC' to exit.
+*/
+BOOL CheckTerminalParameters(ISP_ENVIRONMENT *IspEnvironment, char* pstr)
+{
+    if (stricmp(pstr, "-localecho") == 0)
+    {
+        IspEnvironment->LocalEcho = 1;
+        DebugPrintf(3, "Local echo in terminal mode.\n");
+        return TRUE;
+    }
+
+    if (stricmp(pstr, "-term") == 0)
+    {
+        IspEnvironment->TerminalAfterUpload = 1;
+        DebugPrintf(3, "Invoke terminal after upload.\n");
+        return TRUE;
+    }
+
+    if (stricmp(pstr, "-termonly") == 0)
+    {
+        IspEnvironment->TerminalOnly    = 1;
+        IspEnvironment->ProgramChip    = 0;
+        DebugPrintf(3, "Only provide terminal.\n");
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+void Terminal(ISP_ENVIRONMENT *IspEnvironment)
+{
+    if (IspEnvironment->TerminalAfterUpload || IspEnvironment->TerminalOnly)
+    {
+        int           ch = 0;
+        char buffer[128];
+        int           fdlogfile = -1;
+        unsigned long realsize;
+
+        // When logging is switched on, output terminal output to lpc21isp.log
+        if (IspEnvironment->LogFile)
+        {
+            fdlogfile = open("lpc21isp.log", O_RDWR | O_BINARY | O_CREAT | O_TRUNC, 0777);
+        }
+
+        PrepareKeyboardTtySettings();
+
+        DebugPrintf(1, "Terminal started (press Escape to abort)\n\n");
+        fflush(stdout);
+
+        do
+        {
+            ReceiveComPort(IspEnvironment, buffer, sizeof(buffer) - 1, &realsize, 0,200);          // Check for received characters
+
+            if (realsize)
+            {
+                write(1, buffer, realsize);
+                fflush(stdout);
+                if (IspEnvironment->LogFile)     // When logging is turned on, then copy output to logfile
+                {
+                    write(fdlogfile, buffer, realsize);
+                }
+            }
+
+            // check for keypress, and write any out the port.
+            if (kbhit())
+            {
+                ch = getch();
+                if (ch == 0x1b)
+                {
+                    break;
+                }
+                buffer[0] = (unsigned char)ch;
+                buffer[1] = 0;
+
+                if (IspEnvironment->LocalEcho)
+                {
+                    write(1, buffer, 1);
+                }
+
+                SendComPort(IspEnvironment, buffer);
+            }
+        }
+        while (ch != 0x1b);
+
+        DebugPrintf(1, "\n\nTerminal stopped\n\n");
+        fflush(stdout);
+
+        ResetKeyboardTtySettings();
+
+        if (IspEnvironment->LogFile)
+        {
+            close(fdlogfile);
+        }
+    }
+}
+#endif
diff --git a/reform2-lpc-fw/tools/lpc21isp/lpcterm.h b/reform2-lpc-fw/tools/lpc21isp/lpcterm.h
new file mode 100644
index 0000000000000000000000000000000000000000..fc53759287070fc6ab2bfc66ea56b6e8ca7697e7
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/lpcterm.h
@@ -0,0 +1,43 @@
+/******************************************************************************
+
+Project:           Portable command line ISP for NXP LPC1000 / LPC2000 family
+                   and Analog Devices ADUC70xx
+
+Filename:          lpcterm.h
+
+Compiler:          Microsoft VC 6/7, Microsoft VS2008, Microsoft VS2010,
+                   GCC Cygwin, GCC Linux, GCC ARM ELF
+
+Author:            Martin Maurer (Martin.Maurer@clibb.de)
+
+Copyright:         (c) Martin Maurer 2003-2011, All rights reserved
+Portions Copyright (c) by Aeolus Development 2004 http://www.aeolusdevelopment.com
+
+    This file is part of lpc21isp.
+
+    lpc21isp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    any later version.
+
+    lpc21isp is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    and GNU General Public License along with lpc21isp.
+    If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef TRUE
+#define TRUE (1)
+#endif
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+typedef int BOOL;
+
+void Terminal(ISP_ENVIRONMENT *IspEnvironment);
+BOOL CheckTerminalParameters(ISP_ENVIRONMENT *IspEnvironment, char* pstr);
diff --git a/reform2-lpc-fw/tools/lpc21isp/out.txt b/reform2-lpc-fw/tools/lpc21isp/out.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d4364a248b13c993410f9175c4a9a2227c7f5cab
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpc21isp/out.txt
@@ -0,0 +1,817 @@
+Turn on debug, level: 5.
+lpc21isp version 1.83
+Attempt to read File /home/brad/Dropbox/Dev/lpc1114_blink_led-1.2.1-120108/out/lpc1114_blink_led.hex
+File /home/brad/Dropbox/Dev/lpc1114_blink_led-1.2.1-120108/out/lpc1114_blink_led.hex:
+	loaded...
+Converting file /home/brad/Dropbox/Dev/lpc1114_blink_led-1.2.1-120108/out/lpc1114_blink_led.hex to binary format...
+RecordLength = 10
+RecordAddress = 0000
+RealAddress = 00000000
+RecordType = 00
+Image size now: 16
+RecordLength = 10
+RecordAddress = 0010
+RealAddress = 00000010
+RecordType = 00
+Image size now: 32
+RecordLength = 10
+RecordAddress = 0020
+RealAddress = 00000020
+RecordType = 00
+Image size now: 48
+RecordLength = 10
+RecordAddress = 0030
+RealAddress = 00000030
+RecordType = 00
+Image size now: 64
+RecordLength = 10
+RecordAddress = 0040
+RealAddress = 00000040
+RecordType = 00
+Image size now: 80
+RecordLength = 10
+RecordAddress = 0050
+RealAddress = 00000050
+RecordType = 00
+Image size now: 96
+RecordLength = 10
+RecordAddress = 0060
+RealAddress = 00000060
+RecordType = 00
+Image size now: 112
+RecordLength = 10
+RecordAddress = 0070
+RealAddress = 00000070
+RecordType = 00
+Image size now: 128
+RecordLength = 10
+RecordAddress = 0080
+RealAddress = 00000080
+RecordType = 00
+Image size now: 144
+RecordLength = 10
+RecordAddress = 0090
+RealAddress = 00000090
+RecordType = 00
+Image size now: 160
+RecordLength = 10
+RecordAddress = 00A0
+RealAddress = 000000A0
+RecordType = 00
+Image size now: 176
+RecordLength = 10
+RecordAddress = 00B0
+RealAddress = 000000B0
+RecordType = 00
+Image size now: 192
+RecordLength = 10
+RecordAddress = 00C0
+RealAddress = 000000C0
+RecordType = 00
+Image size now: 208
+RecordLength = 10
+RecordAddress = 00D0
+RealAddress = 000000D0
+RecordType = 00
+Image size now: 224
+RecordLength = 10
+RecordAddress = 00E0
+RealAddress = 000000E0
+RecordType = 00
+Image size now: 240
+RecordLength = 10
+RecordAddress = 00F0
+RealAddress = 000000F0
+RecordType = 00
+Image size now: 256
+RecordLength = 10
+RecordAddress = 0100
+RealAddress = 00000100
+RecordType = 00
+Image size now: 272
+RecordLength = 10
+RecordAddress = 0110
+RealAddress = 00000110
+RecordType = 00
+Image size now: 288
+RecordLength = 10
+RecordAddress = 0120
+RealAddress = 00000120
+RecordType = 00
+Image size now: 304
+RecordLength = 10
+RecordAddress = 0130
+RealAddress = 00000130
+RecordType = 00
+Image size now: 320
+RecordLength = 10
+RecordAddress = 0140
+RealAddress = 00000140
+RecordType = 00
+Image size now: 336
+RecordLength = 10
+RecordAddress = 0150
+RealAddress = 00000150
+RecordType = 00
+Image size now: 352
+RecordLength = 10
+RecordAddress = 0160
+RealAddress = 00000160
+RecordType = 00
+Image size now: 368
+RecordLength = 10
+RecordAddress = 0170
+RealAddress = 00000170
+RecordType = 00
+Image size now: 384
+RecordLength = 10
+RecordAddress = 0180
+RealAddress = 00000180
+RecordType = 00
+Image size now: 400
+RecordLength = 10
+RecordAddress = 0190
+RealAddress = 00000190
+RecordType = 00
+Image size now: 416
+RecordLength = 10
+RecordAddress = 01A0
+RealAddress = 000001A0
+RecordType = 00
+Image size now: 432
+RecordLength = 10
+RecordAddress = 01B0
+RealAddress = 000001B0
+RecordType = 00
+Image size now: 448
+RecordLength = 10
+RecordAddress = 01C0
+RealAddress = 000001C0
+RecordType = 00
+Image size now: 464
+RecordLength = 10
+RecordAddress = 01D0
+RealAddress = 000001D0
+RecordType = 00
+Image size now: 480
+RecordLength = 10
+RecordAddress = 01E0
+RealAddress = 000001E0
+RecordType = 00
+Image size now: 496
+RecordLength = 10
+RecordAddress = 01F0
+RealAddress = 000001F0
+RecordType = 00
+Image size now: 512
+RecordLength = 10
+RecordAddress = 0200
+RealAddress = 00000200
+RecordType = 00
+Image size now: 528
+RecordLength = 10
+RecordAddress = 0210
+RealAddress = 00000210
+RecordType = 00
+Image size now: 544
+RecordLength = 10
+RecordAddress = 0220
+RealAddress = 00000220
+RecordType = 00
+Image size now: 560
+RecordLength = 10
+RecordAddress = 0230
+RealAddress = 00000230
+RecordType = 00
+Image size now: 576
+RecordLength = 10
+RecordAddress = 0240
+RealAddress = 00000240
+RecordType = 00
+Image size now: 592
+RecordLength = 10
+RecordAddress = 0250
+RealAddress = 00000250
+RecordType = 00
+Image size now: 608
+RecordLength = 10
+RecordAddress = 0260
+RealAddress = 00000260
+RecordType = 00
+Image size now: 624
+RecordLength = 10
+RecordAddress = 0270
+RealAddress = 00000270
+RecordType = 00
+Image size now: 640
+RecordLength = 10
+RecordAddress = 0280
+RealAddress = 00000280
+RecordType = 00
+Image size now: 656
+RecordLength = 10
+RecordAddress = 0290
+RealAddress = 00000290
+RecordType = 00
+Image size now: 672
+RecordLength = 10
+RecordAddress = 02A0
+RealAddress = 000002A0
+RecordType = 00
+Image size now: 688
+RecordLength = 10
+RecordAddress = 02B0
+RealAddress = 000002B0
+RecordType = 00
+Image size now: 704
+RecordLength = 10
+RecordAddress = 02C0
+RealAddress = 000002C0
+RecordType = 00
+Image size now: 720
+RecordLength = 10
+RecordAddress = 02D0
+RealAddress = 000002D0
+RecordType = 00
+Image size now: 736
+RecordLength = 10
+RecordAddress = 02E0
+RealAddress = 000002E0
+RecordType = 00
+Image size now: 752
+RecordLength = 10
+RecordAddress = 02F0
+RealAddress = 000002F0
+RecordType = 00
+Image size now: 768
+RecordLength = 10
+RecordAddress = 0300
+RealAddress = 00000300
+RecordType = 00
+Image size now: 784
+RecordLength = 10
+RecordAddress = 0310
+RealAddress = 00000310
+RecordType = 00
+Image size now: 800
+RecordLength = 10
+RecordAddress = 0320
+RealAddress = 00000320
+RecordType = 00
+Image size now: 816
+RecordLength = 10
+RecordAddress = 0330
+RealAddress = 00000330
+RecordType = 00
+Image size now: 832
+RecordLength = 10
+RecordAddress = 0340
+RealAddress = 00000340
+RecordType = 00
+Image size now: 848
+RecordLength = 10
+RecordAddress = 0350
+RealAddress = 00000350
+RecordType = 00
+Image size now: 864
+RecordLength = 10
+RecordAddress = 0360
+RealAddress = 00000360
+RecordType = 00
+Image size now: 880
+RecordLength = 10
+RecordAddress = 0370
+RealAddress = 00000370
+RecordType = 00
+Image size now: 896
+RecordLength = 10
+RecordAddress = 0380
+RealAddress = 00000380
+RecordType = 00
+Image size now: 912
+RecordLength = 10
+RecordAddress = 0390
+RealAddress = 00000390
+RecordType = 00
+Image size now: 928
+RecordLength = 0C
+RecordAddress = 03A0
+RealAddress = 000003A0
+RecordType = 00
+Image size now: 940
+RecordLength = 04
+RecordAddress = 0000
+RealAddress = 00000000
+RecordType = 03
+Start Address = 0x000000C1
+RecordLength = 00
+RecordAddress = 0000
+RealAddress = 00000000
+RecordType = 01
+	converted to binary format...
+	image size : 940
+Image size : 940
+Dumping image file.
+COM-Port /dev/ttyUSB0 opened...
+Synchronizing (ESC to abort).Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=1): '1'
+Read(Length=1): '(0D)'
+Answer(Length=3): '?1(0D)'
+StrippedAnswer(Length=2): ''1(0D)'
+.Sending '?'
+Read(Length=1): '(0A)'
+Answer(Length=1): '(0A)'
+StrippedAnswer(Length=1): ''(0A)'
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=2): '??'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+.Sending '?'
+Read(Length=1): '?'
+Read(Length=0): ''
+Answer(Length=1): '?'
+StrippedAnswer(Length=0): '''
+ no answer on '?'
diff --git a/reform2-lpc-fw/tools/lpcrc/Makefile b/reform2-lpc-fw/tools/lpcrc/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..d0e2ff675fadcd385ac31222b26ded3f1308188c
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpcrc/Makefile
@@ -0,0 +1,12 @@
+CC = gcc
+LD = gcc
+LDFLAGS = -Wall -O2 -std=c99
+EXES = lpcrc
+
+all: $(EXES)
+
+% : %.c
+	$(LD) $(LDFLAGS) -o $@ $<
+
+clean: 
+	rm -f $(EXES)
diff --git a/reform2-lpc-fw/tools/lpcrc/lpcrc b/reform2-lpc-fw/tools/lpcrc/lpcrc
new file mode 100755
index 0000000000000000000000000000000000000000..b3dde0f543e2181e3848c3acf7dd632cfb1fda6d
Binary files /dev/null and b/reform2-lpc-fw/tools/lpcrc/lpcrc differ
diff --git a/reform2-lpc-fw/tools/lpcrc/lpcrc.c b/reform2-lpc-fw/tools/lpcrc/lpcrc.c
new file mode 100644
index 0000000000000000000000000000000000000000..ed316b2365e4acb891223d05294c649048645a1c
--- /dev/null
+++ b/reform2-lpc-fw/tools/lpcrc/lpcrc.c
@@ -0,0 +1,97 @@
+/*
+ * Software License Agreement (BSD License)
+ *
+ * Copyright (c) 2010, Roel Verdult
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+
+#define BLOCK_COUNT 7
+#define BLOCK_LENGTH 4
+#define BLOCK_TOTAL (BLOCK_COUNT*BLOCK_LENGTH)
+
+typedef unsigned char byte_t;
+
+int main(int argc, char *argv[])
+{
+  FILE* pf;
+  byte_t buf[BLOCK_TOTAL];
+  uint32_t crc = 0;
+  uint32_t block;
+  
+  // Check for required arguments
+  if (argc < 2)
+  {
+    printf("syntax: lpcrc <firmware.bin>\n");
+    return 1;
+  }
+  
+  // Try to open the supplied firmware
+  if ((pf = fopen(argv[1],"rb+")) == NULL)
+  {
+    printf("error: could not open file [%s] with write access\n",argv[1]);
+    return 1;
+  }
+
+  // Read out the data blocks used for crc calculation
+  if (fread(buf,1,BLOCK_TOTAL,pf) != BLOCK_TOTAL)
+  {
+    printf("error: could not read required bytes\n");
+    fclose(pf);
+    return 1;
+  }
+
+  // Compute the crc value
+  for (block=0; block<BLOCK_COUNT; block++)
+  {
+    crc += *((uint32_t*)(buf+(block*BLOCK_LENGTH)));
+  }
+  crc = (~crc) + 1;
+  
+  // Reposition the file stream indicator to switch between read and write
+  if (fseek(pf,0,SEEK_CUR) != 0)
+  {
+    printf("error: could not switch from read to write mode\n");
+    fclose(pf);
+    return 1;
+  }
+  
+  // Write the crc back to the file
+  if (fwrite((byte_t*)&crc,1,BLOCK_LENGTH,pf) != BLOCK_LENGTH)
+  {
+    printf("error: could not write crc back to file\n");
+    fclose(pf);
+    return 1;
+  }
+
+  printf("succesfully updated crc to: %08x\n",crc);
+  fclose(pf);
+  
+  return 0;
+}
+
diff --git a/reform2-lpc-fw/tools/lpcrc/lpcrc.exe b/reform2-lpc-fw/tools/lpcrc/lpcrc.exe
new file mode 100644
index 0000000000000000000000000000000000000000..d4ccd6fcb2a31fe8d5f9743bdded0a0232534881
Binary files /dev/null and b/reform2-lpc-fw/tools/lpcrc/lpcrc.exe differ